我正在为内部企业应用创建更新方法。我想要创建的是一个可以快速放入应用程序的类,它将检查服务器是否需要更新。这是我到目前为止,它正确检查,但它在完成方法之前返回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。我需要它是异步的,因为应用程序将检查的服务器位于我们的防火墙后面。因此,如果此人在防火墙之外,则应用程序需要在无法访问服务器时继续。我是朝着正确的方向前进,还是有更好的方法?
答案 0 :(得分:3)
由于dispatch_async
是非阻塞的,因此您的方法会在更新信息返回之前返回(发送并继续)。由于needsUpdate
默认为NO
,这就是您所看到的内容。您可以在日志时间中看到这一点 - 在服务器和应用程序版本之前显示“需要更新否”。
您需要某种回调(例如委托方法或第二个dispatch_async
)以确保获得正确的结果,或者您需要阻止。我建议查看NSURLConnection
和sendAsynchronousRequest:queue:completionHandler:
- 它将在完成时执行完成处理程序,您可以在其中获得处理更新所需的任何代码。
答案 1 :(得分: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];
}];