【问题标题】:Download with NSURLConnection returns empty data?使用 NSURLConnection 下载返回空数据?
【发布时间】:2013-07-14 06:46:50
【问题描述】:

我的应用正在使用 NSURLConnection 从 Internet 下载文件。

出现了两个问题:

1) [connection 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

【问题讨论】:

标签: ios nsurlconnection nsurlconnectiondelegate


【解决方案1】:

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

但也有一个很大的误解——源于之前糟糕的 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;

  • (void)connectionDidFinishLoading:(NSURLConnection*)connection;

如果您不介意,我在 Gist 上放了一个最小实现的示例:SimpleGetHTTPRequest 这应该可以让您快速开始实现自己的 HTTP 请求类。

【讨论】:

  • 感谢您提供的样本,我想我已经得到了我需要的东西!
猜你喜欢
  • 1970-01-01
  • 2014-03-29
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多