JSPatch来更新已上线的App中出现的BUG(超级详细)
JSPatch的作用是什么呢?
简单来说:(后面有具体的操作步骤以及在操作过程中会出现的错误)
1.iOS应用程序上架到AppStore需要等待苹果公司的审核,一般审核时间需要1到2周.虽然程序在上架前会经过测试人员的测试,但有时候还是不免会发生新版本上线后出现严重的bug,导致用户刚升级到新版本就出现crash,严重影响用户体验.
2.这时能做的只是赶紧修复bug然后提交等待漫长的AppStore审核,再盼望用户快点升级,才能完成此次bug的修复,这样及容易导致用户流失,这对企业来说影响非常严重.
3.为了解决由于AppStore审核而导致程序更新新版本慢,目前有以下2种方案实时修复线上bug:
1⃣️直接使用UIWebView加载网络上的HTML的代码,这样如果有问题只需要更新服务器的HTML文件,用户重新进入程序,加载新的HTML文件,整个程序就能更新.对用户影响非常小
2⃣️使用其他脚本语言通过Runtime动态调用OC
1⃣️.1⃣️WaxPatch:它把Lua脚本语言和原生Objective-C应用编程接口(API)结合起来,通过Lua脚本来调用OC
1⃣️.2⃣️JSPatch:JS是通过JavaScriptCore.framework调用Runtime,来实现JS调用OC
JSPatch优势:
1⃣️JS比Lua在应用开发领域有更广泛的应用,目前前端开发和前端开发有融合的趋势,作为扩展的脚本语言,JS是不二之选
2⃣️JSPatch更符合Apple的规则。iOS Developer Program License Agreement里3.3.2提到不可动态下发可执行代码,但通过苹果JavaScriptCore.framework或WebKit执行的代码除外,JS正是通过JavaScriptCore.framework执行的
3⃣️使用系统内置的JavaScriptCore.framework,无需内嵌脚本引擎,体积小巧
4⃣️支持block
JSPatch缺点:
1⃣️相对于WaxPatch,JSPatch劣势在于不支持iOS6,因为需要引入JavaScriptCore.framework
2⃣️另外目前内存的使用上会高于wax,持续改进中
存在风险:JSPatch让脚本语言获得调用所有原生OC方法的能力,不像web前端把能力局限在浏览器,使用上会有一些安全风险
1⃣️若在网络传输过程中下发明文JS,可能会被中间人篡改JS脚本,执行任意方法,盗取APP里的相关信息,危及用户信息和APP
2⃣️若下载完后的JS保存在本地没有加密,在越狱的机器上用户也可以手动替换或篡改脚本
风险控制:
1⃣️JSPatch脚本的执行权限很高,若在传输过程中被中间人篡改,会带来很大的安全问题,为了防止这种情况出现,在传输过程中对JS文件进行了RSA签名加密,流程如下:
服务端:计算JS文件MD5值。用RSA私钥对MD5值进行加密,与JS文件一起下发给客户端。
客户端:拿到加密数据,用RSA公钥解密出MD5值。本地计算返回的JS文件MD5值。对比上述的两个MD5值,若相等则校验通过,取JS文件保存到本地。
由于RSA是非对称加密,在没有私钥的情况下第三方无法加密对应的MD5值,也就无法伪造JS文件,杜绝了JS文件在传输过程被篡改的可能。
2⃣️本地存储
本地存储的脚本被篡改的机会小很多,只在越狱机器上有点风险,对此JSPatch SDK在下载完脚本保存到本地时也进行了简单的对称加密,每次读取时解密。
JSPatch需要使用者有一个后台可以下发和管理脚本,并且需要处理传输安全等部署工作,JSPatch平台帮你做了这些事,提供了脚本后台托管,版本管理,保证传输安全等功能,让你无需搭建一个后台,无需关心部署操作,只需引入一个SDK即可立即使用JSPatch。
JSPatch平台速度和稳定性如何?
通过JSPatch平台上传的脚本文件都会保存在七牛云存储上,客户端APP只跟七牛服务器通讯,支持高并发,CDN分布全国,速度和稳定性有保证。
除了修复bug,JSPatch也可以用于动态运营,实时修改线上APP行为,或动态添加功能。
JSPatch详细使用文档见Github Wiki
第一步:创建好自己的项目
#import"ViewController.h"
@interfaceViewController()
@property(nonatomic,weak)UITableView*table;
//创建可变数组来更新数据
@property(nonatomic,strong)NSMutableArray*dataArray;
@end
@implementationViewController
#pragma mark -懒加载可变数组
- (NSMutableArray*)dataArray
{
if(_dataArray==nil)
{
_dataArray= [NSMutableArrayarray];
[_dataArrayaddObjectsFromArray:@[@"huangfang--1",@"huangfang--2",@"huangfang--3",@"huangfang--4",@"huangfang--5"]];
}
return_dataArray;
}
- (void)viewDidLoad
{
[superviewDidLoad];
self.view.backgroundColor= [UIColorgrayColor];
[selfsetUpVCWithContent];
}
#pragma mark -设置控制器的内容
-(void)setUpVCWithContent
{
//自定义导航栏的标题控件
UILabel*label = [[UILabelalloc]initWithFrame:CGRectMake(0,0,100,44)];
label.text=@"HFJSpatch";
label.textColor= [UIColorgreenColor];
label.font= [UIFontboldSystemFontOfSize:30];
self.navigationItem.titleView= label;
//自定义导航栏右边的item
UIButton*button =[UIButtonbuttonWithType:UIButtonTypeContactAdd];
[buttonaddTarget:selfaction:@selector(addData)forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem*rightButton = [[UIBarButtonItemalloc]initWithCustomView:button];
self.navigationItem.rightBarButtonItem= rightButton;
UITableView*table = [[UITableViewalloc]initWithFrame:self.view.bounds];
self.table= table;
table.dataSource=self;
[self.viewaddSubview:table];
}
#pragma mark -添加数据的方法
-(void)addData
{
NSString*datas =nil;
[self.dataArrayaddObject:datas];
[self.tablereloadData];
}
#pragma mark -数据源方法
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.dataArray.count;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
staticNSString*ID =@"HFcell";
UITableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if(cell ==nil)
{
cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:ID];
cell.textLabel.textColor= [UIColorredColor];
cell.textLabel.textAlignment=NSTextAlignmentCenter;
cell.textLabel.font= [UIFontsystemFontOfSize:20];
if(indexPath.row>5)
{
cell.textLabel.textColor= [UIColororangeColor];
cell.textLabel.textAlignment=NSTextAlignmentRight;
cell.textLabel.font= [UIFontboldSystemFontOfSize:25];
}
}
cell.textLabel.text=self.dataArray[indexPath.row];
returncell;
}
@end
第二步:登录http://jspatch.com该网站,这里需要注册一下账号哈(已有账号的话,可以直接登录)
下载SDK到本地
第三步:下载完成后,打开我们已经创建好的项目,将下载好的SDK拖到我们的工程中.
第四步:需要在我们的工程中添加两个框架( libz.tbd 和 JavaScriptCore.framework )
第五步:在项目工程里先创建一个空的文件(main.js),这个就不用说了吧,大家都会哈^_^
注:如果想在空文件中显示JavaScript的格式的话,可以进行一下操作:
1、先选中刚才创建好的(main.js)
2.
3.在文件中写入代码
//main.js
// 指定要更新的对应的控制器
defineClass("ViewController", {
// 添加或修改的方法(
addData: function() {
// 获取到控制器中的可变数组
var datas = self.dataArray();
datas.addObject("huangfang6");
datas.addObject("huangfang7");
datas.addObject("huangfang8");
datas.addObject("huangfang9");
// 如果添加成功会将数组中的第一个元素打印出来(这个可以根据需要进行打印)
// console.log(datas.firstObject());
// 如果添加成功会将数组中的第一个元素打印出来
console.log(datas.lastObject());
self.table().reloadData();
}
})
注:上面的 addData: function() 中的addData要和我们项目中的点击按钮执行的方法一样,如果不一样会报错的
4、在我们的项目工程中找到AppDelegate.m文件,在以下方法中添加一行测试的代码,我们先在本地测试一下,看看是否成功
#import “AppDelegate.h"
#import “ViewController.h"
#import<JSPatch/JSPatch.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
ViewController *vc = [[ViewController alloc]init];
vc.view.backgroundColor = [UIColor magentaColor];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
self.window.rootViewController = nav;
[self.window makeKeyWindow];
[JSPatch testScriptInBundle];
return YES;
}
@end
以下为运行结果 点击+后出现右对齐的三个
第六步:接下来就需要将我们的main.js文件添加到服务器上来进行操作:
1、将我们的项目工程中的main.js文件项目中移除,在移除之前要复制一份出来,方便等会将main.js 文件上传到服务器哈
2、登录到之前登录的网站,执行以下操作:
2.1 添加我们要更新的项目名称:XGJSPatch
2.2 点击新增APP后,出现如下界面,填写完后,直接点击”提交”按钮就可以了
2.3 接下来会看到以下界面:
2.4 点击上图中的”添加APP版本”,进入如下界面
点击进入下一个界面
第七步:在appDelegate.m文件中写入下面的代码:
一切准备就绪后,可以直接运行 可能会出现以下几个错误
ATS:安全机制 在info.plist中加如下代码
如果都没有错误的话,运行成功后的界面如下图:
下图是我重新更改了下数据 再重新添加了补丁 运行出来的结果
关注「 iOS大全 」
JSPatch来更新已上线的App中出现的BUG(超级详细)的更多相关文章
- 解决“iOS 7 app自动更新,无法在app中向用户展示更新内容”问题
转自cocoachina iOS 7能在后台自动app,这对开发者来说和用户都很方便,但是还是有一些缺点.用户不会知道app本次更新的内容,除非他们上到app的App Store页面去查看.开发者也会 ...
- JSPatch – 动态更新iOS APP
原文:http://blog.cnbang.net/works/2767/ JSPatch是最近业余做的项目,只需在项目中引入极小的引擎,就可以使用JavaScript调用任何Objective-C的 ...
- JSPatch动态更新APP
JSPatch,只需在项目中引入极小的引擎,就可以使用JavaScript调用任何Objective-C的原生接口,获得脚本语言的能力:动态更新APP,替换项目原生代码修复bug. 用途 是否有过这样 ...
- 仿各种APP将文章DOM转JSON并在APP中以列表显示(android、ios、php已开源)
背景 一直以来都想实现类似新闻客户端.鲜城等文章型app的正文显示,即在web editor下编辑后存为json,在app中解析json并显示正文. 网上搜过,没找到轮子.都是给的思路,然后告知是公司 ...
- ios-获取商店已上线app信息
NSString *url = [[NSString alloc] initWithFormat:@"http://itunes.apple.com/lookup?id=%@",@ ...
- 从Android手机中取出已安装的app包,导出apk
从Android手机中取出已安装的app包,导出apk TAG:Android,提取,apk,adb,pm,root,导出apk 假设有这样一个场景,A君看到你手机上一个实用APP,想要安装到自己手机 ...
- uniapp 证书 打包上线GooglePlay app自动升级
uniapp Android证书 打包上线GooglePlay app自动升级 1.Android证书申请 要安装jdk并配置环境变量. keytool -genkey -alias android ...
- 利用RxJava获取手机已安装的App的图片、应用名称和版本号
先上效果图: 获取手机已安装的App列表利用Android系统API就可以办到,这里为什么要引入RxJava?现在我们假设一下有下面几个需求: 1.我们不需要所有的App,只需要用户安装的第三方App ...
- 【转】xcode APP 打包以及提交apple审核详细流程(新版本更新提交审核)
原文网址:http://blog.csdn.net/mad1989/article/details/8167529 最近项目到了最后的阶段,测试完一切ok后,准备打包以及提交,不料看到网上众教程,好多 ...
随机推荐
- Linux.NET学习手记(6)
各位读者大家好,好长一段时间没有更新文章了,自从参加工作之后,每天等待去做的工作没完没了,个人的时间也变得奢侈起来,今后要尽量从中脱身,抽更多的时间来完成自己想做的事情(希望如此). 言归正传,上一回 ...
- Java 8函数编程轻松入门(四)方法引用
C#中系统提供了许多IEnumerable的扩展方法.同样在Java 8中新引入了Collector类. 1.方法引用 定义: 简而言之:就是一个Lambda表达式.在Java 8中,我们我们会使用L ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- Jmeter安装与环境部署
Jmeter安装与环境部署 版权声明:本文为博主原创文章,未经博主允许不得转载. 博主:海宁 联系:whnsspu@163.com
- 搭建LNAMP环境(一)- 源码安装MySQL5.6
1.yum安装编译mysql需要的包 yum -y install gcc-c++ make cmake bison-devel ncurses-devel perl 2.为mysql创建一个新的用户 ...
- 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 架构原理(Architecture) 测试环境(Environment) 安装Moebius( ...
- ROC曲线、PR曲线
在论文的结果分析中,ROC和PR曲线是经常用到的两个有力的展示图. 1.ROC曲线 ROC曲线(receiver operating characteristic)是一种对于灵敏度进行描述的功能图像. ...
- Python标准模块--concurrent.futures
1 模块简介 concurrent.futures模块是在Python3.2中添加的.根据Python的官方文档,concurrent.futures模块提供给开发者一个执行异步调用的高级接口.con ...
- Log4net入门(WCF篇)
在上一篇Log4net入门(ASP.NET MVC 5篇)中,我们讲述了如何在ASP.NET MVC 5项目中使用log4net.在这一篇中,我们将讲述如何在WCF应用中使用log4net,为了讲述这 ...
- .net 分布式架构之分布式锁实现
分布式锁 经常用于在解决分布式环境下的业务一致性和协调分布式环境. 实际业务场景中,比如说解决并发一瞬间的重复下单,重复确认收货,重复发现金券等. 使用分布式锁的场景一般不能太多. 开源地址:http ...