React-Native做本地服务器热更新/热部署(IOS)

前言

        某个公司考虑使用React-Native的理由有很多,热更新/热部署可能是一个很大的原因。如果公司认为热更新/热部署是主要原因的话,那么这应该是一个很错误的决定。因为APP的质量和具有前瞻性的规划才是您真正需要考虑的事情,而不是热更新的补救。当然不可否认的是热更新/热部署很符合敏捷开发这个思维.......

进入正题

        现在热更新的第三方服务很多:微软的CodePushRN中文网的Pushy......国内还是推荐使用国内的服务吧。

        既然有这么多第三方服务为何还要自己开发热更新/热部署功能呢?

        1、安全性

        2、可控性

        3、实现简单的业务逻辑开发起来其实很简单

        4、之前使用的微软CodePush的服务下载时出现很多问题,于是决定自己开发。

开发思路


开发思路

开发步骤

1、编译项目

ios打包编译:CD到项目根目录运行命令

react-native bundle --entry-file index.ios.js --platform ios --dev false --bundle-output ./ios/bundle/index.ios.jsbundle --assets-dest ./ios/bundle

安卓打包请移步到打包APK

ios打包完成后在项目中的ios目录中多出了bundle文件夹,这里就是我们打包出来的RN运行文件,实际上RN运行的就是这里的.jsbundle文件。


编译项目目录

2、压缩编译文件

把bundle文件夹压缩为ZIP包

3、把压缩的bundle的ZIP包上传到后端

4、更新后台相关的配置文件,比如:RN包的版本号、更新日志、是否强制更新、是否静默更新、是否回滚......具体有多少功能是你们的自己的事


5、下载最新的包,这里开始是写代码的时候了

5.1首先网络请求服务的RN配置内容

5.2对比本地RN的版本号

5.3弹出更新

5.4下载解压最新的包

下载和解压文件的代码:下载使用的是AFN、解压使用的是SSZipArchive

AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];

    //下载地址

    NSURL*mgrurl = [NSURLURLWithString:self.updateUrl];

    NSURLRequest*request = [NSURLRequestrequestWithURL:mgrurl];

    NSURLSessionDownloadTask*download = [mgrdownloadTaskWithRequest:requestprogress:^(NSProgress*_NonnulldownloadProgress) {

      //在主线程中调用

      [[NSOperationQueue mainQueue]addOperationWithBlock:^{

        NSLog(@"进度%f",1.0*downloadProgress.completedUnitCount/ downloadProgress.totalUnitCount);

        CGFloatjsw =1.0* downloadProgress.completedUnitCount/ downloadProgress.totalUnitCount* (PW-40);

        self.jdView.frame=CGRectMake(0,0, jsw,5);

        self.jdText.text= [NSStringstringWithFormat:@"更新进度(%.0f/100)",100.0*downloadProgress.completedUnitCount/ downloadProgress.totalUnitCount];

        self.suduText.text= [NSStringstringWithFormat:@"%lldkb/s",[MLRNSingtongetInterfaceBytes]/1024/1024];

      }];

    }destination:^NSURL*_Nonnull(NSURL*_NonnulltargetPath,NSURLResponse*_Nonnullresponse) {

      NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];

      NSLog(@"targetPath:%@",targetPath);

      NSLog(@"fullPath:%@",fullPath);

      return[NSURLfileURLWithPath:fullPath];

    }completionHandler:^(NSURLResponse*_Nonnullresponse,NSURL*_NullablefilePath,NSError*_Nullableerror) {

      //下载完成,解压

      //Caches路径

      NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];

      NSString *xxxx = [[filePath absoluteString] substringFromIndex:7];

      [SSZipArchive unzipFileAtPath: xxxx toDestination:cachesPath];

      [[NSOperationQueue mainQueue]addOperationWithBlock:^{

        [MBProgressHUD hideHUD];

        UIStoryboard*storayobard = [UIStoryboardstoryboardWithName:@"main"bundle:nil];

        self.view.window.rootViewController = storayobard.instantiateInitialViewController;

      }];

    }];

    [downloadresume];

下载和解压和重启app

5.5运行本地的RN文件

在使用调用RN的地方(一般在AppDelegate中)

修改RCTRootView初始化方法为

RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:[[RCTBridge alloc] initWithDelegate:self launchOptions:nil] moduleName:@""name"" initialProperties:nil];


修改RCTRootView初始化方法

添加代理RCTBridgeDelegate


添加代理

实现RCTBridgeDelegate中的sourceURLForBridge方法

- (NSURL*)sourceURLForBridge:(RCTBridge*)bridge {

  <#code#>

}

sourceURLForBridge方法

在sourceURLForBridge方法中确定您是要使用最新那个URL中的包

我这里的逻辑是

判断沙盒是否存在.jsbundle文件 --->  有则使用沙盒中的.jsbundle

                                                            没有则使用本地打包的文件

- (NSURL*)sourceURLForBridge:(RCTBridge*)bridge{

  NSURL*jsCodeLocation;

  // 取得沙盒目录

  NSString *localPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

  // 要检查的文件目录

  NSString*filePath = [localPath  stringByAppendingPathComponent:@"bundle/index.ios.jsbundle"];

  NSFileManager *fileManager = [NSFileManager defaultManager];

  if([fileManagerfileExistsAtPath:filePath]) {

    NSString*newUrl = [NSStringstringWithFormat:@"file://%@",filePath];

    jsCodeLocation = [NSURLURLWithString:newUrl];

    NSLog(@"文件存在");

    returnjsCodeLocation;

  }else{

#if DEBUG

    // 原来的jsCodeLocation

    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

#else

    jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"bundle/index.ios"withExtension:@"jsbundle"];

#endif

    NSLog(@"文件不存在");

    returnjsCodeLocation;

  }

}


判断代码

大功告成运行项目。

到这里最基础的热更新/热部署服务就搭建完成。如果想要更加完善还是需要花点功夫的,毕竟师傅领进门修行靠个人。

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

推荐阅读更多精彩内容