阿里HotFix成功经验流程分享(最全最专业)

登陆官网申请权限,开通HotFix支持。

申请权限.png

一、进入HotFix后台,配置好后台数据。

二、找到iOS的SDK,下载两个framework拖进项目:
AliHotFix.framework
AliHotFixDebug.framework

注意: 在上线之前的Release模式下要把AliHotFixDebug.framework移除,此framework仅用于调试扫码的时候使用,本文接下来会讲解。

记得打开Capabilities里面的keychain sharing

经阿里技术团队解答知道:若使用 XCode8 接入,需要在项目 Capabilities 打开 Keychain Sharing 开关,否则在模拟器下载脚本后会出现 decompress error, md5 didn't match 错误(真机无论是否打开都没问题)这个选项是为了在模拟器下对patch的验签能通过。
iOS的keychain提供一种安全保存信息的方式,可以保存密码等数据,而且keychain中的数据不会因为你删除app而丢失,你可以在重新安装后继续读取keychain中的数据。

三、必须要使用CocoaPods 集成 SDK 所需依赖,安装完成之后在项目目录下执行pod init命令,然后在项目文件夹下创建的podfile文件中添加如下内容:

source 'https://github.com/CocoaPods/Specs.git'
source 'http://repo.baichuan-ios.taobao.com/baichuanSDK/AliBCSpecs.git'
 
platform :ios, '7.0'
inhibit_all_warnings!
 
target ‘项目名称***’ do
    pod 'BCUserTrack'
    pod 'ZipArchive', '~> 1.4.0'
    pod 'wax', :git => 'https://github.com/alibaba/wax.git'
end

(关于集成pod如果遇到坑,可留言咨询)

后台配置成功之后,你已经获得了三个参数App ID、App Secret和RSA密钥,接下来我们看代码:

#import <AliHotFix/AliHotFix.h>
//代码取自官方demo,最好都写在AppDelegate里的这个方法中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
    //加解密补丁文件的密钥(该密钥已加密)
    char aesEncryptKeyBytes[] = {-106,0,-127,-95,-109,-44,-87,84,110,6,-108,-74,-58,-115,37,1,-52,-96,-102,70,-112,73,126,113,-82,120,-72,75,31,-87,-126,75};
    NSData *aesEncryptKeyData = [NSData dataWithBytes:aesEncryptKeyBytes length:sizeof(aesEncryptKeyBytes)];
    //本地自签名证书RSA公钥
    char rsaPublicDerBytes[]={48,-126,2,1,48,-126,1,106,2,9,0,-79,22,-42,-112,86,-37,19,-31,48,13,6,9,42,-122,72,-122,-9,13,1,1,5,5,0,48,69,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17,6,3,85,4,8,19,10,83,111,109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10,19,24,73,110,116,101,114,110,101,116,32,87,105,100,103,105,116,115,32,80,116,121,32,76,116,100,48,30,23,13,49,54,49,48,51,49,48,56,51,53,48,51,90,23,13,50,54,49,48,50,57,48,56,51,53,48,51,90,48,69,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17,6,3,85,4,8,19,10,83,111,109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10,19,24,73,110,116,101,114,110,101,116,32,87,105,100,103,105,116,115,32,80,116,121,32,76,116,100,48,-127,-97,48,13,6,9,42,-122,72,-122,-9,13,1,1,1,5,0,3,-127,-115,0,48,-127,-119,2,-127,-127,0,-42,18,-126,-97,-3,105,-91,72,24,-128,-121,-53,-39,-111,-65,-128,114,101,109,52,-26,-65,-18,-42,-88,13,77,-86,-118,77,-12,42,5,-14,-100,43,-104,-74,-84,39,-51,-81,-48,16,-28,25,-66,66,29,60,-17,-115,-62,30,-19,-120,-127,72,115,59,126,-83,90,87,119,-125,24,75,-65,-85,-118,-59,89,37,51,-121,4,-95,88,-77,-108,-7,5,-32,115,61,-119,14,44,-90,-40,98,-123,96,-53,-38,-101,-128,-72,78,3,-122,-14,-40,-107,-77,-45,12,81,-78,99,-86,-3,22,-97,95,-54,-24,-96,0,14,-2,-57,-25,-2,-81,51,79,2,3,1,0,1,48,13,6,9,42,-122,72,-122,-9,13,1,1,5,5,0,3,-127,-127,0,-64,-63,-100,-76,-35,115,73,-28,40,-63,126,39,-91,109,48,47,19,113,11,60,85,24,75,123,-81,-41,90,37,-59,-82,-3,115,122,-95,-98,-84,-60,8,-12,36,124,-25,14,105,-108,-108,96,-44,-40,-126,-118,7,57,114,-53,-125,5,-125,111,53,-38,-57,80,-19,14,126,-76,-42,64,-31,52,-21,-121,-100,-109,-53,42,-9,-92,18,-94,-19,-49,55,62,-106,127,23,-23,68,-67,26,-1,39,-29,78,-63,-14,118,-11,-94,61,-67,62,-89,-107,-54,-24,31,86,-47,-63,-28,59,-116,62,48,-112,47,101,-3,114,-13,79,13,4,79,11};
    NSData *rsaPublicDerData = [NSData dataWithBytes:rsaPublicDerBytes length:sizeof(rsaPublicDerBytes)];

    //App Secret
    NSString * secret = @"0826092cd0903caf20815f69578856be";
    //RSA密钥
    NSString * privateKey = @"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR5mTRZibau72o0SKBmQisFJ98kZwbAT7XbgfMEU4iIKvzRK/87R220or5LtARnKL7XExBMte6GKHI5PSY0gB6tES8Gp155jf7vWGAls2yXfrKxz2AIiwy2jplCBzCH0GlFbhiFbAkW8OwHlHi9rdpQN3lxmq+1qRDjZGN0heED1npg9BObVHf+7ygEAwyrFvDSnBTfzONZUxZwyz9HynLCbhHWqi8vZacJNS+CVTuymHEa7hbSQyUbOb+QTvJyoovP+L9IkpVhdG1mMRFJf9ex9dV9OTOmZXR29MJVsyZmS3YgHoXtphvClXJ8uaXX6ngfFLQgV/6nss2buxz2O6ZAgMBAAECggEAIZCUXwwWIjoQrta2DoSLVzNDYaAJ/rhxoZQBnTPZ+sXzaPrDVfei311edWcMnRCg+hzIujMdKAXkqlfp4YJmc9Qm//NLiTCqbnKqDLAk0EUInj/p6SFzc5t61aVhIFOagYUWrxH4PNUTlt/SzNkfZspyghr8kbzFe3kFJFBR8qJP+YN+EDunDc/ihb7Z6vmApi7vbNlebKoZZnMs0LhlNxm5xmrOUvezScQ8wjT2bNlAO6nAGPj84fAARmZndeS8D0m7tv3jwKZNlkYt+MKUEdKSaeEx6FBAseBVhavBs9LwRWwekY+SvgN/jRXq0BCuPkUVcD9qDuDFLCaXInN+BQKBgQDYc1ffbuMpAtXCznMG+XCwbSHbQ5s6UFKoaUaymnCinxAvH6Zvw2K6BwqkWmwao4QvJcnfkhlsErc46Xc6fqgF0ywc60wE0XHA7HcCtzJO5DP/6NybAFOaRzq2vwfdqFSuTVelrQAbeAkngnbA8K4XSqYP6Qz81V3Wr7jUF8G7zwKBgQCsjvzdKicHRUAvwII3Kcqkoo5ulxW4CWUxkrc0pwVLXI3alhyiSOdLd7gFhnpS9+1kvp8zu5nabM9VGg7krY/MRHqvurRz5RB6l5bxxv5jrHgpMRiQR2+30zda+n/7FwTkMST+FwkSQXSmF/w+AAOyfZoF5CEQTCx1xoqSZAbBFwKBgQCnzSvHfNjAd4EuiAxm0MRLEh/YM15I4/Jgu1Tiq5Y8jGHolnnaVTfZjhHy/mKmeDPGtV3+Y+4veYbvqRcUkxJBice+F7AUYCb28JsG0O1AeevSLj2wMJ2fki7zc79uWMxlYHJdb3QQ14sJRTw5MZ1VUzrQRNUbwXIBOLNqQYygwwKBgFOiagR3rbrkYZvDXlmGM+VftFD9gVVVmGpSheFLIlHIZiiPoQk29IOrXtGuwBL+f1zY1yinwIYRPtwsaROE27FRb3VEtLmHSFlip5I/tIRyzzqHxTQIq6kZAjdiOi1klsZS228bkxX6C6OE9IjIUQJtxf0c+LmBcfsTY45YVL25AoGAM3leDbpcITvQpqanctpVybhkUUgrhXDFYjx/w+QmNuu8eQ9jR8lDsUtihyu3ssPu2g+ieYaoeybPXAC26kb5Y0j+t5A4JINxisNXdJtrplbJgaC7QgN0FmEDnPmTXY0tvRGwX2zL9kOMvogfyvF9DR2CaUyq1JkcJFGhhrM5mdw=";

    // 百川平台申请的appid,secret,rsaKey.以及本地打包自签证书的RSA公钥&本地加密patch密钥
    [AliHotFix startWithAppID:@"76547-2" secret:secret privateKey:privateKey publicKey:rsaPublicDerData encryptAESKey:aesEncryptKeyData];

    return YES;
}

//在程序每一次重新进入前台激活时,同步补丁。
- (void)applicationDidBecomeActive:(UIApplication *)application {
     [AliHotFix sync];
}

还差rsaPublicDerData(本地自签名证书RSA公钥)和aesEncryptKeyData(加解密补丁文件的密钥)两个参数。

接下来要特别谨慎对待了,下载打包工具到桌面,现在你的桌面有个tools文件夹,里面有三个文件

tool.png

打开终端
第一步:1、cd到tools文件夹;2、终端输入AliHotFixCommand的路径你会得到:

AliHotFixCommand.png

第二步:我们首先进行上图中的第2步,即:
终端输入AliHotFixCommand的路径 -generateRSAKey
会得到

2.2.0png

这是让你输入各种信息,可以直接一直回车,直到输入密码阶段,连续输入两个自定义的密码(想一个复杂点的密码,一定要记住你输入的密码,不要泄露,在此阶段的第3步会用到这个密码,以后的补丁文件也会持续用到,先规定为“密码一”
2.2.1png

你的tools文件夹也会变成这样:

2.2.3png

意思就是生成了本地自签名证书.p12和.der

然后,我们进行图片(AliHotFixCommand.png)中的第1步(对建立的Patch目录进行加密打包):
在tools文件夹中创建如图的目录结构

lua_patchpng

备注:在src目录下的lua补丁文件支持多目录多文件,patch/lib(非必须目录) 存放src目录下lua代码所需的公共类或工具类代码

js_patch.png

备注:js补丁文件必须放在patch/src目录下,只支持单个js补丁文件且文件必须命名为main.js

不管是lua还是js,src文件夹里面存放的都是补丁代码,测试的时候可以什么都不放。也可以在放一个弹窗方法调用,这里有个lua的代码,方便大家用来测试

//测试代码
- (void) showHotFix{
    UIAlertView *ceshiview = [[UIAlertView alloc]initWithTitle:@"HotFix" message:@"测试HotFix" delegate:nil cancelButtonTitle:@"OK " otherButtonTitles:nil, nil];
    [ceshiview show];
}
//lua代码
waxClass{"AViewController"}
function showHotFix(self)
    local ceshiview = UIAlertView:initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles("HotFix","测试HotFix修复后的detail是否改变",nil,"OK ",nil)
    ceshiview:show()
end

解释一下:waxClass{"AViewController"}指的是AViewController里面的方法,起到定位修改内容的作用,官方文档有个转换工具,可以把OC代码转换为js或者lua的代码点我查看,个人觉得很坑,转换后一定要仔细检查一遍,转换的语法往往会有错误,一定要仔细检查。

这里我改变了UIAlertView里message内容,如果message内容改变,也就证明HotFix是work的。还有一点,如果HotFix是work的,也不会走showHotFix方法,可打断点测试。所以我们应该知道,如果修改一个方法中的某一点内容,需要把整个方法的代码都打包成补丁上传后台。
可见写代码的时候分块创建是很有必要的。

打开终端,输入命令格式:
COMMAND-PATH –pack PATCH-DIRECTORY APP-VERSION ENCRYPT-KEY PRIVATE-P12-FILE-PASSWORD
参数说明:
COMMAND-PATH: AliHotFixCommand所在路径
PATCH-DIRECTORY:patch包所在路径
APP-VERSION:patch绑定的app版本
ENCRYPT-KEY:加密patch文件的密钥(备注:长度不超过32位字符串,自定义的密码,我们这里成为“密码二”)
PRIVATE-P12-FILE-PASSWORD:生成RSA密钥时输入的密码(刚才的“密码一”)

你会得到如图的patch.zip的补丁包。


patch补丁包.png

在阿里HotFix后台点击上传补丁。

补丁上传成功.png

问题:上传了但还没发布的补丁怎么删啊?
答:补丁不允许删除的,只允许上传新补丁去覆盖,永远加载同一个版本中最新的补丁。

上传成功后点击“查看详情”,会看到一个二维码,就是我们开始提到的
AliHotFixDebug.framework的作用,真机打开项目会打开摄像头,扫面这个二维码就可以测试patch包是否是work的。


屏幕快照 2016-12-14 13.15.18.png

别急着测试,还有第3步(获取运行patch需要的密钥参数):
打开终端
命令格式: COMMAND-PATH –encryptKey ENCRYPT-KEY

参数说明:
COMMAND-PATH: AliHotFixCommand所在路径
ENCRYPT-KEY:加密文件密钥(备注:要与打包命令输入的相一致,也就是我们之前的“密码二”)

那么在终端中会获得如下代码:

char aesEncryptKeyBytes[] = {xxxx};
//加密过后的aesKey二进制流格式
NSData *aesEncryptKeyData = [NSData dataWithBytes:aesEncryptKeyBytes length:sizeof(aesEncryptKeyBytes)];
char rsaPublicDerBytes[]={xxxx};
// 本地自签名公钥二进制流格式
NSData *rsaPublicDerData = [NSData dataWithBytes:rsaPublicDerBytes length:sizeof(rsaPublicDerBytes)];

就是在AppDelegate里还缺少的两个参数:rsaPublicDerData(本地自签名证书RSA公钥)和aesEncryptKeyData(加解密补丁文件的密钥)。

最后确认一下你要测试的是哪个view或者哪个controller的代码,在那个view或者controller里

#import <AliHotFixDebug/AliHotFixDebug.h>
[AliHotFixDebug showDebug:self];

当进入的时候就会立刻打开摄像头,就可以扫码测试了。

扫码错误:Patch run error: 未能完成操作。(“”错误 -9809。).
答:打包用的自签名证书和集成到app的自签名证书不匹配,建议重新走一遍流程,细心点。
如果patch补丁包成功,扫码会提示:Load patch success.
如果提示Load patch success. 但补丁未生效,个人经验有两个原因:
1、你的lua代码或者js代码语法有问题。
2、可能是你前后用的自定义签名证书不一致,建议重新走一遍流程。

相关说明(此说明参考自梁炯幸
1、所修改的目标方法,必须在方法调用之前已把补丁加载完毕,然后在方法调用时才会生效。
2、补丁的下载是异步的,不会阻塞当前线程。补丁的下载受网络环境影响。
3、加载过的补丁将会存在于App沙盒,App每一次启动都会加载它,即使断网。App在同步补丁时发现没有更高版本的补丁时,会继续使用本地存放的补丁。所以在百川控制台停用了所有补丁后,App再去同步补丁,依然等同于没有更高版本补丁,并不会删除本地补丁。

OK,整个阿里HotFix的流程就结束了。

目前阿里HotFix是免费的,内部说今天想实行一元购的活动,但为了用户体验还是放弃了,等到几个版本的迭代之后阿里HotFix就会收费,现在尝试学习一下阿里HotFix的接入还是比较好的。

另外,整个过程要多谢陈老板的帮助。

个人对于js(具体的编写方法参考JSPatch基础用法)和lua的语法不是很熟悉,还需要继续深入学习才能准确的使用HotFix线上修复bug。个人比较倾向于lua,不知此观点是否正确,有关于lua的书籍和文章,还请大家不吝赐教,积极分享,共同学习。

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

推荐阅读更多精彩内容