使用NSURLConnection下载返回空数据?

时间:2013-07-14 06:46:51

标签: ios nsurlconnection nsurlconnectiondelegate

我的应用正在使用NSURLConnection从互联网上下载文件。

发生了两个问题:

1)永远不会调用[连接didReceiveData]

2)当调用[connection didFinishDownloading]时,我的self.currentData为空

我做错了什么?

我的标题如下:

@interface DIFileDownloader : NSObject <NSURLConnectionDelegate> {

    NSMutableData *currentData;

}

@property (nonatomic, assign) id <DIFileDownloaderDelegate> delegate;

@property (nonatomic, retain) NSMutableArray *supportedFormats;

@property (nonatomic, retain) NSMutableData *currentData;

@property (nonatomic, retain) NSURLConnection *downloadAgent;

@property (nonatomic) long long expectedContentSize;

@property (nonatomic) float currentDownloadProgress;

@property (nonatomic, getter = isRunning) BOOL running;

-(instancetype)initWithSupportedFormats:(NSArray *)extensions;

-(void)downloadFileAtURL:(NSURL *)url;

-(NSString *)documentsDirectoryPath;

@end

我的实施文件:

-(instancetype)initWithSupportedFormats:(NSArray *)extensions {

    self.supportedFormats = [[NSMutableArray alloc] initWithArray:extensions];

    self.running = NO;
}

-(void)downloadFileAtURL:(NSURL *)url {

    NSString *fileExtension = [url pathExtension];

    if ([self.supportedFormats containsObject:fileExtension]) {

        self.downloadAgent = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self];

        [self.downloadAgent start];

        NSLog(@"Beginning download at URL:%@", url.absoluteString);

    }
    else {

    }

}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    NSLog(@"Connection recieved response with size: %f", (float)[response expectedContentLength]);

    self.expectedContentSize = (float)[response expectedContentLength];

    self.running = YES;

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;

    NSLog(@"%i", [httpResponse statusCode]);

    /*

    if ([httpResponse statusCode] >= 200 && [httpResponse statusCode] <= 299) {

    }

     */

}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    NSLog(@"%f", (float)[data length]);

    [currentData appendData:data];

    self.currentDownloadProgress = ((float)[data length] / self.currentDownloadProgress);

    NSLog(@"Connection recieved data. New progress is: %f", self.currentDownloadProgress);

    if ([self.delegate respondsToSelector:@selector(downloader:progressChanged:)]) {
        [self.delegate downloader:self progressChanged:self.currentDownloadProgress];
    }

}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

    NSLog(@"Connection failed");

    if ([self.delegate respondsToSelector:@selector(downloader:failedToDownloadFileAtURL:reason:)]) {
        [self.delegate downloader:self failedToDownloadFileAtURL:connection.originalRequest.URL reason:error];
    }

}

-(void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {

    NSLog(@"Connection finished downloading with size: %f", (float)[currentData length]);

    self.running = NO;

    NSString *filename = [destinationURL.absoluteString lastPathComponent];

    NSString *docPath = [self documentsDirectoryPath];

    NSString *pathToDownloadTo = [NSString stringWithFormat:@"%@/%@", docPath, filename];

    NSError *error = nil;

    [currentData writeToFile:pathToDownloadTo options:NSDataWritingAtomic error:&error];

    if (error != nil) {

        NSLog(@"DIFileDownloader: Failed to save the file because: %@", [error description]);

        if ([self.delegate respondsToSelector:@selector(downloader:failedToDownloadFileAtURL:reason:)]) {
            [self.delegate downloader:self failedToDownloadFileAtURL:connection.originalRequest.URL reason:error];
        }

} 
    else {

        if ([self.delegate respondsToSelector:@selector(downloader:finishedDownloadingFileNamed:atPath:)]) {
            [self.delegate downloader:self finishedDownloadingFileNamed:filename atPath:pathToDownloadTo];
        }

    }

}

- (NSString *)documentsDirectoryPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];
    return documentsDirectoryPath;
}

@end

1 个答案:

答案 0 :(得分:0)

正如其他人和我的评论中所提到的,您的代码中存在一些需要修复的错误。

但也存在一个很大的误解 - 源自前NSURLConnection的可怕文档:

connectionDidFinishDownloading:destinationURL:不是NSURLConnection的两个委托的委托方法,即NSURLConnectionDelegateNSURLConnectionDataDelegate,你应该在你的情况下实现。

您需要实现的最小委托方法集是:

对于NSURLConnectionDelegate

  • (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

然后是NSURLConnectionDataDelegate

  • (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

  • (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

  • (无效)connectionDidFinishLoading:(NSURLConnection的*)连接;

如果你不介意的话,我已经在Gist上添加了一个最小实现的示例:SimpleGetHTTPRequest这可以让你跳转开始实现你自己的HTTP请求类。