iOS不添加任何信息检测App更新

DarEames 7年前
   <h3><strong>一.前言:</strong></h3>    <ul>     <li> <p>1.iOS开发中,有时会有这种需求,在AppStore上出现新版本时,应用内弹窗提示用户更新.</p> </li>     <li> <p>2.之前在网上看到一种方法通过AppId查询更新的,但是有时候APP没上线或开发账号还没注册下来时我们并不知道AppId,此时就要把这个功能做上去,该怎么办呢?</p> </li>     <li> <p>3.现介绍一种简便的方法给大家,不需要提供AppId等任何信息,即可实现查询AppStore中是否有新版本,并提示更新.</p> </li>     <li> <p>4.代码地址:见篇尾.</p> </li>    </ul>    <h3><strong>二.效果:</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a7e05c1a7be0e41cf8ad691e16e29314.png"></p>    <h3><strong>三.实现逻辑:</strong></h3>    <ul>     <li> <p>1.先查询AppStore中该App的信息(包含版本,更新日志等)</p> </li>     <li> <p>2.和App当前版本进行比较,比当前版本新,弹窗并显示更新日志,提示用户跳转到AppStore更新</p> </li>     <li> <p>3.为了方便在以后开发中调用,笔者实现时进行简单封装.</p> </li>    </ul>    <h3><strong>四.直接上代码:</strong></h3>    <p>-4.1获取AppStore中该App的版本信息</p>    <ul>     <li> <p>1.为了不依赖其他数据请求库,笔者采用系统方法做数据请求,当然你们也可以使用AFN等框架请求数据.</p> </li>     <li> <p>2.新建一个请求版本信息的类继承NSObject笔者取名 XHVersionRequest</p> </li>     <li> <p>3.在XHVersionRequest.h文件中添加请求成功和失败回调和数据请求方法,代码如下:</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import typedef void(^RequestSucess) (NSDictionary * responseDict);  typedef void(^RequestFailure) (NSError *error);    @interface XHVersionRequest : NSObject    /**   *  从AppStore中获取App信息   *   *  @param success 成功回调   *  @param failure 失败回调   */  +(void)xh_versionRequestSuccess:(RequestSucess)success failure:(RequestFailure)failure;    @end</code></pre>    <ul>     <li> <p>4.在XHVersionRequest.m文件中实现</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import "XHVersionRequest.h"    @implementation XHVersionRequest  +(void)xh_versionRequestSuccess:(RequestSucess)success failure:(RequestFailure)failure{        NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];      NSString *bundleId = infoDict[@"CFBundleIdentifier"];      NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/lookup?bundleId=%@",bundleId]];      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{            NSURLRequest *request = [NSURLRequest requestWithURL:URL];          NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {                dispatch_async(dispatch_get_main_queue(), ^{                    if(!error)                  {                      NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];                      if(success) success(responseDict);                  }                  else                  {                      if(failure) failure(error);                  }                });            }];            [dataTask resume];        });    }  @end</code></pre>    <p>-4.2解析请求回来App信息数据</p>    <ul>     <li> <p>1.新建一个App信息模型继承NSObject,笔者取名XHAppInfo,为减少依赖,笔者暂不采用JSON -> Model 框架解析数据.</p> </li>     <li> <p>2.在XHAppInfo.h和XHAppInfo.m中分别添加以下代码:</p> </li>     <li> <p>XHAppInfo.h文件</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import #import @interface XHAppInfo : NSObject    /**   *  版本号   */  @property(nonatomic,copy) NSString * version;    /**   *  更新日志   */  @property(nonatomic,copy)NSString *releaseNotes;    /**   *  更新时间   */  @property(nonatomic,copy)NSString *currentVersionReleaseDate;    /**   *  APPId   */  @property(nonatomic,copy)NSString *trackId;    /**   *  bundleId   */  @property(nonatomic,copy)NSString *bundleId;    /**   *  AppStore地址   */  @property(nonatomic,copy)NSString *trackViewUrl;    - (instancetype)initWithResult:(NSDictionary *)result;    @end</code></pre>    <ul>     <li> <p>XHAppInfo.m文件</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import "XHAppInfo.h"    @implementation XHAppInfo    - (instancetype)initWithResult:(NSDictionary *)result{        self = [super init];      if (self) {            self.version = result[@"version"];          self.releaseNotes = result[@"releaseNotes"];          self.currentVersionReleaseDate = result[@"currentVersionReleaseDate"];          self.trackId = result[@"trackId"];          self.bundleId = result[@"bundleId"];          self.trackViewUrl = result[@"trackViewUrl"];          self.appDescription = result[@"appDescription"];          self.sellerName = result[@"sellerName"];          self.fileSizeBytes = result[@"fileSizeBytes"];          self.screenshotUrls = result[@"screenshotUrls"];      }      return self;  }  @end</code></pre>    <p>-4.3比较与当前版本大小关系,提示更新</p>    <ul>     <li> <p>1.笔者新建一个类XHVersion(继承NSObject)来处理版本比较和弹窗</p> </li>     <li> <p>2.为了调用更灵活,我们在XHVersion.h文件中添加如下两个方法:1.一个是使用默认弹窗,2.一个是回调新版本信息,开发者自定义弹窗</p> </li>     <li> <p>XHVersion.h文件</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import #import "XHAppInfo.h"typedef void(^NewVersionBlock)(XHAppInfo *appInfo);@interface XHVersion : NSObject/**   *  检测新版本(使用默认提示框)   */+(void)checkNewVersion;/**   *  检测新版本(自定义提示框)   *   *  @param newVersion 新版本信息回调   */+(void)checkNewVersionAndCustomAlert:(NewVersionBlock)newVersion;@end</code></pre>    <ul>     <li> <p>XHVersion.m文件中进行实现,代码如下</p> </li>    </ul>    <pre>  <code class="language-objectivec">#import "XHVersion.h"  #import "XHVersionRequest.h"    @interface XHVersion()@property(nonatomic,strong)XHAppInfo *appInfo;    @end    @implementation XHVersion    +(void)checkNewVersion{        [[XHVersion shardManger] checkNewVersion];  }  +(void)checkNewVersionAndCustomAlert:(NewVersionBlock)newVersion{        [[XHVersion shardManger] checkNewVersionAndCustomAlert:newVersion];  }    #pragma mark - private    +(XHVersion *)shardManger{        static XHVersion *instance = nil;      static dispatch_once_t oneToken;      dispatch_once(&oneToken,^{            instance = [[XHVersion alloc] init];        });      return instance;  }  -(void)checkNewVersion{        [self versionRequest:^(XHAppInfo *appInfo) {            NSString *updateMsg = [NSString stringWithFormat:@"%@",appInfo.releaseNotes];  #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0          UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"发现新版本" message:updateMsg delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:@"更新", nil];          [alertView show];  #endif    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0          UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"发现新版本" message:updateMsg preferredStyle:UIAlertControllerStyleAlert];          [alert addAction:[UIAlertAction actionWithTitle:@"关闭" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {            }]];          [alert addAction:[UIAlertAction actionWithTitle:@"更新" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {                [self openInAppStoreForAppURL:self.appInfo.trackViewUrl];            }]];            [[self window].rootViewController presentViewController:alert animated:YES completion:nil];  #endif        }];    }  -(UIWindow *)window{        UIWindow *window = nil;      id delegate = [[UIApplication sharedApplication] delegate];      if ([delegate respondsToSelector:@selector(window)]) {          window = [delegate performSelector:@selector(window)];      } else {          window = [[UIApplication sharedApplication] keyWindow];      }      return window;  }  -(void)checkNewVersionAndCustomAlert:(NewVersionBlock)newVersion{        [self versionRequest:^(XHAppInfo *appInfo) {            if(newVersion) newVersion(appInfo);        }];  }  -(void)versionRequest:(NewVersionBlock)newVersion{        [XHVersionRequest xh_versionRequestSuccess:^(NSDictionary *responseDict) {            NSInteger resultCount = [responseDict[@"resultCount"] integerValue];          if(resultCount==1)          {              NSArray *resultArray = responseDict[@"results"];              NSDictionary *result = resultArray.firstObject;              XHAppInfo *appInfo = [[XHAppInfo alloc] initWithResult:result];              NSString *version = appInfo.version;              self.appInfo = appInfo;              if([self isNewVersion:version])//新版本              {                  if(newVersion) newVersion(self.appInfo);              }          }        } failure:^(NSError *error) {        }];    }    #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0  -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{        if(buttonIndex==1)      {          [self openInAppStoreForAppURL:self.appInfo.trackViewUrl];      }  }  #endif    -(void)openInAppStoreForAppURL:(NSString *)appURL{        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:appURL]];  }    - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {        [viewController dismissViewControllerAnimated:YES completion:nil];  }    //是否是新版本  -(BOOL)isNewVersion:(NSString *)newVersion{        return [self newVersion:newVersion moreThanCurrentVersion:[self currentVersion]];  }  -(NSString * )currentVersion{        NSString *key = @"CFBundleShortVersionString";      NSString * currentVersion = [NSBundle mainBundle].infoDictionary[key];      return currentVersion;  }  -(BOOL)newVersion:(NSString *)newVersion moreThanCurrentVersion:(NSString *)currentVersion{        if([currentVersion compare:newVersion options:NSNumericSearch]==NSOrderedAscending)      {          return YES;      }      return NO;  }</code></pre>    <h3><strong>五.调用:</strong></h3>    <ul>     <li> <p>导入头文件 #import "XHVersion.h" ,在需要检测新版本的地方调用下面代码</p> </li>    </ul>    <pre>  <code class="language-objectivec">//1.新版本检测(使用默认提示框)  [XHVersion checkNewVersion];    //2.如果你需要自定义提示框,请使用下面方法  [XHVersion checkNewVersionAndCustomAlert:^(XHAppInfo *appInfo) {          //appInfo为新版本在AppStore相关信息        //请在此处自定义您的提示框        //......  }];</code></pre>    <h3><strong>六.小结:</strong></h3>    <ul>     <li> <p>细看代码的同学可能会发现,笔者并没有通过AppId去拉取该App的版本信息,而是通过bundleId去查询的.</p> </li>    </ul>    <p> </p>    <p> </p>