最近有朋友问我怎么在自己的 App 中添加提示更新、甚至强制更新 App 的有关内容。简单说一下,通过比较 AppStore 和 当前安装 App 的版本号差异,如果 AppStore 中的版本号较大,那么就弹出提示更新窗口。(如:v1.2.1 比 v1.2.0 要大,此时我们获取到的版本号是一个字符串,我们可以通过字符串比较大小来处理。)
但是,此处有两个问题需要注意:
① apple 现如今增加了 AppStore 与 用户 之间的粘性,要求用户只能通过 AppStore 进行更新升级 App。新的上架规则不允许在 App 内部有相关提醒用户进行版本升级更新的提示信息,一旦发现很大程度上会被拒。我也见过类似的被拒信息,如下图:
② 我们要拿到 AppStore 上面版本号,如果是我们前端来做,那么就需要请求 apple 的越洋接口了 - - ,显然这个接口很不稳定,有几率请求失败。
问题已经列出来了。那么下面列一下在我项目中的检查版本更新的代码:
首先我们可以在搜索引擎上搜索你要寻找的 App 在 AppStore 上面的内容地址,如:(王者荣耀在AppStore上面的链接)
https://itunes.apple.com/cn/app/wang-zhe-rong-yao-mi-wu-mo/id989673964?mt=8
然后拿到当前 App 在 AppStore 上面的唯一 id,也就是上面链接上的 989673964。
然后拼接请求 url:(下面是固定格式)
NSString *url = [[NSString alloc] initWithFormat:@"http://itunes.apple.com/lookup?id=%@", @"989673964"];
- (void)updateVersion {
// 获取本地版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"]; // 就是在info.plist里面的 version
// 取得AppStore信息
NSString *url = [[NSString alloc] initWithFormat:@"http://itunes.apple.com/lookup?id=%@", @"989673964"];
AFHTTPSessionManager *manager = [BPBServerReqestUtils sharedHTTPSession];
[manager GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"responseObject --- %@", responseObject);
NSArray *resultArr = responseObject[@"results"];
NSDictionary *resultsDict = resultArr.firstObject;
// 取更新日志信息
NSString *changeStr = resultsDict[@"releaseNotes"];
// app store 最新版本号
AppStoreVersion = resultsDict[@"version"];
// app store 跳转版本链接
_trackViewUrl = resultsDict[@"trackViewUrl"];
NSLog(@"app store 的更新信息 --- %@, app store 的最新版本号 --- %@", changeStr, AppStoreVersion);
// AppStore版本号大于当前版本号,强制更新
if ([AppStoreVersion compare:currentVersion options:NSNumericSearch] == NSOrderedDescending) {
// 弹窗 更新
BPBUpdateAlertView *updateAlertView = [BPBUpdateAlertView updateAlertViewFrame:[UIApplication sharedApplication].keyWindow.bounds version:[NSString stringWithFormat:@"V %@", AppStoreVersion] changeStr:changeStr];
updateAlertView.updateAlertDelegate = self;
[[UIApplication sharedApplication].keyWindow addSubview:updateAlertView];
} else {
// 正常进入程序
[self autoLogin];
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// [SVProgressHUD showInfoWithStatus:@"网络异常"];
// 网络异常时,正常进入程序
[self autoLogin];
}];
}
2017-05-26 14:14:25.445097+0800 BPB[4666:1822321] responseObject --- {
resultCount = 1;
results = (
{
advisories = (
);
appletvScreenshotUrls = (
);
artistId = 11231350027;
artistName = "xxx";
artistViewUrl = "https://itunes.apple.com/us/developer/shenzhen-ben-pao-bao-technology-fsfs50027?uo=4";
artworkUrl100 = "http://is4.mzstatic.com/image/thumb/Purple127/v4/de/2b/basdfsfsbbaf5-de76-37c2-23fc-324d187fde41/source/100x100bb.jpg";
artworkUrl512 = "http://is4.mzstatic.com/image/thumb/Purple127/v4/de/2b/ba/de2bbaf5-de76-37c2-23fc-32sfsfsdse41/source/512x512bb.jpg";
artworkUrl60 = "http://is4.mzstatic.com/image/thumb/Purple127/v4/de/2bsdsde2bbaf5-de76-37c2-23fc-324d187fde41/source/60x60bb.jpg";
bundleId = "com.benpaobao.dev";
contentAdvisoryRating = "4+";
currency = USD;
currentVersionReleaseDate = "2017-05-15T18:03:56Z";
description = "app 描述信息";
features = (
);
fileSizeBytes = 107344896;
formattedPrice = Free;
genreIds = (
6012,
6000
);
genres = (
Lifestyle,
Business
);
ipadScreenshotUrls = (
);
isGameCenterEnabled = 0;
isVppDeviceBasedLicensingEnabled = 1;
kind = software;
languageCodesISO2A = (
ZH
);
minimumOsVersion = "8.0";
price = 0;
primaryGenreId = 6012;
primaryGenreName = Lifestyle;
releaseDate = "2016-12-14T20:32:57Z";
releaseNotes = "版本更新信息";
screenshotUrls = (
"http://a5.mzstatic.com/us/r30/Purple122/v4/64/3c/1b/643c1ba9-971e-1f59-94e8-d57f914d9fa4/screen69233x696.jpeg",
"http://a1.mzstatic.com/us/r30/Purple111/v4/60/e9/7c/60e97c1b-8fb5-8643-c85b-739123696x696.jpeg",
"http://a2.mzstatic.com/us/r30/Purple122/v4/62/2a/27/622a27ce-42f0-c38b-1c25-a513d3da9911/scree3213696.jpeg",
"http://a1.mzstatic.com/us/r30/Purple111/v4/0e/5a/74/0e5a74ba-87a5-d38c-71233d8907e6778/screen696x696.jpeg",
"http://a1.mzstatic.com/us/r30/Purple122/v4/33/7d/95/337d9536-a915-68b3-4827-ed3a6fe39831/screen691236.jpeg"
);
sellerName = "xxx";
sellerUrl = "xxx";
supportedDevices = (
"iPad2Wifi-iPad2Wifi",
"iPad23G-iPad23G",
"iPhone4S-iPhone4S",
"iPadThirdGen-iPadThirdGen",
"iPadThirdGen4G-iPadThirdGen4G",
"iPhone5-iPhone5",
"iPodTouchFifthGen-iPodTouchFifthGen",
"iPadFourthGen-iPadFourthGen",
"iPadFourthGen4G-iPadFourthGen4G",
"iPadMini-iPadMini",
"iPadMini4G-iPadMini4G",
"iPhone5c-iPhone5c",
"iPhone5s-iPhone5s",
"iPadAir-iPadAir",
"iPadAirCellular-iPadAirCellular",
"iPadMiniRetina-iPadMiniRetina",
"iPadMiniRetinaCellular-iPadMiniRetinaCellular",
"iPhone6-iPhone6",
"iPhone6Plus-iPhone6Plus",
"iPadAir2-iPadAir2",
"iPadAir2Cellular-iPadAir2Cellular",
"iPadMini3-iPadMini3",
"iPadMini3Cellular-iPadMini3Cellular",
"iPodTouchSixthGen-iPodTouchSixthGen",
"iPhone6s-iPhone6s",
"iPhone6sPlus-iPhone6sPlus",
"iPadMini4-iPadMini4",
"iPadMini4Cellular-iPadMini4Cellular",
"iPadPro-iPadPro",
"iPadProCellular-iPadProCellular",
"iPadPro97-iPadPro97",
"iPadPro97Cellular-iPadPro97Cellular",
"iPhoneSE-iPhoneSE",
"iPhone7-iPhone7",
"iPhone7Plus-iPhone7Plus",
"iPad611-iPad611",
"iPad612-iPad612"
);
trackCensoredName = "xxx";
trackContentRating = "4+";
trackId = 233231134;
trackName = "xxx";
trackViewUrl = "xxx";
version = "1.2.3";
wrapperType = software;
}
);
}
所以说,我们通常不会用这种方式去请求版本信息。
正确的做法是让后台提供一个接口,手动去填最新版本的信息,然后请求我们自己的接口去获取到这些有用的信息。再进行版本判定。