Tôi đang gặp một số vấn đề thực sự lạ với NSURLConnection vì vậy tôi hy vọng bạn có thể giúp tôi.NSURLConnection hoạt động hoàn hảo trong iOS 4.3 nhưng không có trong iOS 5/iOS 6
Điều tôi đang cố gắng tải xuống một số dữ liệu từ một URL nhất định bằng cách sử dụng NSURLConnection.
Tôi đã tạo lớp trợ giúp của riêng mình để nhận đường dẫn dữ liệu, tải xuống và thông báo cho người gọi qua đại biểu khi quá trình tải xuống hoàn tất.
Điều hoạt động hoàn hảo trên iPhone của tôi với iOS 4.3. Tuy nhiên, khi được thử nghiệm trên iOS 5 hoặc iOS6, phương thức connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
không bao giờ được gọi và tôi không nhận được kết quả mong muốn.
Các tập tin lớp .h chứa:
#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
Và file .m trông như thế này:
#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
Dưới đây là một số ảnh chụp màn hình để hiển thị cho bạn những gì tôi đang nói về:
Đây là những gì xảy ra khi tôi chạy ứng dụng trên iOS5 hoặc iOS6, yêu cầu khởi tạo chính nó, nhận được phản hồi và gọi connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL
ngay lập tức
Tuy nhiên, khi tôi chạy cùng một ứng dụng trên iOS 4.3, tất cả mọi thứ hoạt động hoàn hảo như bạn có thể nhìn thấy từ ảnh chụp màn hình dưới đây:
Tôi cũng nhận thấy rằng iOS 5 và iOS 6 làm không gọi phương thức 'kết thúc' giống như iOS 4.3, nhưng tôi không nghĩ rằng có bất kỳ điều gì liên quan đến vấn đề hiện tại của tôi.
Và như một điều cuối cùng, tài liệu hướng dẫn trên đây nói rằng phương pháp trong câu hỏi (kết nối: didReceiveData) là thực sự phản đối như iOS 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html
Tuy nhiên, một tiểu bang tham chiếu mà nó là một phần của NSURLConnectionDataDelegate giao thức và có sẵn từ iOS 2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html
XCode dường như đồng ý rằng nó được chấp nhận:
Chỉ trong trường hợp ai thắc mắc làm thế nào tôi đang sử dụng các downloader, nó là khá tầm thường thực sự:
Trong .h:
#import <UIKit/UIKit.h>
#import "NIAsyncDownloader.h"
@interface DTViewController : UIViewController <NIAsyncDownloaderDelegate>
{
NIAsyncImageDownloader *downloader;
}
@end
Và trong .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
Vì vậy, tóm tắt, tại sao tôi gặp vấn đề và phải làm gì?
Cảm ơn trước :)
bình chọn lên không chỉ vì đó là một câu hỏi hay, nhưng vì đó là một rất tốt bằng văn bản một (vấn đề mô tả, ảnh chụp màn hình, những gì bạn đã thử cho đến nay, vv) –
Bạn nhận được gì nếu bạn đăng nhập 'NSError' trong kết nối' - (void): (NSURLConnection *) didFailWithError: (NSError *) error'? –
Cảm ơn Bruno :) @Rich, tôi không nhận được gì - vì bạn có thể thấy có một NSLog trong phương thức ủy nhiệm đó, nhưng nó không bao giờ được gọi vì dường như không có lỗi xảy ra. Ngoài ra, như bạn có thể đã nhận thấy, tôi đang đăng nhập 'didReceiveResponse' là tốt, và mã trạng thái là '200' mà sẽ cho thấy mọi thứ đều OK trong cả hai trường hợp – DarkoB