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

简介: 目前能够实现热更新的方法,总结起来有以下三种 1. 使用FaceBook 的开源框架 reactive native,使用js写原生的ios应用 ios app可以在运行时从服务器拉取最新的js文件到本地,然后执行,因为js是一门动态的 脚本语言,所以可以在运行时直接读取js文件执行,也因此能够实现ios的热更新   2. 使用lua 脚本。lua脚本如同

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

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.

建立一个动态库,如图:

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

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

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

 

//
//  JKDylib.h
//  JKDylb
//
//  Created by wangdan on 15/7/5.
//  Copyright (c) 2015年 wangdan. All rights reserved.
//

#import 

@interface JKDylib : NSObject

-(void)showViewAfterVC:(id)fromVc inBundle:(NSBundle*)bundle;

@end

.m文件

 

 

//
//  JKDylib.m
//  JKDylb
//
//  Created by wangdan on 15/7/5.
//  Copyright (c) 2015年 wangdan. All rights reserved.
//

#import JKDylib.h
#import JKViewController.h

@implementation JKDylib

-(void)showViewAfterVC:(id)fromVc inBundle:(NSBundle*)bundle
{
    if (fromVc == nil ) {
        return;
    }
    
    JKViewController *vc = [[JKViewController alloc] init];
    UIViewController *preVc = (UIViewController *)fromVc;
    
    if (preVc.navigationController) {
        [preVc.navigationController pushViewController:vc animated:YES];
    }
    else {
        UINavigationController *navi = [[UINavigationController alloc] init];
        [navi pushViewController:vc animated:YES];
    }
    
}
@end

上述代码意图非常明显,

 

就是调用该动态库的时候

 

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

 

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

 

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

主工程目录如下:

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

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

 

//
//  ViewController.m
//  DylibTest
//
//  Created by wangdan on 15/7/5.
//  Copyright (c) 2015年 wangdan. All rights reserved.
//

#import ViewController.h
#import AFNetWorking.h

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @bundle test;
    
    AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@http://www.baidu.com]];
    [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@request success);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@request failure);
    }];
    
    
    
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, 100, 50)];
    btn.backgroundColor = [UIColor blueColor];
    
    [btn addTarget:self
            action:@selector(btnHandler)
  forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:btn];
    
    NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    BOOL writeResult =
    [@hellow writeToFile:[NSString stringWithFormat:@%@/%@,document,@hello.plist] atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    // Do any additional setup after loading the view, typically from a nib.
}


-(void)btnHandler
{
    
    //AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];
    //manager.responseSerializer = [AFJSONResponseSerializer serializer];
   // NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@http://www.baidu.com]];
   // [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
    //    NSLog(@request success);
   // } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      // NSLog(@request failure);
    //}];
    
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *bundlePath = [NSString stringWithFormat:@%@/%@,documentDirectory,@JKDylb.framework];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:bundlePath]) {
        NSLog(@file not exist ,now  return);
        return;
    }
    NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
    
    if (!bundle  ![bundle load]) {
        NSLog(@bundle load error);
    }
    
    Class loadClass = [bundle principalClass];
    if (!loadClass) {
        NSLog(@get bundle class fail);
        return;
    }
    NSObject *bundleObj = [loadClass new];
    [bundleObj performSelector:@selector(showViewAfterVC:inBundle:) withObject:self withObject:bundle];
    
    NSString *framePath = [[NSBundle mainBundle] privateFrameworksPath];
    NSLog(@framePath is %@,framePath);
    
    NSLog(@file attri 
 %@,bundle.localizations);
    
//    [bundleObj showViewAfterVC:self inBundle:bundle];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

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

 

JKDylib.framework

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

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

 

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

 

 

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

 

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

 

 

 

关于动态更新的思考:

 

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

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

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

目录
相关文章
|
4月前
|
Java 应用服务中间件 Windows
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
|
16天前
|
传感器 iOS开发 UED
探索iOS生态系统:从App Store优化到用户体验提升
本文旨在深入探讨iOS生态系统的多个方面,特别是如何通过App Store优化(ASO)和改进用户体验来提升应用的市场表现。不同于常规摘要仅概述文章内容的方式,我们将直接进入主题,首先介绍ASO的重要性及其对开发者的意义;接着分析当前iOS平台上用户行为的变化趋势以及这些变化如何影响应用程序的设计思路;最后提出几点实用建议帮助开发者更好地适应市场环境,增强自身竞争力。
|
23天前
|
设计模式 Swift iOS开发
探索iOS开发:从基础到高级,打造你的第一款App
【10月更文挑战第40天】在这个数字时代,掌握移动应用开发已成为许多技术爱好者的梦想。本文将带你走进iOS开发的世界,从最基础的概念出发,逐步深入到高级功能实现,最终指导你完成自己的第一款App。无论你是编程新手还是有志于扩展技能的开发者,这篇文章都将为你提供一条清晰的学习路径。让我们一起开始这段旅程吧!
|
2月前
|
开发工具 iOS开发 MacOS
【Mac_mistake】app不能安装在未命名需要OSv11.13或更高版本
【Mac_mistake】app不能安装在未命名需要OSv11.13或更高版本
100 0
|
4月前
|
编解码 iOS开发
IOS上架APP Store时预览图尺寸
IOS上架APP Store时预览图尺寸
732 3
|
4月前
|
开发工具 iOS开发
解决Flutter运行报错Could not run build/ios/iphoneos/Runner.app
解决Flutter运行报错Could not run build/ios/iphoneos/Runner.app
180 2
|
4月前
|
iOS开发
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
222 0
App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法
|
4月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
168 0
|
4月前
|
开发者
【Azure Logic App】中国区标准版本的逻辑应用(Standard Logic App)无法查看历史执行记录的解决之道
【Azure Logic App】中国区标准版本的逻辑应用(Standard Logic App)无法查看历史执行记录的解决之道