0

我的应用程序正在使用 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
4

1 回答 1

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;

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

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

于 2013-07-14T08:00:31.637 回答