iOS开发-检查版本更新与强制更新控制。
在开发中经常遇到需要检查版本,检查版本及请求appstoreLookUrl查看版本号与当前的版本号进行比对,看是否需要更新。强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
发送请求系统NSURLConnection sendAsynchronousRequest
代码如下
SDVersionManager.h
#import <Foundation/Foundation.h>
@interface SDVersionManager : NSObject<NSCoding>
@property (nonatomic,strong) NSString *lastVersionCode; //版本code
@property (nonatomic,strong) NSString *lastVersion; //保存最新的版本lastVersion
@property (nonatomic,strong) NSString *versionNotes; //版本更新的记录releaseNotes
+ (instancetype)sharedInstance;
/**
检测版本更新,如果有新版本,提醒用户更新,提醒一次
@param needUpdate 需要更新的回调
@param failure 不需要更新
*/
+ (void)checkAppVersion:(void (^) (void))needUpdate
failure:(void (^) (void))failure;
@end
#pragma mark - SDVersionManagerDB
@interface SDVersionManagerDB : NSObject
+ (instancetype)sharedInstance;
/**
获取自定义对象UpdatedVersion实体,反序列化操作
@return UpdatedVersion 实体
*/
- (SDVersionManager *)loadLastVersion;
/**
保存自定义对象序列号
@param version UpdatedVersion实体
@return 是否保存成功
*/
- (BOOL)saveLastVersion:(SDVersionManager *)version;
@end
SDVersionManager.m
#import "SDVersionManager.h"
#import "SDContextManager.h"
#define kDataFileVersion @"UpdatedVersion"
#define kDocumentPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]
@class SDVersionManagerDB;
@implementation SDVersionManager
/**
单例模式使用 dispatch_once_t if不是线程安全的
@return 实例对象
*/
+ (instancetype)sharedInstance
{
static SDVersionManager *_sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[SDVersionManagerDB sharedInstance] loadLastVersion];
if (_sharedInstance == nil) {
_sharedInstance = [[SDVersionManager alloc] init];
_sharedInstance.lastVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
}
});
return _sharedInstance;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_lastVersionCode forKey:NSStringFromSelector(@selector(lastVersionCode))];
[aCoder encodeObject:_lastVersion forKey:NSStringFromSelector(@selector(lastVersion))];
[aCoder encodeObject:_versionNotes forKey:NSStringFromSelector(@selector(versionNotes))];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
_lastVersionCode = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(lastVersionCode))];
_lastVersion = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(lastVersion))];
_versionNotes = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(versionNotes))];
}
return self;
}
/**
检测版本更新,如果有新版本,提醒用户更新,提醒一次
@param needUpdate 需要更新的回调
@param failure 不需要更新
*/
+ (void)checkAppVersion:(void (^) (void))needUpdate
failure:(void (^) (void))failure {
NSURL *appstoreUrl = [NSURL URLWithString:[SDContextManager shareInstance].appstoreLookUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:appstoreUrl];
NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
NSString *bundleCurrentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
__weak typeof(currentVersion) weakCurrentVersion = currentVersion;
__weak typeof(bundleCurrentVersion) weakBundleCurrentVersion = bundleCurrentVersion;
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
if (!connectionError) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];
NSArray *results = [dic objectForKey:@"results"];
if ([results count] > 0) {
NSDictionary *resultValue = [results objectAtIndex:0];
NSString *versionStr = [resultValue objectForKey:@"version"];
NSString *version = [[resultValue objectForKey:@"version"] stringByReplacingOccurrencesOfString:@"." withString:@""];
NSString *note = [resultValue objectForKey:@"releaseNotes"];
NSString *curVersion = [weakCurrentVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
NSString *curBundleVersion = [weakBundleCurrentVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
[SDVersionManager sharedInstance].versionNotes = note;
if ([curVersion integerValue] < [version integerValue]) {
//当前版本比appstore上低
NSString *alastVerstion = [SDVersionManager sharedInstance].lastVersion;
if (alastVerstion && version && ([alastVerstion integerValue] < [version integerValue])) {
[SDVersionManager sharedInstance].lastVersion = version;
[SDVersionManager sharedInstance].lastVersionCode = versionStr;
if (needUpdate) {
needUpdate();
}
} else {
if (failure) {
failure();
}
}
} else if ([curVersion integerValue] <= [version integerValue]) {
//当前版本比appstore上相同
[SDVersionManager sharedInstance].lastVersion = version;
[SDVersionManager sharedInstance].lastVersionCode = versionStr;
if (failure) {
failure();
}
} else if ([curVersion integerValue] > [version integerValue]) {
//当前版本比appstore上高
[SDVersionManager sharedInstance].lastVersion = version;
[SDVersionManager sharedInstance].lastVersionCode = versionStr;
if (failure) {
failure();
}
}
[[SDVersionManagerDB sharedInstance] saveLastVersion:[SDVersionManager sharedInstance]];
}
} else {
if (failure) {
failure();
}
}
}];
}
@end
#pragma mark - SDVersionManagerDB
@implementation SDVersionManagerDB
+ (instancetype)sharedInstance {
static SDVersionManagerDB *_sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[SDVersionManagerDB alloc] init];
});
return _sharedInstance;
}
/**
获取自定义对象UpdatedVersion实体,反序列化操作
@return UpdatedVersion 实体
*/
- (SDVersionManager *)loadLastVersion {
NSString *dataFile = [NSString stringWithFormat:@"%@/%@", kDocumentPath, kDataFileVersion];
@try
{
SDVersionManager *version = (SDVersionManager *)[NSKeyedUnarchiver unarchiveObjectWithFile:dataFile];
if (version) {
return version;
}
}
@catch (NSException *e)
{
}
return nil;
}
/**
保存自定义对象序列化
@param version UpdatedVersion实体
@return 是否保存成功
*/
- (BOOL)saveLastVersion:(SDVersionManager *)version {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:version];
NSString *dataFile = [NSString stringWithFormat:@"%@/%@", kDocumentPath, kDataFileVersion];
return [data writeToFile:dataFile atomically:YES];
}
@end
强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
这块暂时就不写请求服务端的代码了。
iOS开发-检查版本更新与强制更新控制。
在开发中经常遇到需要检查版本,检查版本及请求appstoreLookUrl查看版本号与当前的版本号进行比对,看是否需要更新。强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
学习记录,每天不停进步。