项目需求:
由于公司项目是做离线地图的,老板希望有版本更新时用户能及时更新,所以要求app第一次检测到版本更新时记录下来这次时间,如果30天后没更新,app只能使用5次,每次进入app就弹框提示更新和稍后更新,弹出第5次以后,若还未更新则强制用户更新,不然无法使用app,只有app更新版本后才能继续使用
实现思路:
通过联网检测项目在AppStore上的版本号与本地info.plist中获取的当前版本号对比,
若有新版本则跳转到AppStore项目页面下载
实现:
从info.plist中获取项目当前版本号:
NSDictionary *infoDic=[[NSBundle mainBundle] infoDictionary];
NSString *currentVersion=infoDic[@"CFBundleShortVersionString"];
发送网络请求获取App store中项目的最新版本号:
以下方法会发生请求从app store中检测app最新的信息,拿到最新的版本号会与info.plist中版本号进行对比判断,此方法中还封装了一些业务逻辑:app在第一次检测更新到30天以后,会在每次启动app时提示版本更新和稍后更新,5次以后若还未更新则强制用户更新,不然无法使用app,
具体根据公司的要求处理业务逻辑
下面方法也可以在application:didFinishLaunchingWithOptions:中调用
+ (void)checkAppVersionWithCompletion:(void (^)(BOOL isSuccess))completion {
[[NSUserDefaults standardUserDefaults] setObject:kCurrentVersion forKey:AppUpdateCheckCurrentVersionKey];
// 获取appStore版本号
[[[NSURLSession sharedSession] dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://itunes.apple.com/cn/lookup?id=953032158"]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(data && !error);
});
}
if (data == nil || error) {
return;
}
NSDictionary *appInfoDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
NSArray *array = [appInfoDic objectForKey:@"results"];
if (array.count < 1) {
return;
}
NSDictionary *dic = [array objectAtIndex:0];
NSString *appStoreVersion = [dic objectForKey:@"version"];
#if DEBUG
appStoreVersion = @"1000000";
#endif
BOOL isNewVersion = [kCurrentVersion compare:appStoreVersion options:NSNumericSearch] == NSOrderedAscending;
if (isNewVersion) {
NSTimeInterval fristCheckAppUpdateTime = [[NSUserDefaults standardUserDefaults] doubleForKey:FristCheckAppUpdateKey];
NSTimeInterval currentTimeInterval = [[NSDate date] timeIntervalSince1970];
if (fristCheckAppUpdateTime <= 0.0) {
// 记录第一次版本检测到版本更新的时间
fristCheckAppUpdateTime = currentTimeInterval;
[[NSUserDefaults standardUserDefaults] setDouble:fristCheckAppUpdateTime forKey:FristCheckAppUpdateKey];
}
BOOL isTipUpdate = NO;
if (!AppUpdateCheckDayCount) {
isTipUpdate = YES;
} else {
NSTimeInterval day30LaterInterval = [NSDate getTimeIntervalWithDayCount:AppUpdateCheckDayCount fromTimeInterval:fristCheckAppUpdateTime];
// 当第一次提示更新到现在有30天了,就在每次启动app时提示用户更新app
isTipUpdate = currentTimeInterval >= day30LaterInterval;
}
if (isTipUpdate) {
__block NSInteger currentTipCount = [[NSUserDefaults standardUserDefaults] integerForKey:AppUpdateCheckUpdateApkWarnTipCountKey];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSString *message = nil;
NSArray *buttonTitles = @[];
if (currentTipCount >= AppUpdateCheckMaxTipCount) {
message = @"程序有最新版本,请更新并运行新版";
buttonTitles = @[@"立即更新"];
#if DEBUG
buttonTitles = @[@"立即更新", @"Reset"];
#endif
} else {
message = [NSString stringWithFormat:@"程序有最新版本,是否更新?请注意:您当前的版本还有%ld次使用机会", AppUpdateCheckMaxTipCount-currentTipCount];
buttonTitles = @[@"立即更新", @"稍后更新"];
}
currentTipCount++;
[[NSUserDefaults standardUserDefaults] setInteger:currentTipCount forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
[UIAlertView showWithTitle:@"有可用版本更新" message:message cancelButtonTitle:nil otherButtonTitles:buttonTitles tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
if (buttonIndex == 0) {
NSURL *url = [NSURL URLWithString:[@"https://itunes.apple.com/us/app/id953032158?ls=1&mt=8" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if ([UIDevice currentDevice].systemVersion.floatValue >= 10.0f) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}
#if DEBUG
if (buttonIndex == 1 && [buttonTitles containsObject:@"Reset"]) {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#endif
}];
});
} else {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
} else {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}] resume];
}
当app未更新且提示次数超过5次时就强制用户更新,可以在applicationDidBecomeActive中调用下面的方法提示更新,拦截用户进入app
// 强制更新
+ (void)showUpdateApp {
// 为了防止app更新完成后 启动时获取的currentTipCount值没有改变,会导致再次提示一次强制更新,这里在checkAppVersion时将版本存起来,然后更新完成后再对比就不会出现问题
NSString *currentVersion = [[NSUserDefaults standardUserDefaults] stringForKey:AppUpdateCheckCurrentVersionKey];
BOOL isNewVersion = [currentVersion compare:kCurrentVersion options:NSNumericSearch] == NSOrderedAscending;
// 如果kCurrentVersion大于currentVersion,说明当前版本已经更新了
if (!isNewVersion) {
// 当app未更新且提示次数超过5次时就强制用户更新
NSInteger currentTipCount = [[NSUserDefaults standardUserDefaults] integerForKey:AppUpdateCheckUpdateApkWarnTipCountKey];
if (currentTipCount >= AppUpdateCheckMaxTipCount) {
NSArray *buttonTitles = @[@"立即更新"];
#if DEBUG
buttonTitles = @[@"立即更新", @"Reset"];
#endif
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIAlertView showWithTitle:@"有可用版本更新" message:@"程序有最新版本,请更新并运行新版" cancelButtonTitle:nil otherButtonTitles:buttonTitles tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) {
if (buttonIndex == 0) {
NSURL *url = [NSURL URLWithString:[@"https://itunes.apple.com/us/app/id953032158?ls=1&mt=8" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if ([UIDevice currentDevice].systemVersion.floatValue >= 10.0f) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}
#if DEBUG
if (buttonIndex == 1 && [buttonTitles containsObject:@"Reset"]) {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#endif
}];
});
}
} else {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:AppUpdateCheckUpdateApkWarnTipCountKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}