React-Native開發(fā)iOS篇-熱更新的實(shí)現(xiàn)

需求

1.在打開APP的時(shí)候進(jìn)行網(wǎng)絡(luò)請求盯滚,檢查是否有網(wǎng)絡(luò)更新筋帖。

2.如果有網(wǎng)絡(luò)更新迅耘,下載新的版本贱枣,再次打開APP的時(shí)候,就直接連接到新的內(nèi)容颤专。

具體功能的實(shí)現(xiàn):

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

  UpdataLoader* upLoatder = [UpdataLoader shareUpLoader];
  //保證存放路徑是存在的
  [upLoatder createPath];
  //檢查更新并下載纽哥,有更新則直接下載,無則保持默認(rèn)配置
  [upLoatder getAppVersion];
  //定義加載bundle的URL
  NSURL *jsCodeLocation;
  
  NSString* iOSBundlePath = [[upLoatder iOSFileBundlePath] stringByAppendingPathComponent:@"index.ios.bundle"];
  if ([[NSFileManager defaultManager] fileExistsAtPath:iOSBundlePath]) {
   jsCodeLocation = [NSURL URLWithString:iOSBundlePath];
  }else{
    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
  }
  
//  NSLog(@"jsCodeLocation%@",jsCodeLocation);
  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"******"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
  [DownLoadTool defaultDownLoadTool].view = rootView;
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

上述代碼是在Appdelegate中的實(shí)現(xiàn)栖秕,關(guān)鍵點(diǎn)有兩個(gè):
1.實(shí)現(xiàn)對版本號的數(shù)據(jù)持久化存儲春塌。
2.如何加載沙盒路徑下的js.bundle文件。


實(shí)現(xiàn)數(shù)據(jù)持久化的方法

在三種數(shù)據(jù)持久化得方式中簇捍,我選擇了plist文件去存儲版本號和下載路徑只壳。

//獲取版本信息儲存的文件路徑
-(NSString*)getVersionPlistPath{
  
  //獲取沙盒路徑
  NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString* path = [paths objectAtIndex:0];
  NSLog(@"the save version file's path is :%@",path);
  //填寫文件名
  NSString* filePath = [path stringByAppendingPathComponent:kVersionPlist];
  //  NSLog(@"文件路徑為:%@",filePath);
  return filePath;
}

//創(chuàng)建或修改版本信息
-(void)writeAppVersionInfoWithDictiony:(NSDictionary*)dictionary{
  NSString* filePath  = [self getVersionPlistPath];
  [dictionary writeToFile:filePath atomically:YES];
}

分為兩步,第一步確定存儲路徑暑塑,第二步將要存儲的信息調(diào)用

 [dictionary writeToFile:filePath atomically:YES];

的方法去寫入本地路徑吼句。


實(shí)現(xiàn)從本地文件夾中獲取bundle并加載

在這里,有以下幾個(gè)問題需要去解決:

  • 如何下載事格?
  • 下載完畢后如何解壓惕艳?
  • 解壓完成后如何配置文件搞隐?

首先解決如何下載的問題,在這里我選擇了第三方AFNetworking 3.0來實(shí)現(xiàn)對文件的下載远搪。

-(void)downLoadWithUrl:(NSString*)url{
  [self showPromptWithStr:@"發(fā)現(xiàn)新的版本劣纲,開始下載..."];
  //根據(jù)url下載相關(guān)文件
  NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
  AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
  NSURL *URL = [NSURL URLWithString:url];
  NSURLRequest *request = [NSURLRequest requestWithURL:URL];
  NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
      //獲取下載進(jìn)度
//      NSLog(@"Progress is %f", downloadProgress.fractionCompleted);
  } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    //有返回值的block,返回文件存儲路徑
    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    NSURL* targetPathUrl = [documentsDirectoryURL URLByAppendingPathComponent:kiOSFileName];
    return [targetPathUrl URLByAppendingPathComponent:[response suggestedFilename]];

  } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    if(error){
      //下載出現(xiàn)錯誤
      NSLog(@"%@",error);
      
    }else{
      [self showPromptWithStr:@"更新完畢谁鳍。請重新啟動******癞季!"];
      //下載成功
      NSLog(@"File downloaded to: %@", filePath);
      self.zipPath = [[filePath absoluteString] substringFromIndex:7];
      //下載成功后更新本地存儲信息
      [[UpdataLoader shareUpLoader] writeAppVersionInfoWithDictiony:[UpdataLoader shareUpLoader].versionInfo];
      //解壓并刪除壓縮包
      if ([self unZip]) {
        [self deleteZip];
      };

    }
  }];
  [downloadTask resume];
}

在這里需要注意的是每個(gè)下載的設(shè)置默認(rèn)是被掛起的,所以在設(shè)置完畢之后倘潜,需要調(diào)用

  [downloadTask resume];

使得下載主動進(jìn)行绷柒。

在下載完畢之后的block回調(diào)中,是在主線程中進(jìn)行的窍荧,在這里就可以進(jìn)行一些UI的更新辉巡。

注意在完成之后返回的文件路徑filePath為:
file:///*********
直接進(jìn)行使用發(fā)現(xiàn),獲取不到文件蕊退。
必須將file:///去掉才能解決問題郊楣。
利用nsstring提供的方法來實(shí)現(xiàn)。

self.zipPath = [[filePath absoluteString] substringFromIndex:7];

OK解決的下載問題瓤荔,現(xiàn)在來解決解壓問題净蚤,解壓方式我選擇了第三方提供的SSZipArchive.
代碼如下:


//解壓壓縮包
-(BOOL)unZip{
  if (self.zipPath == nil) {
    return NO;
  }
  //檢查Document里有沒有bundle文件夾
  NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  NSString* bundlePath = [path stringByAppendingPathComponent:kiOSfileSetName];
  BOOL isDir;
  //如果有,則刪除后解壓输硝,如果沒有則直接解壓
  if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:&isDir]&&isDir) {
    [[NSFileManager defaultManager] removeItemAtPath:bundlePath error:nil];
  }
  NSString *zipPath = self.zipPath;
  NSString *destinationPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  BOOL success = [SSZipArchive unzipFileAtPath:zipPath
                                 toDestination:destinationPath];
  return success;
}

//刪除壓縮包
-(void)deleteZip{
  NSError* error = nil;
  [[NSFileManager defaultManager] removeItemAtPath:self.zipPath error:&error];
}

最后今瀑,來解決一下如何配置的問題:
在各種文檔里都沒有找到說明如何加載一個(gè)現(xiàn)有的js.bundle文件。
經(jīng)過我個(gè)人的幾番嘗試点把,我找到了如下方法:

 NSURL *jsCodeLocation;
jsCodeLocation = [NSURL URLWithString:iOSBundlePath];

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Dingla"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];

iOSBUndlepath為沙盒內(nèi)的文件路徑橘荠。

至此,iOS的熱更新就實(shí)現(xiàn)了郎逃。

git倉庫點(diǎn)我

2017.09.14 PS:
因?yàn)槲恼聦懙谋容^早哥童,源碼我已經(jīng)刪除了。
感謝這位同學(xué)將代碼補(bǔ)全褒翰。
附上地址點(diǎn)我

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贮懈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子优训,更是在濱河造成了極大的恐慌朵你,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揣非,死亡現(xiàn)場離奇詭異抡医,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)早敬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門魂拦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來毛仪,“玉大人搁嗓,你說我怎么就攤上這事芯勘。” “怎么了腺逛?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵荷愕,是天一觀的道長。 經(jīng)常有香客問我棍矛,道長安疗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任够委,我火速辦了婚禮荐类,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茁帽。我一直安慰自己玉罐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布潘拨。 她就那樣靜靜地躺著吊输,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铁追。 梳的紋絲不亂的頭發(fā)上季蚂,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音琅束,去河邊找鬼扭屁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涩禀,可吹牛的內(nèi)容都是我干的料滥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼埋泵,長吁一口氣:“原來是場噩夢啊……” “哼幔欧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起丽声,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤礁蔗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后雁社,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浴井,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年霉撵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了磺浙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洪囤。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撕氧,靈堂內(nèi)的尸體忽然破棺而出瘤缩,到底是詐尸還是另有隱情,我是刑警寧澤伦泥,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布剥啤,位于F島的核電站,受9級特大地震影響不脯,放射性物質(zhì)發(fā)生泄漏府怯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一防楷、第九天 我趴在偏房一處隱蔽的房頂上張望牺丙。 院中可真熱鬧,春花似錦复局、人聲如沸冲簿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽民假。三九已至,卻和暖如春龙优,著一層夾襖步出監(jiān)牢的瞬間羊异,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工彤断, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留野舶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓宰衙,卻偏偏與公主長得像平道,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子供炼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容