2013-06-02 3 views
5

У меня возникают некоторые действительно странные проблемы с NSURLConnection, поэтому я надеюсь, что вы можете мне помочь.NSURLConnection отлично работает в iOS 4.3, но не в iOS 5/iOS 6

Что я пытаюсь сделать, это загрузить некоторые данные из заданного URL с помощью NSURLConnection.

Я создал свой собственный класс-помощник, который получает путь к данным, загружает его и уведомляет вызывающего абонента через делегат, когда загрузка завершается.

Вещь прекрасно работает на моем iPhone с iOS 4.3. Однако при тестировании на iOS 5 или iOS6 метод connection:(NSURLConnection *)connection didReceiveData:(NSData *)data никогда не вызывается, и я не получаю желаемого результата.

Файл класса .h содержит:

#import <Foundation/Foundation.h> 

@protocol NIAsyncDownloaderDelegate 
@required 
- (void) asyncDownloaderDataDownloadComplete:(NSData *)data withError:(bool) error; 
@end 

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDataDelegate> 
{ 
    NSURLConnection *theConnection; 
    NSMutableData* myData; 

    NSURL *downloadURL; 

    id delegate; 
} 

-(id) initWithDataDownloadString:(NSString *) stringAddress; 

@property (nonatomic, retain) id delegate; 

@end 

И файл .m выглядит следующим образом:

#import "NIAsyncDownloader.h" 

@implementation NIAsyncImageDownloader 

@synthesize delegate; 

-(id) initWithDataDownloadString:(NSString *)stringAddress 
{ 
    if (self = [super init]) 
    { 
     [self loadDataFromURL:[NSURL URLWithString:stringAddress]]; 
    } 
    return self; 
} 

- (void)loadDataFromURL:(NSURL*)url 
{ 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    downloadURL = url; 

    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
    theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 
} 

-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    NSLog(@"The response is: %@, status code %i, url %@", response.description, ((NSHTTPURLResponse*)response).statusCode, ((NSHTTPURLResponse*)response).URL.description); 
} 

-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 

    if (myData == nil) 
    { 
     myData = [[NSMutableData alloc] initWithCapacity:2048]; 
    } 

    [myData appendData:data]; 
} 

//CALLED ON iOS 4.3 
- (void)connectionDidFinishLoading:(NSURLConnection*)connection 
{ 
    //so self data now has the complete image 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    [self handleDownloadSuccess]; 
} 

//CALLED ON iOS 5, iOS 6 
-(void) connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL 
{ 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    [self handleDownloadSuccess]; 
} 

-(void) handleDownloadSuccess 
{  
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    [theConnection release]; 
    theConnection = nil; 

    [delegate asyncDownloaderDataDownloadComplete:myData withError:NO]; 

    [myData release]; 
    myData = nil; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    NSLog(@"Called: %@", NSStringFromSelector(_cmd)); 
    [delegate asyncDownloaderDataDownloadComplete:nil withError:YES]; 
} 

@end 

Вот несколько скриншотов, чтобы показать вам, что я говорю:

Это то, что происходит, когда я запускаю приложение на iOS5 или iOS6, запрос инициализирует себя, получает ответ и сразу вызывает connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL ios5 ios6

Однако, когда я бег же приложение на прошивке 4.3, все работает отлично, как вы можете видеть на скриншотах ниже:

ios4.3 1 iOS4.3 2

Я также заметил, что прошивка 5 и IOS 6 сделать не называть тот же метод «финиша», как iOS 4.3, но я не думаю, что это имеет какое-то отношение к моей текущей проблеме.

И как окончательная вещь, документация здесь говорит, что рассматриваемый метод (соединение: didReceiveData) фактически устаревшая прошивка 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html

Однако еще эталонные состояниями, что она является частью протокол NSURLConnectionDataDelegate и доступен с прошивкой 2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html

XCode, кажется, согласны, что она устарела:

xcode

Только в случае, если кто задается вопросом, как я использую загрузчик, это довольно тривиальным действительно:

В .h:

#import <UIKit/UIKit.h> 
#import "NIAsyncDownloader.h" 

@interface DTViewController : UIViewController <NIAsyncDownloaderDelegate> 
{ 
    NIAsyncImageDownloader *downloader; 
} 

@end 

И в .m:

#import "DTViewController.h" 

@interface DTViewController() 

@end 

@implementation DTViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    downloader = [[NIAsyncImageDownloader alloc] initWithDataDownloadString:@"http://www.freeimageslive.com/galleries/sports/sportsgames/pics/whitedice1.jpg"]; 
    downloader.delegate = self; 
} 

-(void) asyncDownloaderDataDownloadComplete:(NSData *)data withError:(bool)error 
{ 
    if (data == nil || error) 
    { 
     NSLog(@"DOWNLOAD FAILED"); 
    } 
    else 
    { 
     NSLog(@"DOWNLOAD SUCCEEDED"); 
    } 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

Итак, Подводя итог, почему у меня возникают проблемы и что делать?

Заранее спасибо :)

+0

проголосовали не только потому, что это хороший вопрос, но потому, что это очень хорошо написана одна (проблема описание, скриншоты, то, что вы пробовали до сих пор, и т. д.) –

+0

Что вы можете получить, если вы зарегистрируете соединение NSError в соединении '- (void): (NSURLConnection *) connection didFailWithError: (NSError *) error'? –

+0

Спасибо Bruno :) @Rich, я ничего не получаю - как вы можете видеть, есть NSLog и в этом делетете, но он никогда не вызывается, потому что, по-видимому, ошибка не возникла. Кроме того, как вы могли заметить, я также регистрирую «didReceiveResponse», а код состояния - «200», который указывает, что в обоих случаях все нормально. – DarkoB

ответ

1

Это может или не может быть проблемой, но когда я создал, чтобы сделать подобную вещь, которую я осуществлению NSURLConnectionDelegate и протоколов NSURLConnectionDataDelegate.Я не проверял на IOS версий ранее 5, но она работала как в 5 и 6 для меня:

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> { 

} 
+0

Я старался соответствовать любой возможной комбинации протоколов между '' (от всех 3 до ничьих, включая ваше предложение), но, к сожалению, никто из них не работал. (Я только что попробовал еще раз убедиться, но, к сожалению, это не помогло) – DarkoB

+0

Hrmm .. Wel Я не совсем уверен, в чем проблема. Но я могу поделиться примером кода, который я использую, который работает для меня, может быть, это поможет вам. Вот пример использования интерфейса, реализации и примера: https://gist.github.com/localhuman/5694156 – ModernCarpentry

+0

Спасибо большое, я посмотрю на него и попытаюсь использовать его – DarkoB

Смежные вопросы