2013-07-14 2 views
0

내 응용 프로그램이 NSURLConnection을 사용하여 인터넷에서 파일을 다운로드하고 있습니다.NSURLConnection을 사용하여 다운로드하면 빈 데이터가 반환됩니까?

두 가지 문제가 발생됩니다

1) 연결 didReceiveData]가 호출되지

[연결 didFinishDownloading이]라고

2), 내 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 connection : didReceiveData : is not called ios5]와 같은 문제가있는 것 같습니다 (http://stackoverflow.com/questions/13085007/nsurlconnection-connectiondidreceivedata-is-not-called-on-ios5) 또 다른 유용한 답변은 [NSURLConnection didReceiveData : did not got iOS] (http://stackoverflow.com/q/14553538) –

+0

코드에 여러 가지 버그가 있습니다. init 메소드가 규칙에 맞지 않습니다. 객체를 반환하지 않습니다. 'currentDownloadProgress'를 계산하는 방법은 작동하지 않습니다. 코드에 어설 션 및 오류 검사를 많이 추가하고 디버깅 세션을 시작하는 것이 좋습니다. – CouchDeveloper

답변

0

고치다.

그러나 하나의 큰 오해도있다 - NSURLConnection의 전 끔찍한 문서에 따른 :

connectionDidFinishDownloading:destinationURL: 즉, NSURLConnectionDelegateNSURLConnectionDataDelegate 당신이 구현 해야하는있는 NSURLConnection의 두 대표의 위임 방법은 아닙니다 당신의 케이스.

구현해야 대리자 메서드의 최소한은 다음과 같습니다에 대한

NSURLConnectionDelegate :

  • (무효) 연결 : (있는 NSURLConnection *) 연결 didFailWithError : (NSError *) 오류;

    • (공극) 접속 : (있는 NSURLConnection *) 연결 didReceiveResponse 다음 NSURLConnectionDataDelegate 대한 다음

  • (NSURLResponse *) 반응;

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

  • (void) connectionDidFinishLoading : (NSURLConnection *) connection; 당신이 당신의 자신의 HTTP 요청 클래스를 구현합니까 점프 시작을 제공해야 SimpleGetHTTPRequest :

당신이 괜찮다면

, 나는 요점에 대한 최소한의 구현의 샘플을 넣어했습니다.

+0

샘플을 보내 주셔서 감사합니다. 필요한 것을 얻었습니다. – JohnWickham