2013-02-27 2 views
1

사내 엔터프라이즈 앱의 업데이트 방법을 만들고 있습니다. 내가 만들고자하는 것은 빠르게 앱에 넣을 수있는 클래스이며, 업데이트가 필요한 경우 서버에서 확인합니다. 이것은 내가 지금까지 가지고있는 것인데 정확하게 검사하지만 그 방법을 끝내기 전에 NO을 반환한다. 나는이이앱 업데이트 확인

NSLog(@"Needs Update %@",[checkForUpdate checkForUpdateWithResponse] ? @"Yes":@"No"); 

과 같이 호출

#import "checkForUpdate.h" 

@implementation checkForUpdate 

BOOL needsUpdate 
NSDictionary *versionDict; 


#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 


+ (BOOL)updateCheck { 

    NSString *urlStringVersion = [[NSString alloc] initWithFormat:@"http://URL/app_info?app=app"]; 
    NSURL *urlVersion = [NSURL URLWithString:urlStringVersion]; 

    dispatch_async(kBgQueue, ^{ 
     NSData* data =[NSData dataWithContentsOfURL:urlVersion]; 

     if (data){ 
      NSError* error; 
      NSArray* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
      if (json != nil && [json count] != 0) { 
       versionDict = [json objectAtIndex:0]; 

       CGFloat serverVersion = [[versionDict valueForKey:@"version"]floatValue]; 
       CGFloat appVersion = [[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey] floatValue]; 
       NSLog(@"Server Version %f",serverVersion); 
       NSLog(@"App Version %f",appVersion); 

       if ([versionDict count] != 0){ 
        if (serverVersion > appVersion){ 
         [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; 
         needsUpdate = YES; 
        }else{ 
         [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; 
         needsUpdate = NO; 
        } 
       } 

      } 
     } 

    }); 

    return needsUpdate; 

} 


@end 

내 checkUpdate.m에서 내 checkUpdate.h

@interface checkForUpdate : NSObject 

+ (BOOL)updateCheck; 


@end 

에서

내 로그입니다

Needs Update No 
Server Version 2.000000 
App Version 1.000000 

확인하기 전에 NO가 반환되는 이유가 확실하지 않습니다. 응용 프로그램이 확인할 서버가 방화벽 뒤에 있으므로 비동기가 필요합니다. 따라서 방화벽 외부에있는 사람은 서버에 연결할 수 없을 때 계속해야합니다. 나는 올바른 방향으로 나아가고 있습니까? 아니면 더 좋은 방법이 있습니까?

답변

3

업데이트가 비동기식으로 확인되지만 사용자의 방법 설계로 인해 즉각적인 응답을 기대합니다. 작업이 완료 될 때마다 처리기에 알리기 위해 아래 예와 같이 메소드를 다시 엔지니어링 할 수 있습니다.

참고 : 오류는 선택하지 않고 테스트하지 않습니다. 그러나, 수업이 종류의 콜백 사용하기 위해 예로부터 수집한다 : 당신을 통해 업데이트를 확인 UpdateChecker를 사용할 때 보이게 될지

UpdateChecker 클래스

typedef void (^onComplete)(BOOL requiresUpdate); 

@interface UpdateChecker : NSObject 
-(void)checkForUpdates:(onComplete)completionHandler; 
@end 

@implementation UpdateChecker 
-(void)checkForUpdates:(onComplete)completionHandler 
{ 
    NSString *urlStringVersion = [[NSString alloc] initWithFormat:@"http://URL/app_info?app=app"]; 
    NSURL *urlVersion = [NSURL URLWithString:urlStringVersion]; 
    dispatch_block_t executionBlock = 
    ^{ 
     /* 
      Your update checking script here 
      (Use the same logic you are currently using to retrieve the data using the url) 
      */ 
     NSData* data = [NSData dataWithContentsOfURL:urlVersion]; 
     BOOL requiresUpdate = NO; 
     if (data) 
     { 
      ... 
      ... 
      ... 
      requiresUpdate = ...; //<-whatever your outcome 
     } 

     //Then when completed, notify the handler (this is our callback) 
     //Note: I typically call the handler on the main thread, but is not required. 
     //Suit to taste. 
     dispatch_async(dispatch_get_main_queue(), 
     ^{ 
      if (completionHandler!=NULL) 
       completionHandler(requiresUpdate); 
     }); 
    }; 
    dispatch_async(kBgQueue, executionBlock); 
} 
@end 

이를 당신의 앱

UpdateChecker *checker = [UpdateChecker alloc] init]; 
[checker checkForUpdates:^(BOOL requiresUpdate) 
{ 
    if (requiresUpdate) 
    { 
     //Do something if your app requires update 
     [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; 
    } 
    else   
     [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; 
}]; 
+0

이것은 완전히 새로운 것입니다. 저는이 문제를 해결하기 위해 노력하고 있습니다. 이걸 구현하는 방법을 좀 더 보여줄 수 있습니까? – Jonathan

+1

궤적을 잡기 위해 수정 된 답변이 약간 있습니다. 동일한 논리를 사용하는 것과 관련하여 내가 추가 한 주석을 주목하십시오. 그 자리에 모든 논리를 놓으십시오. 작은 코드 조각을 포함시켜보다 나은 결과를 얻을 수 있습니다. – Jeremy

+3

두번째 예제에서, 여러분이 제공 한 코드 블록 (중괄호 사이의 내용)은 업데이트 확인이 완료되었을 때 호출됩니다. 이것은 콜백 (callback)이라고 불리우며, 내 업데이트 확인을 마쳤을 때 알려주므로 알 수있다. 나는 그것에 대해 뭔가 할 수있다. – Jeremy

3

dispatch_async은 비 차단이므로 업데이트 정보가 반환되기 전에 메소드가 반환됩니다 (발송 및 계속). needsUpdate은 기본적으로 NO으로 기본 설정되어 있습니다. 로그 타이밍에서이를 볼 수 있습니다. 서버 및 응용 프로그램 버전보다 "Needs Update No"가 나타납니다.

올바른 결과를 얻으려면 일종의 콜백 (대리자 메서드 또는 두 번째 예 : dispatch_async)이 필요합니다. 그렇지 않으면 차단해야합니다. NSURLConnectionsendAsynchronousRequest:queue:completionHandler:을 살펴 보는 것이 좋습니다. 완료시 완료 핸들러가 실행되며, 여기에서 업데이트 처리에 필요한 코드를 가질 수 있습니다.