App啓動更新

咱們在平常開發中,常常遇到須要對app進行更新的問題,除了在app store中找到你的應用並更新,還能夠在app內提示應用更新,這種方式的場景是,當咱們的app過審,咱們須要在同一時間告知用戶,咱們的新版本已經發布,並根據要求用戶更新的急緩程度,採用軟更和強更的方式,完成版本更新。bash

選擇更新方式

推送更新的方式有多種,但通常都是在啓動時,經過對比版本並決定是否要參與更新:網絡

1.跟服務端錄好的版本號配對,這種方式更新的掌握權在運營者本身身上,能夠決定須要跟新的時間,統一放出更新消息。服務端推更和應用內推送推更的原理同樣,基於推更穩定和服務人羣數量,各有利弊。session

2.跟iTunes 上的版本號對比,也是在每次啓動時,比較版本,提示更新,這種作法更爲直接。app

如何選擇適合本身的更新,具體要根據產品定位來設計。ui

代碼

這裏只介紹iTunes方式。
url

1.比較更新spa

GGXVersion.h設計

+ (instancetype)share;
- (void)showVersion:(void (^)(NSString *))version;複製代碼

GGXVersion.m
代理

+ (instancetype)share {
    static GGXVersion *ggxVersion = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ggxVersion = [[GGXVersion alloc] init];
    });
    return ggxVersion;
}
//獲取最新版本號
- (void)showVersion:(void (^)(NSString *))version {
    [self request:^(NSString *storeVersion) {
        NSLog(@"version %@",storeVersion);
        NSString *new = [self compVersion:storeVersion];
        version(new);
    }];
}
/**
 typedef enum _NSComparisonResult {
 NSOrderedAscending = -1,    // <
 NSOrderedSame,              // =
 NSOrderedDescending         // >
 } NSComparisonResult;
 */
//比較版本大小
- (NSString *)compVersion:(NSString *)storeVersion {
    NSString *bundleVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    //v1>v2
    if ([storeVersion compare:bundleVersion options:NSNumericSearch] == NSOrderedDescending)
        NSLog(@"須要更新,store最新版本是: %@",storeVersion);
        return storeVersion;
}
//NSURLSession請求
- (void)request:(void (^)(NSString *))comp {
    //請求地址
    NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com/cn/lookup?id=1438938483"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    /* 發送HTTPS請求是須要對網絡會話設置代理的 */
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        if (error == nil) {
            //返回的數據
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            NSArray *res = dict[@"results"];
            //NSLog(@"%@",dict);
            if (res.count > 0) {
                NSString *storeVersion = res[0][@"version"];
                comp(storeVersion);
            }
        }
    }];
    [dataTask resume];
}
// 請求身份驗證,遵循協議<NSURLSessionDataDelegate>
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    // 提供身份驗證請求的信息
    NSLog(@"被保護空間 %@",challenge.protectionSpace);
    // NSURLAuthenticationMethodServerTrust: ServerTrust認證,適用於任何協議
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
        return;
    }
    NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
複製代碼

2.封裝提示框
code

GGXAlert.h

/**
 初始化彈框

 @param vc alert添加到哪層,默認window
 @param title 標題
 @param message 描述內容
 @param style alert樣式
 @param titleArray 須要建立的按鈕數量
 @param cancel 是否須要建立【取消】,默認不建立,按鈕名稱本身定義
 @param alertAction 回調按鈕對應下標
 */
+ (void)alertControllerWithVC:(UIViewController *__nullable)vc title:(NSString *)title message:(NSString *)message style:(UIAlertControllerStyle)style titleArray:(NSArray *)titleArray needCancel:(NSString *__nullable)cancel alertAction:(void (^)(NSInteger index))alertAction;複製代碼

GGXAlert.m

+ (void)alertControllerWithVC:(UIViewController *__nullable)vc title:(NSString *)title message:(NSString *)message style:(UIAlertControllerStyle)style titleArray:(NSArray *)titleArray needCancel:(NSString *__nullable)cancel alertAction:(void (^)(NSInteger))alertAction {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:style];
    for (NSInteger i = 0; i < titleArray.count; i++) {
        UIAlertAction *confirm = [UIAlertAction actionWithTitle:titleArray[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            if (alertAction) {
                alertAction(i);
            }
        }];
        [alert addAction:confirm];
        
    }
    if (cancel != nil) {
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            if (alertAction) {
                alertAction(titleArray.count);
            }
        }];
        [alert addAction:cancelAction];
    }
    [self showUPdate:alert currentVC:vc];
    
}
+ (void)showUPdate:(UIAlertController *)alert currentVC:(UIViewController *__nullable)vc {
    
    if (!vc) {
        UIWindow   *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        alertWindow.rootViewController = [[UIViewController alloc] init];
        alertWindow.windowLevel = UIWindowLevelAlert + 1;
        [alertWindow makeKeyAndVisible];
        [alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
    }else {
        [vc presentViewController:alert animated:YES completion:nil];
    }
    
}
複製代碼

因爲在代碼中設置alert默認在window最上層,除非覆蓋,另外咱們還能夠將alert直接添加到當前視圖中

3.實現

AppDelegate.m

GGXVersion *gxv = [GGXVersion share];
    [gxv showVersion:^(NSString * _Nonnull version) {
        NSString *title = [NSString stringWithFormat:@"最新版本 %@",version];
        [GGXAlert alertControllerWithVC:nil title:title message:@"發現新版本,是否當即更新?" style:UIAlertControllerStyleAlert titleArray:@[@"當即升級"] needCancel:@"下次再說" alertAction:^(NSInteger index) {
            if (index == 0) {
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://apps.apple.com/kh/app/super-fowlst/id1438938483"]];
                exit(0);
            }

        }];
    }];複製代碼

這裏有必要說一下 exit(0)終止程序,若是咱們須要使用強更,在跳轉下載頁面後再次跳回app會再次提示彈窗,這裏作了一個障眼法,看似回到app後保持原頁面,實則已經終止程序而是再次啓動,可是建議通常狀況下不要過於依賴exit,會形成用戶體驗很差。


最後

咱們將要說一下軟更新和強更新

軟更新有更多可選內容,用戶不更新也能夠作到正常使用。咱們能夠設置更新暫不提醒、跳過,更新:用戶跳轉到下載頁面,即便不下載再次回到app依然可使用;暫不提醒:設置一個週期,好比三天,會再次彈出這個更新提醒;跳過:再次啓動app依然提醒用戶更新。

強更新,用戶沒法選擇,只有贊成更新才能繼續使用應用。

純屬我的分享,但願對iOS社區能有更多貢獻。

相關文章
相關標籤/搜索