前言
一說到熱修復(fù),可能很多人會覺得應(yīng)該很復(fù)雜,很難用(我以前是這么覺得的。。。),然后最近入職的公司的項目,剛上線就發(fā)現(xiàn)了重大bug,然后提新版,然后審核,用了差不多4天的時間,這確實很耽誤事的,然后就決定研究下熱修復(fù)的使用,為以后的突發(fā)bug做好準(zhǔn)備,實際發(fā)現(xiàn),使用起來蠻簡單的,這里以一個小demo演示熱修復(fù)是如何修復(fù)崩潰的,具體更深入的用法,可以看這個
https://github.com/bang590/JSPatch/wiki/JSPatch-%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95
開始
1、新建項目

起名這個
2、寫一段必定會崩潰的代碼
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSArray *arr = @"asd";
arr[1];
}
這里我在ViewController.m中給self.view點擊時故意造個bug,NSArray指向NSString,然后取下標(biāo),然后運行,點擊屏幕必崩
3、引入JSPatch框架
去JSPatch官網(wǎng)下載SDK http://www.jspatch.com/ 下載后將framework文件拖到項目中
在link binary中導(dǎo)入兩個庫libz和JavaScriptCore兩個框架

到JSPatch官網(wǎng)注冊、登錄,點擊我的app,添加app,獲取app key

在appDelegate中集成JSPatch
#import "AppDelegate.h"
// 導(dǎo)入頭文件
#import <JSPatch/JSPatch.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 通過appKey啟動
[JSPatch startWithAppKey:@"d22019f4b014551b"];
// 同步JSPatch官網(wǎng)控制臺中的js補丁
[JSPatch sync];
return YES;
}
@end
這樣,我們的app,就集成了JSPatch,運行即可
3、更新補丁,修復(fù)閃退bug
1、 我們現(xiàn)在假設(shè)我們的demo已經(jīng)上線了,xcode沒法修改我們demo的代碼了。
寫補丁,需要一點JS基礎(chǔ),但會聲明變量、調(diào)用方法,就可以使用大部分功能了,好在JSPatch作者為我們開發(fā)了一款插件,可以使用XCode補全JS代碼。
https://github.com/bang590/JSPatchX
Alcatraz搜一下JSPatchX裝上就行
2、在我們剛才的demo中新建一個empty文件,叫main.js,這是JSPatch規(guī)定的js文件命名

我們嘗試在補丁中重寫我們的touchBegin方法,并彈出AlertView告訴大家我們修復(fù)完成了。代碼如下
// 要用到的OC類需要require引用下
require('UIAlertView')
// 重寫ViewController類中的touchesBegan_withEvent方法,具體寫法看文檔吧
defineClass("ViewController", {
touchesBegan_withEvent: function(touches, event) {
// 方法的實現(xiàn)
var av = UIAlertView.alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles("bug修復(fù)了", "是不是很神奇", null, "取消", "確定", null);
av.show();
}
})
會點JS就能看懂代碼,還是很簡單的,這時我們可以把main.js文件從項目中拷貝出來了,刪掉項目中的main.js,這里只是想用下xcode中JSPatchX插件的提示功能,main.js不用打在包中
3、發(fā)布補丁
發(fā)布前先測試下我們的閃退bug,打開應(yīng)用點擊屏幕會閃退的
這時來到JSPatch官網(wǎng),找到我們的demo

點擊添加版本,把我們當(dāng)前版本添加上

點擊新添加的版本

點擊選擇文件,選擇我們main.js即可

下面有一些選項,加密和開發(fā)預(yù)覽(先debug測試,通過后再發(fā)給線上app)等,我們這里直接選全量下發(fā),就是直接把補丁發(fā)給所有已安裝的app了,點擊提交即可

再次重新打開app,你會發(fā)現(xiàn),點擊屏幕?。?!奇跡發(fā)生了?。?!還是崩潰?。?!這是ATS的鍋。。。在info.plist里加上如下代碼,允許http訪問
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
重新運行下,這回就ok
點擊屏幕,會發(fā)現(xiàn)我們寫的alertView彈出來了,大功告成。
總結(jié)
總體使用還是比較簡單的,更多功能可以去文檔中發(fā)掘
補充
一、可能很多人都不會寫js補丁,好在JSPatch作者還為我們準(zhǔn)備了另一個工具。
http://bang590.github.io/JSPatchConvertor/
這個工具可以幫助我們轉(zhuǎn)換OC代碼為JS,這回,門檻夠低了吧,哈哈

二、測試js文件是否生效
我們可以在我們的項目中測試我們書寫的main.js是否生效,以防把錯誤的js文件發(fā)布到正式版上,就影響用戶的使用了。
// [JSPatch startWithAppKey:@"asdasdasdasdasadasd"];
// [JSPatch sync];
[JSPatch testScriptInBundle]; // 用于測試,會在bundle下自動尋找main.js來執(zhí)行
testScriptInBundle會自動尋找我們項目bundle下的main.js文件,跟main.js發(fā)到JSPatch控制臺再sync的效果是一樣的,測試完畢記得改回來。