2013-02-27 69 views
1

我正在为内部企业应用程序创建更新方法。我想创建的是一个我可以快速放入应用程序的类,它将检查服务器是否需要更新。这是我到目前为止,它检查正确,但它返回NO之前完成该方法。应用程序检查更新

在我checkUpdate.h

@interface checkForUpdate : NSObject 

+ (BOOL)updateCheck; 


@end 

在我checkUpdate.m

#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 

我这样称呼它

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

这是我的日志

Needs Update No 
Server Version 2.000000 
App Version 1.000000 

我不知道为什么它甚至在检查之前没有返回NO。我需要它是一个异步的,因为应用程序将检查的服务器在我们的防火墙后面。所以如果这个人在防火墙之外,当无法到达服务器时,应用程序需要继续。我是朝着正确的方向前进,还是有更好的方法?

回答

3

您正在异步检查更新,但期望通过您的方法设计立即做出响应。您可以将您的方法重新设计为如下例所示,以便在操作完成后通知处理程序:

注意:未检查并未检测到错误;然而,教训,从例子中得出是使用某种形式的回调:

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在整个检查更新它看起来你的应用程序

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 2013-02-27 18:51:58

+1

修改了一些答案,让你走上正轨。请注意我添加的有关使用相同逻辑的评论。把你所有的逻辑放在那个地方。我已经包含了一小段代码,以便您可以获得更好的方向。 – Jeremy 2013-02-27 19:06:49

+3

在我的第二个示例中,当您的更新检查完成时,将调用您提供的代码块(大括号之间的内容)。这被称为回调,这意味着,当你检查我的更新时,我知道了,所以我可以做一些关于它的事情。 – Jeremy 2013-02-27 19:12:28

3

由于dispatch_async是非阻塞的,因此您的方法在您的更新信息已返回(调度并继续)之前返回。由于needsUpdate默认为NO,这就是你会看到的。您可以在日志时间中看到这一点 - 在服务器和应用程序版本之前会显示“需要更新否”。

您需要某种回调(例如代表方法或第二个dispatch_async)以确保您获得正确的结果,或者需要阻止。我建议您查看NSURLConnectionsendAsynchronousRequest:queue:completionHandler: - 它会在完成时执行完成处理程序,您可以在其中拥有处理更新所需的任何代码。