2013-06-02 33 views
5

Mam bardzo dziwne problemy z NSURLConnection, więc mam nadzieję, że możesz mi pomóc.NSURLConnection działa idealnie w systemie iOS 4.3, ale nie w systemie iOS 5/iOS 6

Co próbuję zrobić, to pobrać dane z danego adresu URL przy użyciu NSURLConnection.

Zrobiłem własną klasę pomocniczą, która odbiera ścieżkę danych, pobiera ją i powiadamia dzwoniącego przez delegata po zakończeniu pobierania.

Wszystko działa idealnie na moim iPhonie z systemem iOS 4.3. Jednak podczas testowania na iOS 5 lub iOS6, metoda connection:(NSURLConnection *)connection didReceiveData:(NSData *)data nigdy nie jest wywoływana i nie uzyskuję pożądanego rezultatu.

Plik klasa .h zawiera:

#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 

a plik .m wygląda następująco:

#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 

Oto kilka zrzutów ekranu, aby pokazać, co mówię:

Tak dzieje się, gdy uruchomię aplikację na iOS5 lub iOS6, żądanie inicjuje się, odbiera odpowiedź i odzywa się connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL od razu ios5 ios6

Jednak kiedy uruchomić tę samą aplikację na iOS 4.3, wszystko działa idealnie jak widać z ekranu poniżej:

ios4.3 1 iOS4.3 2

Zauważyłem również, że iOS 5 i iOS 6 zrobić nie wywołaj tej samej metody "kończenia", jak iOS 4.3, ale nie sądzę, że ma to coś wspólnego z moim aktualnym problemem.

I jako ostateczny rzeczy, dokumentację tu mówi, że omawiana metoda (gra: didReceiveData) jest rzeczywiście przestarzała iOS 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html

Jednak kolejne stany referencyjne, że jest to część protokół NSURLConnectionDataDelegate i jest dostępny od iOS 2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html

XCode wydaje się zgodzić, że jest przestarzała:

xcode

wszelki wypadek ktoś zastanawia się, jak używam downloader, to jest dość trywialne naprawdę:

W .h:

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

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

@end 

A w .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 

Więc, podsumowałeś, dlaczego mam problemy i co robić?

góry dzięki :)

+0

głosowanie się nie tylko dlatego, że jest to dobre pytanie, ale ponieważ jest to bardzo dobrze napisany jeden (problem opis, zrzuty ekranu, co wypróbowałeś do tej pory itp.) –

+0

Co otrzymasz, jeśli zarejestrujesz 'NSError' w połączeniu' - (void): (NSURLConnection *) didFailWithError: (NSError *) error'? –

+0

Dzięki Bruno :) @Rich, nic nie dostaję - jak widzisz, istnieje również NSLog w tej metodzie delegata, ale nigdy nie jest wywoływana, ponieważ najwyraźniej nie wystąpił błąd. Ponadto, jak być może zauważyliście, loguję się również do "didReceiveResponse", a kod stanu to "200", co oznacza, że ​​wszystko jest w porządku w obu przypadkach. – DarkoB

Odpowiedz

1

może lub nie może być problem, ale kiedy skonfigurować, aby zrobić coś podobnego ja wdrożenia NSURLConnectionDelegate i protokoły NSURLConnectionDataDelegate to.Nie testowałem na wersjach iOS ubiegłych do 5, ale pracował zarówno 5 i 6 dla mnie:

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> { 

} 
+0

Próbowałem dostosować się do każdej możliwej kombinacji protokołów między '' (od wszystkich 3 do zera, włącznie z twoją sugestią), ale niestety żaden z nich nie zadziałał. (Właśnie spróbowałem, żeby się upewnić, ale niestety to nie pomogło) – DarkoB

+0

Hrmm .. Wel Nie jestem do końca pewien, co to jest problem. Ale mogę udostępnić przykład kodu, który używam, który działa dla mnie, może to ci pomoże. Oto interfejs, implementacja i przykład użycia: https://gist.github.com/localhuman/5694156 – ModernCarpentry

+0

Wielkie dzięki, przyjrzę się temu i spróbuję go użyć – DarkoB

Powiązane problemy