標籤:
JSPatch,只需在項目中引入極小的引擎,就可以使用JavaScript調用任何Objective-C的原生介面,獲得指令碼語言的能力:動態更新APP,替換項目原生代碼修複bug。
是否有過這樣的經曆:新版本上線後發現有個嚴重的bug,可能會導致crash率激增,可能會使網路請求無法發出,這時能做的只是趕緊修複bug然後提交等待漫長的AppStore審核,再盼望使用者快點升級,付出巨大的人力和時間成本,才能完成此次bug的修複。
使用JSPatch可以解決這樣的問題,只需在項目中引入JSPatch,就可以在發現bug時下發JS指令碼補丁,替換原生方法,無需更新APP即時修複bug。
@implementation JPTableViewController...- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *content = self.dataSource[[indexPath row]]; //可能會超出數組範圍導致crash JPViewController *ctrl = [[JPViewController alloc] initWithContent:content]; [self.navigationController pushViewController:ctrl];}...@end
上述代碼中取數組元素處可能會超出數組範圍導致crash。如果在項目裡引用了JSPatch,就可以下發JS指令碼修複這個bug:
//JSdefineClass("JPTableViewController", { //instance method definitions tableView_didSelectRowAtIndexPath: function(tableView, indexPath) { var row = indexPath.row() if (self.dataSource().length > row) { //加上判斷越界的邏輯 var content = self.dataArr()[row]; var ctrl = JPViewController.alloc().initWithContent(content); self.navigationController().pushViewController(ctrl); } }}, {})
這樣 JPTableViewController 裡的 -tableView:didSelectRowAtIndexPath: 就替換成了這個JS指令碼裡的實現,在使用者無感知的情況下修複了這個bug。
原理
JSPatch用iOS內建的JavaScriptCore.framework作為JS引擎,但沒有用它JSExport的特性進行JS-OC函數互調,而是通過Objective-C Runtime,從JS傳遞要調用的類名函數名到Objective-C,再使用NSInvocation動態調用對應的OC方法。
JSPatch更符合Apple的規則。iOS Developer Program License Agreement裡3.3.2提到不可動態下發可執行代碼,但通過蘋果JavaScriptCore.framework或WebKit執行的代碼除外,JS正是通過JavaScriptCore.framework執行的。
動態更新方案對比:JSPatch vs React Native
iOS開發熱更新JSPatch