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
Tuttavia, quando si esegue la stessa applicazione su iOS 4.3, tutto funziona perfettamente, come potete vedere dagli screenshot qui sotto:
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:
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 :)
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.) –
Cosa ottieni se accedi a 'NSError' in' - (void) connection: (NSURLConnection *) connection didFailWithError: (NSError *) error'? –
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