美文网首页iOS开发技术iOS在路上知识总结
iOS 版本更新(强制更新)检测问题

iOS 版本更新(强制更新)检测问题

作者: 清河湾 | 来源:发表于2016-08-19 10:16 被阅读13905次

    12月1日更新

    谢谢,@搬砖技术的提醒
    需要添加些注意事项:

    版本号对比是需要相同的位数的情况下的

    比如:位数不同的没法比较, 比如 2.3.10与2.4.1 和 2.3.9 与 2.3.10 , 这个时候 2.3.10 应该是变成2.4.0
    如果是后续需要 多位的那应该也是 2.004.001 ,补足位数,才有可比性.

    5月 18日 更新

    这部分是之前对比有BUG的,现在已经修复了.


    Paste_Image.png

    ------------------------------------------------------------------------------------------

    原文

    通常iOS系统中是默认设置再wifi状态,且网络状况良好下自己更新应用的.
    但是如果用户设置了不自动更新,但是我们的APP出现重要的版本,一定需要用户更新的情况下,就会需要这个功能了.

    这个版本更新一般会有两种方式:
    1.在自己的服务器上部署上一个文件,写入版本数据,然后app去获取版本数据,与自己的当前版本比对, 提示更新
    优点:可自定义更新模式(强制更新,选择更新)
    缺点:APP审核的时间不可控
    2.去AppStore获取当前发布的版本号,与用户当前版本比对,然后提示更新.
    优点:版本更新的时间精准
    缺点:自定义空间小
    这两种方法一般推荐第2种....
    需要自定义更新模式的(强制更新,选择更新)推荐使用第一种

    //第二种
    /*版本更新检测
    284882215 (Facebook APP ID)
    
    //中国区,需要再.com后面加 /cn 下面已经加,测试对于外国的APP也能行
    
    #define APP_URL @"http://itunes.apple.com/cn/lookup?id=你程序的appId"
    
    请求网络数据,返回的大致数据如下,其他还有好多数据,我们把关键的给截取出来
    
    {  
        resultCount = 1;  
        results =     (  
                    {  
                artistId = 开发者 ID;  
                artistName = 开发者名称; 
                price = 0; 
                isGameCenterEnabled = 0;  
                kind = software;  
                languageCodesISO2A =             (  
                    EN  
                ); 
                trackCensoredName = 审查名称;  
                trackContentRating = 评级;  
                trackId = 应用程序 ID;  
                trackName = 应用程序名称";  
                trackViewUrl = 应用程序介绍网址(下载地址);  
                userRatingCount = 用户评级;  
                userRatingCountForCurrentVersion = 1;  
                version = 版本号;  
                wrapperType = software; 
          }  
        );  
    }  
    NSString *version =  responseObject[@"results"][@"version"]; //版本号
    NSString *trackViewUrl =  responseObject[@"results"][@"trackViewUrl"]; //程序下载地址
    取得这些数据后关键的信息就是“ version”最新版本号和“ trackViewUrl”程序下载地址。然后与本地程序的版本比较即可。
    */
    ##这个你可以参照下面第一种的过程都一样
    
    请求数据 -> 判断版本 -> 提示或不提示-> 后续操作
    
    

    //第一种

    你首先要去后台配置这个版本更新文件,json文件,或者txt文件也行,可配置的,(后台搞定)

    在进入程序的时候 去后台接口,请求这个数据
    /*
    示例 josn格式
    AFNetworking请求回来responseObject的格式  (请求我就不写了,这种代码烂大街咯)
    {
        iosDownload = "itms-apps://itunes.apple.com/cn/app/wang-yi-yun-yin-le-pao-bufm/id590338362?mt=8";
        iosForce = 0; //控制强制更新
        iosUpdateMsg = "更新信息,哈哈哈😄";
        iosVersion = "v1.2.5";
    }
    */
    #pragma mark - 强制更新需要加上这个通知的监听,就是无论怎么打开 ,都会提示更新(有点流氓,慎用)
    - (void)viewDidLoad {
        [super viewDidLoad];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(versionIFUpdata) name:UIApplicationDidBecomeActiveNotification object:nil];
    }
     
    #pragma mark - 判断版本生是否更新,如有更新,提示用户升级,的方法
    -(void)versionIFUpdata
    {
    
        //是否是强制更新
        BOOL force = [_responseObject[@"iosForce"] intValue];
        
        if (force)
        {
            [self forceUpVersion]; //强制
            
        }else
        {
            [self upVersion];  //选择
        }
    
    }
    #pragma mark - 强制更新
    -(void)forceUpVersion
    {
    
        NSString *iosDownload;
        NSString *iosVersion;
        
        BOOL force  = [_responseObject[@"iosForce"] intValue];
        iosDownload = _responseObject[@"iosDownload"];
    //    iosDownload = @"itms-apps://itunes.apple.com/cn/app/wang-yi-yun-yin-le-pao-bufm/id590338362?mt=8";
        iosVersion = _responseObject[@"iosVersion"];
        //更新描述
        NSString *detail = _responseObject[@"iosUpdateMsg"];
    
        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"" message:[NSString stringWithFormat:@"检测到有新版本:%@ \n该版本是重要版本,不更新将导致应用不可用 \n%@",iosVersion,detail] preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                // itms-apps://itunes.apple.com/cn/app/wang-yi-yun-yin-le-pao-bufm/id590338362?mt=8
                NSURL *url = [NSURL URLWithString:iosDownload];
                [[UIApplication sharedApplication] openURL:url];
                upDateflag = NO;
                
        }];
            
        [alertVC addAction:action1];
        [self presentViewController:alertVC animated:YES completion:nil];
    }
    #pragma mark - 选择更新
    -(void)upVersion
    {
        
        
        NSString *iosDownload;
        NSString *iosVersion;
        
    
        
        iosDownload = _responseObject[@"iosDownload"];
    #pragma mark - 注意在这里跳转到APPstore需要URL Schemes :"itms-apps://............."
    //    iosDownload = @"itms-apps://itunes.apple.com/cn/app/wang-yi-yun-yin-le-pao-bufm/id590338362?mt=8";
        iosVersion = _responseObject[@"iosVersion"];
        
    //去掉其他,只保留数字
    iosVersion = [[iosVersion componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""];
    
    #pragma  mark -  获取当前本地的版本号
        NSDictionary *localDic =[[NSBundle mainBundle] infoDictionary];
        NSString *localVersion =[localDic objectForKey:@"CFBundleShortVersionString"];
    //去掉其他,只保留数字
        localVersion = [[localVersion componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""];
    //这里需要补齐位数,保证 版本号位数相同的情况下再进行比较 
        if(iosVersion.length != localVersion.length){
            NSInteger gap = 0;
            if(iosVersion.length > localVersion.length){
                gap = iosVersion.length - localVersion.length;
                while (gap) {
                    localVersion = [localVersion stringByAppendingString:@"0"];
                    gap--;
                }
            }else{
                gap = localVersion.length - iosVersion.length;
                while (gap) {
                    iosVersion = [iosVersion stringByAppendingString:@"0"];
                    gap--;
                }
            }
        }
    
      int iosVersionNum = iosVersion.intValue;
      int localVersionNum = localVersion.intValue;
         
    
        //更新描述
        NSString *detail = _responseObject[@"iosUpdateMsg"];
        if (localVersionNum < iosVersionNum)//如果本地版本比较低 证明要更新版本
        {
    
            upDateflag = YES;
    
            UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"更新" message:[NSString stringWithFormat:@"检测到有新版本:v%@ \n %@",iosVersion,detail] preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                // itms-apps://itunes.apple.com/cn/app/wang-yi-yun-yin-le-pao-bufm/id590338362?mt=8
                NSURL *url = [NSURL URLWithString:iosDownload];
                [[UIApplication sharedApplication] openURL:url];
                upDateflag = NO;
                
            }];
            UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
                upDateflag = NO;
            }];
            [alertVC addAction:action1];
            [alertVC addAction:action2];
            [self presentViewController:alertVC animated:YES completion:nil];
            
        }
    
    }
    
    //如果是使用AFNetworking 请求的话,需要设置一下返回格式为JSON格式
       AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.requestSerializer = [AFJSONRequestSerializer serializer];
    

    根据@ylyer的反馈,测试了一下 , "http://itunes.apple.com/lookup?id=我的appid&country=cn "这个样子也是可以成功的

    相关文章

      网友评论

      • 搬砖技术:localVersion = [[localVersion componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]] componentsJoinedByString:@""];
        int iosVersionNum = iosVersion.intValue;
        int localVersionNum = localVersion.intValue;

        //更新描述
        NSString *detail = _responseObject[@"iosUpdateMsg"];
        if (localVersionNum < iosVersionNum)//如果本地版本比较低 证明要更新版本
        这个判断是不对的,比如2.3.10与2.4.1,明显2.4.1是更后版本,然而241小于2310
        0a4069affb24:iOS 11 一审核通过就改状态,可是跳到AppStore app 的状态是打开而不是更新,请问这是怎么回事?
        清河湾:如果还有其他的解决办法,请告知.哈哈哈哈,谢谢指出错误.
        清河湾:这个位数不同的是没法比较的, 比如 2.3.10与2.4.1 和 2.3.9 与 2.3.10 , 这个时候 2.3.10 应该是变成2.4.0 才对的,如果是后续需要 多位的那应该也是 2.0004.00000 ,补足位数有可比性.
      • tkbj:请问 APP 第一次上架之前 APP 的 ID 是不知道 如何使用第二种方法进行升级啊?
        李某lkb:你创建了应用就会有appid的.不需要等上架.
        清河湾:这个url 配置成动态的,从后台获取就好了啊,然后审核通过后 ,后台修改一下就行
      • SHMI:有没有demo啊.
      • 草书行者:我这边碰到一个更新了以后回来他的[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]值没更新到最新导致他不断地提示要更新,不知道你们这边有没有碰到
        清河湾:这个问题可能是你在进入程序的时候没有吧设置版本信息的方法 在提示更新的方法之后加载?
        我是没有遇到
        05519861f626:你这个问题解决没?
      • 吕小布_1d11:楼主我是用的是获取服务器的版本信息,然后包括强制更新和更新, 这样做真的不回被拒吗?
        清河湾:@dqk1023 你是不是注册错通知了? UIApplicationDidBecomeActiveNotification 通知 取消 alert提示框也是会触发的,不存在你说的情况啊:flushed:
        dqk1023:[[UIApplication sharedApplication] openURL 加上这个弹出系统自带的提示框,点击取消,不照样安装不了新版的
        清河湾:@吕小布_1d11 不会的,除非你在审核期间改后台变成强制更新,那铁定被拒
      • FM_7b92:[[UIApplication sharedApplication] openURL 加上这个弹出系统自带的提示框,点击取消,不照样安装不了新版的
        清河湾:什么?你说的是强制更新还是非强制更新的啊,强制更新就没有取消按钮啊
      • 4VZhang:localVersion < iosVersionDouble ,使用double值的方法比较2.9和2.10 是否能够达到预期的效果
        清河湾:之前的有BUG ,现在已经修复.能达到预期效果
      • 一口吃成死胖子:“本次版本更新为强制更新,下个版本更新可能为选择更新”,这属于需要“自定义更新模式”的类型吗?如果只走方法二,向AppStore请求数据,是不是每次都只能“选择更新”?
        清河湾:我只是提供查询版本的方法和接口,其他的自己都可以自定义的啊,你打开应用的时候去App Storest 查版本号,返回回来的数据你自己想再去自己的服务器判断一下或者自定义一下操作都是可以的,想怎么样就怎么样,看需求
      • 清河湾:@YwWyW 在APPdelegate里面调不起 alert提示框,所以才用通知
        清河湾:@_moses 可以,这很机智😎
        _moses:用self.window.rootViewController别用self不就行了吗:flushed:
      • YwWyW:applicationDidBecomeActive直接在APPdelegate里写不就好了嘛
        _moses:@稳稳2333 我一直在appdelegate里面alert啊。。。
      • dong_liang:为什么审核时间不可控?还有这样提示会被拒吗
        dong_liang:@漂泊不定 好吧,这么说时间都不可控啊,我以为第一种有被拒的可能,正在考虑用哪种方法做...
        清河湾:@dong_liang 这样的提示不会被拒绝啊,我测试过有效
        清河湾:@dong_liang 因为审核不是你在控制的,是苹果那边审核而定的啊
      • 搜捕儿:这样不会被拒吗
        清河湾:@搜捕儿 亲测不会
      • ylyer:我用 http://itunes.apple.com/cn/lookup?id=我的appid ,用AFNetworking去请求,并不会成功,把url复制到浏览器就自动下载了一个文件,文件内确实有app的各项数据,请问这是什么情况?
        后来我用 http://itunes.apple.com/lookup?id=我的appid&country=cn 就可以请求成功了 :blush:
        清河湾:@ylyer 不成功应该是你格式没设置好,你设置一下返回格式为json格式试试看
      • c1ca6820ba49:有个问题不明白,ios的应用不是只能去app store更新,如何可以自定义更新?还有强制更新呢? :smile:
        清河湾:@Ashen 这个我是直接把更新数据写入本地保存起来的,每次打开联网的时候写入最新状态,然后判断的时候去读取本地数据
        Ashen:@清河湾 如果强制更新需要联网才能弹出强制框,那要是断网进入app,避免了弹框,在打开app怎么处理
        清河湾:@SummyX2 这个肯定是要去AppStore 更新的,这里只是说一个提示功能,强制更新主要是用于有重大BUG的时候,导致应用有问题的时候,就强制提示,不去Appstore更新就无法操作应用的行为

      本文标题:iOS 版本更新(强制更新)检测问题

      本文链接:https://www.haomeiwen.com/subject/fonejttx.html