IOS產(chǎn)品開發(fā)中常常會(huì)遇到這種情況谎砾,線上發(fā)現(xiàn)一個(gè)嚴(yán)重bug,可能是一個(gè)crash,可能是一個(gè)功能無法使用逢倍,這時(shí)能做的只是趕緊修復(fù)Bug然后提交等待漫長的審核,即使申請(qǐng)加急也不會(huì)快到那里去景图,即使審核完了之后较雕,還要盼望著用戶快點(diǎn)升級(jí),用戶不升級(jí)還是在存在同樣的漏洞挚币,這樣的情況讓開發(fā)者付出了很大的成本才能完成Bug的修復(fù)亮蒋。
JSPath就是為了解決這樣的問題而出現(xiàn)的,只需要在項(xiàng)目中引入極小的JSPatch引擎妆毕,就可以還用JavaScript語言調(diào)用Objective-C的原生API慎玖,動(dòng)態(tài)更新APP,修復(fù)BUG笛粘。
JSPaht本身是開源項(xiàng)目,項(xiàng)目地址:http://jspatch.com/,github地址:https://github.com/bang590/JSPatch
在他的官網(wǎng)上面給出了一個(gè)例子:
@implementationJPTableViewController
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
4
NSString *content = self.dataSource[[indexPath row]];//可能會(huì)超出數(shù)組范圍導(dǎo)致crash
JPViewController *ctrl =[[JPViewController alloc] initWithContent:content];
[self.navigationController pushViewController:ctrl];
}
...
@end
可以通過下發(fā)下面的JavaScript代碼修復(fù)這個(gè)bug:
//JS
defineClass("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);
}
}
}, {})
JSPtch需要一個(gè)后臺(tái)服務(wù)用來下發(fā)和管理腳本趁怔,并需要處理傳輸安全等。
注冊(cè)獲取AppKey
在平臺(tái)上面注冊(cè)一個(gè)賬戶薪前,新建一個(gè)App可以拿到對(duì)應(yīng)的AppKey润努。
導(dǎo)入SDK到項(xiàng)目中
SDK地址:http://jspatch.com/Index/sdk
當(dāng)前下載下來的SDK版本名稱是:JSPatch 2.framework,需要去掉中間的空格,不然導(dǎo)入項(xiàng)目的時(shí)候會(huì)報(bào)錯(cuò)示括。
導(dǎo)入項(xiàng)目的時(shí)候要選擇Copy items if needed铺浇。
還需要添加對(duì)于的依賴框架JavaScriptCore.framework和libz.tbd.
添加JSPatch代碼
在AppDelegate.m中添加代碼:
#import"AppDelegate.h"
#import
@implementationAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[JSPatch startWithAppKey:@"f78378d77e5783e8"];
[JSPatch sync];
returnYES;
}
@end
在平臺(tái)中上傳js修復(fù)文件
為了簡單我們只上傳一個(gè)簡單的UIAlertView,彈出一個(gè)提示框:
ar alertView = require('UIAlertView').alloc().init();
alertView.setTitle('Alert');
alertView.setMessage('AlertView from js');
![Uploading 2855997-8dd6771dfca9a2fe_173960.png . . .]
alertView.addButtonWithTitle('OK');
alertView.show();
用JavaScript實(shí)例化了UIAlertView,文件名需要命名為main.js垛膝。
從服務(wù)器下發(fā)到客戶端
把main.js上傳到服務(wù)器上鳍侣,下發(fā)到版本為1.0的客戶端上面。
在請(qǐng)求服務(wù)加載腳本的時(shí)候出現(xiàn)了一個(gè)錯(cuò)誤:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
這個(gè)錯(cuò)誤出現(xiàn)的原因是ios9引入了新特性App Transport Security(ATS),簡單來說就是APP內(nèi)部的請(qǐng)求必須使用HTTPS協(xié)議吼拥。
很明顯這里的url并沒有使用https倚聚,我們可以通過設(shè)置先規(guī)避掉這個(gè)問題:
1.在info.plist中添加NSAppTransportSecurity類型為Dictionary.2.在NSAppTransportSecurity中添加NSAllowsArbitraryLoads類型為Boolean,值為YES
運(yùn)行效果: