2013-06-02 15 views
5

Sto riscontrando alcuni problemi davvero strani con NSURLConnection quindi spero che tu possa darmi una mano.NSURLConnection funziona perfettamente in iOS 4.3 ma non in iOS 5/iOS 6

Quello che sto cercando di fare è scaricare alcuni dati da un dato URL usando NSURLConnection.

Ho creato la mia classe di supporto che riceve il percorso dati, lo scarica e notifica il chiamante via delegato al termine del download.

La cosa funziona perfettamente sul mio iPhone con iOS 4.3. Tuttavia, se testato su iOS 5 o iOS6, il metodo connection:(NSURLConnection *)connection didReceiveData:(NSData *)data non viene mai chiamato e non ottengo il risultato desiderato.

Il file di classe .h contiene:

#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 

e il file .m assomiglia a questo:

#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 

Ecco alcuni screenshot per mostrare ciò di cui sto parlando:

Questo è ciò che accade quando eseguo l'applicazione su iOS5 o iOS6, la richiesta si inizializza, riceve una risposta e chiama subito connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL ios5 ios6

Tuttavia, quando si esegue la stessa applicazione su iOS 4.3, tutto funziona perfettamente, come potete vedere dagli screenshot qui sotto:

ios4.3 1 iOS4.3 2

Ho anche notato che iOS 5 e iOS 6 fare non chiamare lo stesso metodo 'finish' come iOS 4.3, ma non penso che abbia qualcosa a che fare con il mio problema attuale.

E come ultima cosa, la documentazione qui dice che il metodo in questione (collegamento: didReceiveData) è in realtà deprecato a partire da iOS 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html

Tuttavia, un altro rinvio che è una parte della protocollo e NSURLConnectionDataDelegate è disponibile dal iOS 2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html

XCode sembra essere d'accordo che è deprecato:

xcode

Solo nel caso qualcuno si chiede come sto usando il downloader, è piuttosto banale realtà:

In .h:

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

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

@end 

E in .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 

Quindi, riassunto, perché sto avendo problemi e cosa devo fare?

Grazie in anticipo :)

+0

hanno votato per non solo perché è una buona domanda, ma perché è molto ben scritto una (problema descrizione, screenshot, cosa hai provato fino ad ora, ecc.) –

+0

Cosa ottieni se accedi a 'NSError' in' - (void) connection: (NSURLConnection *) connection didFailWithError: (NSError *) error'? –

+0

Grazie Bruno :) @Rich, non ho ottenuto nulla - come potete vedere c'è anche un NSLog in quel metodo delegato, ma non viene mai chiamato perché apparentemente non si è verificato alcun errore. Inoltre, come avrete notato, sto registrando anche "didReceiveResponse" e il codice di stato è "200" che indica che tutto è OK in entrambi i casi – DarkoB

risposta

1

Questo può o non può essere il problema, ma quando ho creato per fare una cosa simile a implementare il NSURLConnectionDelegate ei protocolli NSURLConnectionDataDelegate.Non ho ancora testato su versioni iOS precedenti al 5, ma ha lavorato sia 5 e 6 per me:

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> { 

} 
+0

Ho provato a conformarmi a tutte le possibili combinazioni di protocolli tra '(da tutti 3 a nessuno, incluso il tuo suggerimento), ma purtroppo nessuno di loro ha funzionato. (Ho appena provato di nuovo per essere sicuro, ma sfortunatamente non è stato d'aiuto) – DarkoB

+0

Hrmm .. Wel non sono esattamente sicuro di cosa tu sia un problema. Ma posso condividere un esempio di codice che sto usando che funziona per me, forse ti aiuterà. Ecco un'interfaccia, un'implementazione e un esempio di utilizzo: https://gist.github.com/localhuman/5694156 – ModernCarpentry

+0

Grazie a molti amici, darò un'occhiata a questo e cercherò di usarlo – DarkoB

Problemi correlati