總評:
oc 與js的交互帅腌,1.有原生的方式,oc 調(diào)js簡單麻汰,js調(diào)oc 麻煩(協(xié)議攔截"實現(xiàn)的交互方式)速客。
2.iOS7之前,蘋果沒有出 JavaScriptCore 之前五鲫,業(yè)界普遍采用開源庫WebViewJavascriptBridge和EasyJSWebView來解決的溺职,原理都是基于攔截協(xié)議的封裝,
3.iOS7之后,蘋果針對JavaScript出了一個官方的庫JavaScriptCore,是Objective-C封裝了WebKit的JavaScript引擎浪耘,使我們可以脫離WebView執(zhí)行JS代碼乱灵。所以在iOS7之后想要實現(xiàn)交互,采用JavaScriptCore也是一種不錯的選擇七冲,前提是你的項目不需要兼容到iOS7之前(覺得現(xiàn)在應(yīng)該不那么強調(diào)要兼容到iOS7了吧)
4.iOS8發(fā)布的時候痛倚,蘋果又推出了WKWebView,對之前的UIWebView進行了一次脫胎換骨的重構(gòu)(將UIWebView和UIWebViewDelegate重構(gòu)成了14個類和3個協(xié)議)澜躺,功能也更加完善和強大蝉稳,穩(wěn)定性和性能也明顯提高。
一掘鄙,方法互調(diào)(首先聲明的是無論如何互調(diào)耘戚,都需要兩邊配合的,有點像與后臺的交互)
1.1 oc 調(diào)用js方法
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
示例:
if (sender.tag == 234) {
[self.webView stringByEvaluatingJavaScriptFromString:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')"];
}
//參數(shù)無限制
直接oc調(diào)用js的函數(shù)代碼操漠,也是強悍收津!
對應(yīng)的js:
<html>
<!--描述網(wǎng)頁信息-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>小黃</title>
<style>
.btn{height:40px; width:60%; padding: 0px 30px; background-color: #0071E7; border: solid 1px #0071E7; border-radius:5px; font-size: 1.2em; color: white}
</style>
<script>
//提供給OC調(diào)用JS的方法列表
function alertSendMsg(num,msg) {
alert('這是我的手機號:' + num + ',' + msg + '!!')
}
</script>
</head>
</html>
1.2 js調(diào)用oc 的方法(那就麻煩咯)
js那邊不麻煩,也就加個鏈接
<html>
<!--描述網(wǎng)頁信息-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>小黃</title>
<style>
.btn{height:40px; width:60%; padding: 0px 30px; background-color: #0071E7; border: solid 1px #0071E7; border-radius:5px; font-size: 1.2em; color: white}
</style>
<script>
//JS響應(yīng)方法列表
function btnClick3() {
location.href = "rrcc://showSendNumber_msg_?13300001111&go climbing this weekend"
}
</script>
</head>
<!--網(wǎng)頁具體內(nèi)容-->
<body>
<br/><br/>
<div>
<label>小黃:13300001111</label>
</div>
<br/><br/>
<div>
<button class="btn" type="button" onclick="btnClick3()">發(fā)短信給小紅</button>
</div>
</body>
</html>
ps:"_"用作OC方法名中冒號的替換(這個應(yīng)該是特殊字符的轉(zhuǎn)義吧)
麻煩的是oc這邊(其實就是對js傳過來的url進行處理浊伙,分解出方法名和參數(shù)撞秋,通過OC執(zhí)行選擇器(selector)方法,來實現(xiàn)嚣鄙,不過這種方式最多只能傳遞參數(shù)的個數(shù)為2個吻贿,如果需要多個參數(shù),可以從數(shù)據(jù)結(jié)構(gòu)的組織方面入手)
#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@",NSStringFromSelector(_cmd));
//OC調(diào)用JS是基于協(xié)議攔截實現(xiàn)的 下面是相關(guān)操作
NSString *absolutePath = request.URL.absoluteString;
NSString *scheme = @"rrcc://";
if ([absolutePath hasPrefix:scheme]) {
NSString *subPath = [absolutePath substringFromIndex:scheme.length];
if ([subPath containsString:@"?"]) {//1個或多個參數(shù)
if ([subPath containsString:@"&"]) {//多個參數(shù)
NSArray *components = [subPath componentsSeparatedByString:@"?"];
NSString *methodName = [components firstObject];
methodName = [methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"];
//這段處理后的methodName結(jié)果是@"showSendNumber:msg:"(為了利用OC執(zhí)行選擇器(selector)方法拗慨,來實現(xiàn))
SEL sel = NSSelectorFromString(methodName);
NSString *parameter = [components lastObject];
NSArray *params = [parameter componentsSeparatedByString:@"&"];
if (params.count == 2) {
if ([self respondsToSelector:sel]) {
//OC執(zhí)行選擇器(selector)方法關(guān)鍵是這一句了
[self performSelector:sel withObject:[params firstObject] withObject:[params lastObject]];
}
}
} else {//1個參數(shù)
NSArray *components = [subPath componentsSeparatedByString:@"?"];
NSString *methodName = [components firstObject];
methodName = [methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"];
SEL sel = NSSelectorFromString(methodName);
NSString *parameter = [components lastObject];
if ([self respondsToSelector:sel]) {
[self performSelector:sel withObject:parameter];
}
}
} else {//沒有參數(shù)
NSString *methodName = [subPath stringByReplacingOccurrencesOfString:@"_" withString:@":"];
SEL sel = NSSelectorFromString(methodName);
if ([self respondsToSelector:sel]) {
[self performSelector:sel];
}
}
}
return YES;
}
二廓八,內(nèi)容上的交互
就目前所知奉芦,oc 直接修改webview的內(nèi)容比較方便赵抢,但是,js 想直接修改oc 的界面內(nèi)容貌似不可以声功。(不知道是不是蘋果方面出于安全方面的考慮烦却,不給隨隨便便的一個網(wǎng)頁這種權(quán)限?)
2.1 oc 修改webView的內(nèi)容
這些操作先巴,貌似都是在這個delegate里進行的
// 網(wǎng)頁視圖加載完畢會調(diào)用代理的這個方法
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
2.1.1 取
首先必須強調(diào)的是除非有且僅有唯一的標(biāo)簽其爵,比如網(wǎng)頁只有一個<title></title>
那么就可以直接拿
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
//獲取URL
NSString *curURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
而有多個<div></div>確沒有標(biāo)示,是拿不了的(不過這種情況少吧祢恰)
2.1.2 改
//修改屬性值
NSString *js_result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('good')[0].color='red';"];
2.1.3 刪
NSString *str = @"document.getElementsByClassName('detail_btns2')[0].remove();";
[webView stringByEvaluatingJavaScriptFromString:str];
2.1.4
好像找不到“增”和“查”啊摩渺,擦~
最后
當(dāng)然也有一些封裝的庫,不過還是建議用蘋果提供的吧(JavaScriptCore)