iOS开发实战 - 如何更灵活的控制App版本更新

  1. 自从iOS可以在设置中开启App自动更新后,越来越多的App不再弹框提示用户进行版本更新,尤其是强制更新,其实苹果并不建议在App中加入用户更新的提示,如果在应用审核期间被看到,会大大增加被拒的风险;
  2. 但是在项目前期,特别是中小公司的项目,应用内容生态不完整,产品设计也经常变化,bug频出,每次版本更新的改动较大,为了用户更好的体验,不得不进行版本更新的提示,甚至较重要的版本会采用强制更新的提示;
  3. 很多时候需要在应用审核期间做出一些差异来躲避审核策略,比如:改变登录方式,隐藏支付方式等需求,因此最新版本号掌握在自己的手里就显得至关重要;

方法一:通过获取应用在AppStore最新的版本号,并与应用当前版本号做对比

优点:不需要提供额外的API,后续版本更新管理简单

缺点:

  1. 获取版本号会出现延迟或版本号不稳定,会出现与刚刚发布的版本号对不上的情况;
    解决办法:将"https://itunes.apple.com/lookup?id=" 更换为:"https://itunes.apple.com/cn/lookup?id=",后者服务器在国内,延迟低,但偶尔还是会出现版本号对不上的情况。
  2. 从AppStore检查版本更新,审核被拒的风险很大;
  3. 灵活性差,每个版本只能设定一种提示方式,例如需要根据本次更新的内容进行版本更新提示,可能需要经常改动这块代码,比如: 优化体验,变动不大可能需要“本次更新不提示”,增加新功能可能需要“建议更新”,修复重大bug可能需要“强制更新”。

方法二:通过请求自己服务器的App版本更新API获取App最新版本号,同时获取本次更新提示的方式

优点:更灵活,请求回来的版本号可控,提示更新方式掌握在自己手中

缺点:

  1. 需要后台多提供两个API
    获取更新版本号;
    更改最新版本号;
  2. 以后每次发布新版本后需要去更改最新版本号
详细介绍一下第二种方法:
App版本更新

服务端API:
1.获取最新版本号
2.应用发布后修改最新版本号
建议:
1.检查更新可以放到子线程里面去做,防止线程阻塞;
附加:强制更新
追加一个是否强制更新的参数

主要代码:
下面实例代码不仅控制了版本更新提示方式,还控制了在应用审核期间的用户登录方式,同样你也可以在其中加入控制支付方式的需求

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //默认登录方式为验证码登录
    [UD integerForKey:IS_CHECK_PASS];
    [self getAppStoreVersion];
}

- (void)getAppStoreVersion {
    [YQHttpRequest getData:@{@"commonAppType":@"IOS"} url:@"/common/app/version/getAppVersion" success:^(id responseDic) {
        if ([responseDic[@"status"] isEqualToString:@"0"]) {
            NSString *updateCode = [NSString new];
            if (responseDic[@"appIsUpdate"]) {
                updateCode = responseDic[@"appIsUpdate"];
            }
            unsigned int appStoreVersion = [[responseDic[@"message"] stringByReplacingOccurrencesOfString:@"." withString:@""] unsignedIntValue];
            [self checkAppUpdateWithAppVersion:appStoreVersion appIsUpdate:updateCode];
        } else {
            [UD setInteger:1 forKey:IS_CHECK_PASS];
        }
    } fail:^(NSError *error) {
        [UD setInteger:1 forKey:IS_CHECK_PASS];
        NSLog(@"%@",error);
    }];
}

//检查更新
- (void)checkAppUpdateWithAppVersion:(unsigned int)appStoreVersion appIsUpdate:(NSString *)updateCode {
    //获取当前版本
    unsigned int nowVersion = [[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] stringByReplacingOccurrencesOfString:@"." withString:@""] unsignedIntValue];
    //对比版本
    if (appStoreVersion < nowVersion){
        //未审核通过-密码登录
        [UD setInteger:0 forKey:IS_CHECK_PASS];
    }else {
        //审核通过-验证码登录
        [UD setInteger:1 forKey:IS_CHECK_PASS];
        if (appStoreVersion > nowVersion) {
            //需要更新-是否弹出更新
            switch (updateCode.intValue) {
                case 0: //不更新
                    break;
                case 1: //强制更新
                {
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"为了提供更卓越的服务,请您更新APP后使用" delegate:self cancelButtonTitle:nil otherButtonTitles:@"立即更新", nil];
                    alert.tag = 88;
                    [alert show];
                }
                    break;
                case 2: //建议更新
                {
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"为了提供更卓越的服务,请您更新APP后使用" delegate:self cancelButtonTitle:@"残忍拒绝" otherButtonTitles:@"去更新", nil];
                    alert.tag = 66;
                    [alert show];
                }
                default:
                    break;
            }
        }
    }
}

#prama mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (alertView.tag == 66) {
        //建议更新
        if (buttonIndex == 1) {
            NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://itunes.apple.com/cn/app/xing-dong/id%@?l=zh&ls=1&mt=8", APPLE_ID]];
            [[UIApplication sharedApplication]openURL:url];
        }
    } else if (alertView.tag == 88) {
        //强制更新
        if (buttonIndex == 0) {
            NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://itunes.apple.com/cn/app/xing-dong/id%@?l=zh&ls=1&mt=8", APPLE_ID]];
            [[UIApplication sharedApplication] openURL:url];
            //强制退出App
            exit(0)
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352