NSURLConnection在iOS 4.3中完美运行,但在iOS 5/iOS 6中运行不佳

Dar*_*koB 5 objective-c nsurlconnection ios

我在NSURLConnection有一些非常奇怪的问题,所以我希望你能帮助我.

我想要做的是使用NSURLConnection从给定的URL下载一些数据.

我创建了自己的帮助程序类,它接收数据路径,下载它,并在下载完成时通过委托通知调用者.

这款产品在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
Run Code Online (Sandbox Code Playgroud)

并且.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
Run Code Online (Sandbox Code Playgroud)

以下是一些屏幕截图,向您展示我在说什么:

这是发生了什么,当我运行的iOS5或iOS6的应用程序,请求初始化自身,接收响应,并要求connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL马上 ios5 ios6

但是,当我在iOS 4.3上运行相同的应用程序时,一切都很完美,如下面的屏幕截图所示:

ios4.3 1 iOS4.3 2

我还注意到iOS 5和iOS 6没有像iOS 4.3那样调用相同的"完成"方法,但我认为这与我当前的问题没有任何关系.

作为最终的东西,在这里的文件说,在讨论的方法(连接:didReceiveData)实际上是不赞成的iOS 4.3: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/ NSURLConnectionDelegate_Protocol/DeprecationAppendix/AppendixADeprecatedAPI.html

然而,另一个参考说,它是NSURLConnectionDataDelegate协议的一部分,并且是可用的,因为iOS的2: http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDataDelegate_protocol/Reference/Reference.html

XCode似乎同意它已被弃用:

Xcode中

万一有人想知道我如何使用下载程序,它真的很简单:

在.h:

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

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

@end
Run Code Online (Sandbox Code Playgroud)

在.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
Run Code Online (Sandbox Code Playgroud)

总而言之,为什么我有问题和做什么?

提前致谢 :)

Mod*_*try 1

这可能是问题,也可能不是问题,但是当我设置做类似的事情时,我实现了 NSURLConnectionDelegate 和 NSURLConnectionDataDelegate 协议。我没有在 5 之前的 iOS 版本上进行过测试,但它在 5 和 6 中都适用于我:

@interface NIAsyncImageDownloader : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> {

}
Run Code Online (Sandbox Code Playgroud)