最近在iOS項目中需要使用到oc與js之間的相互調(diào)用唧领,而且要求是實現(xiàn)方式必須與Android中的相同溃肪,方便js中統(tǒng)一處理算谈。于是在對第三方庫WebViewJavascriptBridge進行研究之后糠雨,仿照Android中的WebView與JS的交互機制削葱,實現(xiàn)了一個奖亚,在這里分享給大家。
首先要說明的是析砸,在iOS中js調(diào)用Objective-C的代碼只能通過重定向的形式進行昔字,即js中通過修改iframe的src,或者直接跳轉(zhuǎn)到一個url首繁,在Objective-C中通過UIWebView的
webView:shouldStartLoadWithRequest:navigationType:方法攔截這個跳轉(zhuǎn)作郭,然后通過解析跳轉(zhuǎn)的url獲取js需要調(diào)用的方法名和參數(shù)。而在Android中弦疮,只需要調(diào)用WebView的addJavascriptInterface方法夹攒,將一個js對象綁定到一個java類,在類中實現(xiàn)相應(yīng)的函數(shù)胁塞,當(dāng)js需要調(diào)用java的方法時咏尝,只需要直接在js中通過綁定的對象調(diào)用相應(yīng)的函數(shù)即可。
顯然Android中js交互的方式要比iOS上方便得多啸罢,因此编检,我們可以在iOS上實現(xiàn)一套與Android相類似的機制。下面先說明一下實現(xiàn)的原理扰才,要在js中直接通過綁定的對象調(diào)用相應(yīng)的函數(shù)允懂,那么就需要在js中添加相應(yīng)的代碼,但是為了確保與Android的一致性衩匣,js代碼應(yīng)該在客戶端以注入的形式加入累驮。所以酣倾,我們先實現(xiàn)一下需要注入的代碼:
詳見:DEMO
DEMO2
javaScript:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (webView != _webView) { return; }
//is js insert
//這句代碼的原理就是如果html文件中不包含在app中定義的方法就在這里獲取然后然會給js
if (![[webView stringByEvaluatingJavaScriptFromString: [NSString stringWithFormat:@"typeof window.%@ == 'object'", kBridgeN ame]] isEqualToString:@"true"]) {
//get class method dynamically
unsigned int methodCount = 0;
Method *methods = class_copyMethodList([self class], &methodCount);
NSMutableString *methodList = [NSMutableString string];
for (int i=0; i<methodCount; i++) {
NSString *methodName = [NSString stringWithCString:sel_getName(method_getName(methods[i])) encoding:NSUTF8StringEncoding];
[methodList appendString:@"\""];
[methodList appendString: [methodName stringByReplacingOccurrencesOfString:@":" withString:@"" ]];
[methodList appendString:@"\","];
}
if (methodList.length>0) {
[methodList deleteCharactersInRange:NSMakeRange(methodList.length-1, 1)];
}
NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:@"WebViewJsBridge" ofType:@"js"];
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:js, methodList]];
}
__strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
if (strongDelegate && [strongDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
[strongDelegate webViewDidFinishLoad:webView];
}
}