2013-07-14 39 views
0

我的應用程序正在使用NSURLConnection從互聯網上下載文件。使用NSURLConnection下載會返回空數據?

兩個問題發生:

1)連接didReceiveData]從未被稱爲

2)當[連接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

那麼,一方面你永遠不會創建你的'NSMutableData'對象。 –

+1

然後它看起來像你有與[NSURLConnection連接:didReceiveData:不在ios5上調用]相同的問題(http://stackoverflow.com/questions/13085007/nsurlconnection-connectiondidreceivedata-is-not-called-on-ios5 )[NSURLConnection didReceiveData:還沒有被調用的iOS]還有另一個有用的答案(http://stackoverflow.com/q/14553538) –

+0

你的代碼中有許多錯誤:你的init方法不符合規則,並且不返回對象。你計算'currentDownloadProgress'的方式不起作用,還有一些。我建議在代碼中添加很多斷言和錯誤檢查,然後開始調試會話。 – CouchDeveloper

回答

0

正如別人在我的評論,也有在你的代碼,你需要一些錯誤提到固定。

但也有一個很大的誤解 - 從NSURLConnection前可怕的文檔而產生:

connectionDidFinishDownloading:destinationURL:不是NSURLConnection的兩個代表的委託方法,即NSURLConnectionDelegateNSURLConnectionDataDelegate你應該在實現你案件。

在組最少的委託方法,你需要實現的是:

對於NSURLConnectionDelegate

  • (無效)連接:(NSURLConnection的*)連接didFailWithError:(NSError *)錯誤;

然後爲NSURLConnectionDataDelegate

  • (無效)連接:(NSURLConnection的*)連接didReceiveResponse:(NSURLResponse *)響應; (NSURLConnection *)連接didReceiveData:(NSData *)data;(NSURLConnection *)連接: (void)connectionDidFinishLoading:(NSURLConnection *)connection;

如果你不介意的話,我已經把一個最小實現對要點的樣品:SimpleGetHTTPRequest這應該給你一個跳開始就實現自己的HTTP請求類。

+0

感謝那個樣本,我想我已經得到了我需要的東西! – JohnWickham