ios app 实现热更新(无需发新版本实现app添加新功能)

转载 2015年11月18日 15:48:07

m

目前能够实现热更新的方法,总结起来有以下三种

1. 使用FaceBook 的开源框架 reactive native,使用js写原生的ios应用

ios app可以在运行时从服务器拉取最新的js文件到本地,然后执行,因为js是一门动态的

脚本语言,所以可以在运行时直接读取js文件执行,也因此能够实现ios的热更新


2. 使用lua 脚本。lua脚本如同js 一样,也能在动态时被。之前愤怒的小鸟使用

lua脚本做的一个插件 wax,可以实现使用lua写ios应用。热更新时,从服务器拉去lua脚本

然后动态的执行就可以了。遗憾的是 wax目前已经不更新了。


上面是网上现在能够搜到的热更新方法。

xcode 6 之后,苹果开放了 ios 的动态库编译权限。所谓的动态库,其实就是可以在运行时加载。

正好利用这一个特性,用来做ios的热更新。

1.

建立一个动态库,如图:


动态库包含需要使用的viewCOntroller,当然可以包含任何需要使用的自定义ui和逻辑。

动态库的入口是一个jkDylib的类。它的.h和.m文件分别如下:

  1. //  
  2. //  JKDylib.h  
  3. //  JKDylb  
  4. //  
  5. //  Created by wangdan on 15/7/5.  
  6. //  Copyright (c) 2015年 wangdan. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. @interface JKDylib : NSObject  
  12.   
  13. -(void)showViewAfterVC:(id)fromVc inBundle:(NSBundle*)bundle;  
  14.   
  15. @end  

.m文件
  1. //  
  2. //  JKDylib.m  
  3. //  JKDylb  
  4. //  
  5. //  Created by wangdan on 15/7/5.  
  6. //  Copyright (c) 2015年 wangdan. All rights reserved.  
  7. //  
  8.   
  9. #import "JKDylib.h"  
  10. #import "JKViewController.h"  
  11.   
  12. @implementation JKDylib  
  13.   
  14. -(void)showViewAfterVC:(id)fromVc inBundle:(NSBundle*)bundle  
  15. {  
  16.     if (fromVc == nil ) {  
  17.         return;  
  18.     }  
  19.       
  20.     JKViewController *vc = [[JKViewController alloc] init];  
  21.     UIViewController *preVc = (UIViewController *)fromVc;  
  22.       
  23.     if (preVc.navigationController) {  
  24.         [preVc.navigationController pushViewController:vc animated:YES];  
  25.     }  
  26.     else {  
  27.         UINavigationController *navi = [[UINavigationController alloc] init];  
  28.         [navi pushViewController:vc animated:YES];  
  29.     }  
  30.       
  31. }  
  32. @end  

上述代码意图非常明显,

就是调用该动态库的时候

  1. -(void)showViewAfterVC:(id)fromVc inBundle:(NSBundle*)bundle  
在该函数中,创建一个viewController 然后使用mainBundler 的navigationController  push 新建的viewController,显示动态库的ui界面。

而动态库中的JKViewController 内容则可以根据需要随便定义。


2. 完成上述动态库的编译工作后,现在需要做的就是在主工程中,写一段加载该动态库的代码。

主工程目录如下:


在最重要的viewCotrooler里面,定义了加载动态库的方法:

  1. //  
  2. //  ViewController.m  
  3. //  DylibTest  
  4. //  
  5. //  Created by wangdan on 15/7/5.  
  6. //  Copyright (c) 2015年 wangdan. All rights reserved.  
  7. //  
  8.   
  9. #import "ViewController.h"  
  10. #import "AFNetWorking.h"  
  11.   
  12. @interface ViewController ()  
  13.   
  14. @end  
  15.   
  16. @implementation ViewController  
  17.   
  18. - (void)viewDidLoad {  
  19.     [super viewDidLoad];  
  20.     self.view.backgroundColor = [UIColor whiteColor];  
  21.     self.title = @"bundle test";  
  22.       
  23.     AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];  
  24.     manager.responseSerializer = [AFJSONResponseSerializer serializer];  
  25.     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];  
  26.     [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  27.         NSLog(@"request success");  
  28.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  29.         NSLog(@"request failure");  
  30.     }];  
  31.       
  32.       
  33.       
  34.     UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(010010050)];  
  35.     btn.backgroundColor = [UIColor blueColor];  
  36.       
  37.     [btn addTarget:self  
  38.             action:@selector(btnHandler)  
  39.   forControlEvents:UIControlEventTouchUpInside];  
  40.       
  41.     [self.view addSubview:btn];  
  42.       
  43.     NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
  44.       
  45.     BOOL writeResult =  
  46.     [@"hellow" writeToFile:[NSString stringWithFormat:@"%@/%@",document,@"hello.plist"] atomically:YES encoding:NSUTF8StringEncoding error:nil];  
  47.       
  48.     // Do any additional setup after loading the view, typically from a nib.  
  49. }  
  50.   
  51.   
  52. -(void)btnHandler  
  53. {  
  54.       
  55.     //AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];  
  56.     //manager.responseSerializer = [AFJSONResponseSerializer serializer];  
  57.    // NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];  
  58.    // [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  59.     //    NSLog(@"request success");  
  60.    // } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  61.       // NSLog(@"request failure");  
  62.     //}];  
  63.       
  64.     NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
  65.     NSString *bundlePath = [NSString stringWithFormat:@"%@/%@",documentDirectory,@"JKDylb.framework"];  
  66.       
  67.     if (![[NSFileManager defaultManager] fileExistsAtPath:bundlePath]) {  
  68.         NSLog(@"file not exist ,now  return");  
  69.         return;  
  70.     }  
  71.     NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];  
  72.       
  73.     if (!bundle || ![bundle load]) {  
  74.         NSLog(@"bundle load error");  
  75.     }  
  76.       
  77.     Class loadClass = [bundle principalClass];  
  78.     if (!loadClass) {  
  79.         NSLog(@"get bundle class fail");  
  80.         return;  
  81.     }  
  82.     NSObject *bundleObj = [loadClass new];  
  83.     [bundleObj performSelector:@selector(showViewAfterVC:inBundle:) withObject:self withObject:bundle];  
  84.       
  85.     NSString *framePath = [[NSBundle mainBundle] privateFrameworksPath];  
  86.     NSLog(@"framePath is %@",framePath);  
  87.       
  88.     NSLog(@"file attri \n %@",bundle.localizations);  
  89.       
  90. //    [bundleObj showViewAfterVC:self inBundle:bundle];  
  91. }  
  92.   
  93. - (void)didReceiveMemoryWarning {  
  94.     [super didReceiveMemoryWarning];  
  95.     // Dispose of any resources that can be recreated.  
  96. }  
  97.   
  98. @end  

viewController视图中有一个按钮,点击按钮后,从 document目录下面找到动态库(虽然此时document下并没有动态库),动态库的名称约定好味

JKDylib.framework

然后使用NSBundle 加载该动态库,具体见代码。

加载成功后,调用在动态库中实现的方法

  1. [bundleObj performSelector:@selector(showViewAfterVC:inBundle:) withObject:self withObject:bundle];  
  2.      
编译该工程,然后运行到手机上,然后退出该程序


3. 打开itunes 然后将动态库同步到刚才的测试工程目录下。


4.在此打开测试工程程序,点击button,则会发现能够进入在动态库中定义的ui界面了。


上面工程的参考代码 在 

http://download.csdn.net/detail/j_akill/8891881


关于动态更新的思考:


采用动态库方式实现热更新其实还是有一个问题,就是如何在主工程和动态库之间共享组建

比如网络组件以及其他等等第三方组件。

目前我没发现好方法,只能在动态库和主工程之间分别添加并且编译。


APP热更新方案

APP热更新方案 为什么要做热更新 当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App、测试、向各个应用市场和渠道换包、提示用户升级...
  • weixin_37730482
  • weixin_37730482
  • 2017年06月15日 18:52
  • 2250

ios app 实现热更新(无需发新版本实现app添加新功能)

目前能够实现热更新的方法,总结起来有以下三种 1. 使用FaceBook 的开源框架 reactive native,使用js写原生的ios应用 ios app可以在运行时从服务器拉取最新的js文件到...
  • j_akill
  • j_akill
  • 2015年07月12日 12:17
  • 13905

Unity应用的iOS热更新

Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina   Agenda ? 什么是热更新 ? 为何要热更新 ? 如何在i...
  • yuxikuo_1
  • yuxikuo_1
  • 2016年06月30日 09:47
  • 907

app内部自动更新

12306的app可以绕过appstore直接更新?这个“更新”真的是更新吗? 答案很简单:12306是一个webapp 内部功能都是通过web来实现的 更新其实是在下载html 样式 js 等...
  • ios_xumin
  • ios_xumin
  • 2016年07月05日 11:09
  • 1290

移动端热更新方案(iOS+Android)

PPT资源包含iOS+Android 各种方案分析:https://github.com/qiyer/Share/blob/master/%E7%83%AD%E6%9B%B4%E6%96%B0%E5%...
  • jia12216
  • jia12216
  • 2017年03月08日 11:09
  • 573

【Ionic】Ionic实现iOS与Android端代码『热更新』与Android升级下载功能 ( v1.3.x版本 )

热更新的好处 通常ionic源码可包括(HTML,JavaScript,CSS文件和其他资源),往常我们必须通过提交程序到应用市场,经过漫长的审核后才可让用户更新,每改动一个小地方都需要重新打新版本...
  • hu764525403
  • hu764525403
  • 2016年11月08日 18:22
  • 6331

iOS 热更新方案

以下是iOS app热更新的几种方案,  由于苹果在2017年3月左右更新了开发者协议, 禁止需要线上审核的应用进行热更新, 所以请大家慎用 (企业版不需要提交审核当然是可以使用的) ...
  • chengkaizone
  • chengkaizone
  • 2017年03月20日 10:41
  • 3367

如何实现iOS热更新

最近被苹果审核整怕了,每次提交版本都得等待一周到两周的审核时间,我是受不了这种速度了,于是决定研究有没有其他的方法跳过提交版本这个步骤,同样能够修复bug呢,于是我找到了JSPatch,也许也有很多人...
  • touch929
  • touch929
  • 2017年06月06日 17:18
  • 2740

Unity IOS下的热更新研究

主要思路是替换掉在mono里image.c的
  • yy405145590
  • yy405145590
  • 2014年11月19日 15:45
  • 4884

android app热更新方案探讨(一)

app更新速度越来越快,功能也越来越多。辛辛苦苦的等待半夜凌晨的到来,然后上线app。刚上完线,duang!出bug了,瞬间心情跌到了谷底了。心情不好不是最要紧的,bug不好才要命。于是乎,辛辛苦苦的...
  • u012491617
  • u012491617
  • 2016年06月03日 13:37
  • 3237
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ios app 实现热更新(无需发新版本实现app添加新功能)
举报原因:
原因补充:

(最多只允许输入30个字)