// // HYBVersionManager.h // // Created by 黄仪标 on 15/1/27. // #import <Foundation/Foundation.h> // 应用已经发布到APP Store后才会在Itunes上有应用的链接 // 所以版本检测必须是已经发布过才能做 // 在真正实现功能时,需要替换成真正的链接 // @requared #define kAppStoreLink @"" #define kItunsLink @"" /*! * 版本管理器 */ @interface HYBVersionManager : NSObject /*! * @brief 单例方法 */ + (HYBVersionManager *)sharedVersionManager; /* * 调用此方法来执行版本检测 * @param type */ - (void)checkVersion:(int)type; @end
// // HYBVersionManager.m // // Created by 黄仪标 on 15/1/27. // #import "HYBVersionManager.h" #import "UIAlertView+Blocks.h" #define kRequestTimeOut 60.0 @interface HYBVersionManager () { int _type; UIAlertView *_alertView; } @end @implementation HYBVersionManager /*! * @brief 单例方法 */ + (HYBVersionManager *)sharedVersionManager { static HYBVersionManager *sharedObject = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (!sharedObject) { sharedObject = [[self alloc] init]; } }); return sharedObject; } - (instancetype)init { if (self = [super init]) { _type = 0; // 自动检测 } return self; } - (void)checkVersion:(int)type { _type = type; [self checkAppStoreVersion]; } - (void)checkAppStoreVersion { if ([NSThread isMainThread]) { [self performSelectorInBackground:@selector(checkAppStoreVersion) withObject:nil]; return; } @autoreleasepool { //prevent concurrent checks static BOOL checking = NO; if (checking) return; checking = YES; NSError *error = nil; NSURLResponse *response = nil; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:kItunsLink] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:kRequestTimeOut]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode; if (data && statusCode == 200) { error = nil; id json = nil; if ([NSJSONSerialization class]) { NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]; json = [dict[@"results"] lastObject]; } else { json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } if (!error) { // 获取到appstore上最新的版本号 NSString *latestVersion = [self valueForKey:@"version" inJSON:json]; NSString *localVersion = [self appLocalVersion]; [self check:latestVersion localVersion:localVersion]; } } // finished checking = NO; } } - (void)check:(NSString *)latestVersion localVersion:(NSString *)localVersion { if ([latestVersion compare:localVersion] == NSOrderedDescending) { // 有新版本 [self showPromptForUpdate]; } else if ([latestVersion compare:localVersion options:NSNumericSearch] == NSOrderedSame) {// 已经是最新版本 if (_type == 1) { // 手动 [self showMessage]; } } } - (void)showMessage { if (_alertView) { _alertView.hidden = YES; [_alertView removeFromSuperview]; _alertView = nil; } UIAlertView *alert = [UIAlertView showWithTitle:@"" message:@"当前版本已经是最新版本!" okButton:@"确定" cancelButton:nil]; _alertView = alert; } - (void)showPromptForUpdate { [UIAlertView showWithTitle:nil message:@"有新版本发布了,亲,快去更新吧!" cancelButtonTitle:@"暂不更新" otherButtonTitles:@[@"立即更新"] tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == 0) { } else { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:kAppStoreLink]]; } }]; } /*! * @brief 获取app本地的版本号 */ - (NSString *)appLocalVersion { NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; NSString *version = [info objectForKey:@"CFBundleVersion"]; return [version stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]]; } - (NSString *)valueForKey:(NSString *)key inJSON:(id)json { if ([json isKindOfClass:[NSString class]]) { //use legacy parser NSRange keyRange = [json rangeOfString:[NSString stringWithFormat:@"\"%@\"", key]]; if (keyRange.location != NSNotFound) { NSInteger start = keyRange.location + keyRange.length; NSRange valueStart = [json rangeOfString:@":" options:(NSStringCompareOptions)0 range:NSMakeRange(start, [(NSString *)json length] - start)]; if (valueStart.location != NSNotFound) { start = valueStart.location + 1; NSRange valueEnd = [json rangeOfString:@"," options:(NSStringCompareOptions)0 range:NSMakeRange(start, [(NSString *)json length] - start)]; if (valueEnd.location != NSNotFound) { NSString *value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)]; value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; while ([value hasPrefix:@"\""] && ![value hasSuffix:@"\""]) { if (valueEnd.location == NSNotFound) { break; } NSInteger newStart = valueEnd.location + 1; valueEnd = [json rangeOfString:@"," options:(NSStringCompareOptions)0 range:NSMakeRange(newStart, [(NSString *)json length] - newStart)]; value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)]; value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; } value = [value stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; value = [value stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"]; value = [value stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; value = [value stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""]; value = [value stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"]; value = [value stringByReplacingOccurrencesOfString:@"\\r" withString:@"\r"]; value = [value stringByReplacingOccurrencesOfString:@"\\t" withString:@"\t"]; value = [value stringByReplacingOccurrencesOfString:@"\\f" withString:@"\f"]; value = [value stringByReplacingOccurrencesOfString:@"\\b" withString:@"\f"]; while (YES) { NSRange unicode = [value rangeOfString:@"\\u"]; if (unicode.location == NSNotFound || unicode.location + unicode.length == 0) { break; } uint32_t c = 0; NSString *hex = [value substringWithRange:NSMakeRange(unicode.location + 2, 4)]; if (hex != nil) { NSScanner *scanner = [NSScanner scannerWithString:hex]; [scanner scanHexInt:&c]; } if (c <= 0xffff) { value = [value stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6) withString:[NSString stringWithFormat:@"%C", (unichar)c]]; } else { //convert character to surrogate pair uint16_t x = (uint16_t)c; uint16_t u = (c >> 16) & ((1 << 5) - 1); uint16_t w = (uint16_t)u - 1; unichar high = 0xd800 | (w << 6) | x >> 10; unichar low = (uint16_t)(0xdc00 | (x & ((1 << 10) - 1))); value = [value stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6) withString:[NSString stringWithFormat:@"%C%C", high, low]]; } } return value; } } } } else { return json[key]; } return nil; } @end
之前使用了iLink库,可是后来出现了很多的问题,于是不得不去掉,自己写一个,完全自主控制了。
这里功能很简单,一种是自动检测,也就是在应用启动的时候调用,
另一种是手动检测,一般是放在设置中的检查版本更新时,手动检测。