У меня возникают некоторые действительно странные проблемы с 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
Однако, когда я бег же приложение на прошивке 4.3, все работает отлично, как вы можете видеть на скриншотах ниже:
Я также заметил, что прошивка 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, кажется, согласны, что она устарела:
Только в случае, если кто задается вопросом, как я использую загрузчик, это довольно тривиальным действительно:
В .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
Итак, Подводя итог, почему у меня возникают проблемы и что делать?
Заранее спасибо :)
проголосовали не только потому, что это хороший вопрос, но потому, что это очень хорошо написана одна (проблема описание, скриншоты, то, что вы пробовали до сих пор, и т. д.) –
Что вы можете получить, если вы зарегистрируете соединение NSError в соединении '- (void): (NSURLConnection *) connection didFailWithError: (NSError *) error'? –
Спасибо Bruno :) @Rich, я ничего не получаю - как вы можете видеть, есть NSLog и в этом делетете, но он никогда не вызывается, потому что, по-видимому, ошибка не возникла. Кроме того, как вы могли заметить, я также регистрирую «didReceiveResponse», а код состояния - «200», который указывает, что в обоих случаях все нормально. – DarkoB