2012-01-04 6 views
0

새 파일이있는 경우에만 파일을 다운로드하는 NSURLConnection을 수행합니다 (마지막 수정 날짜로 확인). 하지만이 두 가지 NSURLRequests 및 NSURLConnection 함께 두 가지 방법을 사용하여이를 달성하기 위해. 글쎄, 그들은 똑같은 행동을한다.메서드가 두 번 호출됩니다.

- (IBAction)uppdatera:(id)sender 
{ 
    checkHeaders = YES; 

    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.forellgatan.se/site/ftp_files/Kapareskolan.zip"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0]; 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

    if (theConnection) 
    { 
     self.receivedData = [[NSMutableData data] retain]; 
    } 

    else 
    { 
     UIAlertView *connectFailMessage = [[UIAlertView alloc] initWithTitle:@"Ingen internetanslutning! 1" message:@"Anslut dig till internet för att ladda ner!" delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
     [connectFailMessage show]; 
     [connectFailMessage release];   
    } 
} 

- (void)downloadNewFile 
{ 
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.forellgatan.se/site/ftp_files/Kapareskolan.zip"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0]; 

    NSURLConnection *theConnection2 = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

    if (theConnection2) 
    { 
     self.receivedData = [[NSMutableData data] retain]; 
    } 

    else 
    { 
     UIAlertView *connectFailMessage = [[UIAlertView alloc] initWithTitle:@"Ingen internetanslutning! 2" message:@"Anslut dig till internet för att ladda ner!" delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
     [connectFailMessage show]; 
     [connectFailMessage release];   
    } 

    checkHeaders = NO; 

    self.progressView.hidden = NO; 
} 

그것은 didReceiveResponse 방법을 통해 진행됩니다

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    if (checkHeaders == YES) 
    { 
     NSHTTPURLResponse *test = (NSHTTPURLResponse *)response; 

     if ([test respondsToSelector:@selector(allHeaderFields)]) 
     { 
      NSDictionary *metaData = [test allHeaderFields]; 

      NSString *lastModifiedString = [metaData objectForKey:@"Last-Modified"]; 

      NSString *savedString = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastModified"]; 

      if (![lastModifiedString isEqualToString:savedString]) 
      { 
       [self downloadNewFile]; 
      } 

      else if ([lastModifiedString isEqualToString:savedString]) 
      {  
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ingen uppdatering tillgänglig" message:@"Det finns ingen uppdatering att hämta just nu." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
       [alert show]; 
       [alert release]; 
      } 

      NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; 
      [standardUserDefaults setObject:lastModifiedString forKey:@"LastModified"]; 
      [standardUserDefaults synchronize]; 
     } 
    } 

    [self.receivedData setLength:0]; 
    self.fileSize = [[NSNumber numberWithLong: [response expectedContentLength]] retain]; 
} 

마지막 connectionDidFinishLaunching 방법 :

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    if (checkHeaders == NO) 
    { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
     NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; 
     [self.receivedData writeToFile:[basePath stringByAppendingPathComponent:@"Kapareskolan.zip"] atomically:YES]; 

     [self unzipDownloadedFile]; 

     self.progressView.hidden = YES; 

     NSLog(@"Finished..."); 
    } 

    [connection cancel]; 
} 

내가 didFinishLaunching 방법은 두 번 호출되는 알고 있지만 내가 어떻게 내가 할 수있는 알고 싶어요 업데이트가있을 경우 메서드가 두 번 호출되지 않도록 하시겠습니까?

많은 질문과 많은 코드를 알고 있지만 힌트를 주면 매우 감사 할 것입니다.

답변

2

didReceiveResponse 메서드에서 첫 번째 연결 개체를 완료했다면 취소해야합니다. 그렇지 않으면 connectionDidFinishLoading 메소드로 이동합니다. 나는 이것이 당신이 원하는 생각 : 당신이 경쟁 조건이 발생할 수있는 두 번째 요청을 시작한 후 NO에 checkHeaders을 설정하는 것처럼

if (![lastModifiedString isEqualToString:savedString]) 
    { 
    [connection cancel]; 
    [self downloadNewFile]; 
    } 

는 또한 보인다.

+0

감사합니다. NSURLConnection * theConnection2 인스턴스 변수를 사용해야합니까? – Jacob

+0

미안하지만, 네가 무엇을 묻고 있는지 잘 모르겠다 ... 분명히 할 수 있니? – Jonathan

+0

제 잘못, 어디서 '[연결 취소];'방법을 써야합니까? – Jacob

1

programming guide에 따르면 연결은 "대리인이 connectionDidFinishLoading :을 수신하거나 연결 : didFailWithError : 메시지를 연결 메시지를 보내어 취소하기 전에 언제든지 취소 할 수 있습니다."

그래서 왜 그냥 didReceiveResponse 위임 방법에 if-else 블록 후 connectionDidFinishLoading 방법에서

 [connection cancel]; 

를 이동하려고하지? 두 경우 모두 "checkHeaders == YES"연결을 취소하려고합니다. 새 연결을 시작하려고하거나 현재 연결에 대해 알아야 할 모든 것을 이미 알고 있습니다. 요청 된 갱신

: 비동기 그 NSURLConnection 오프

if (![lastModifiedString isEqualToString:savedString]) { 
     [self downloadNewFile]; 
    } else { // you've already implicitly checked for equality above 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ingen uppdatering tillgänglig" message:@"Det finns ingen uppdatering att hämta just nu." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 
    } 
    // you've used the connection for everything that you need, so cancel it in either case 
    [connection cancel]; 

downloadNewFile 등 차기,이 두 문자열이 동일하는 경우에 괜찮을 것이다. 약간 더 안전하다면 cancel 메서드 호출을 if-else 검사 직전으로 옮기십시오.

+0

흠, 어쩌면 나는 바보예요. 코드에 넣어 주시겠습니까? – Jacob

관련 문제