oc 與js 的原生互動
總評:
oc 與js的互動,1.有原生的方式,oc 調js簡單,js調oc 麻煩(協議攔截"實現的互動方式)。
2.iOS7之前,蘋果沒有出 JavaScriptCore 之前,業界普遍採用開源庫WebViewJavascriptBridge和EasyJSWebView來解決的,原理都是基於攔截協議的封裝,
3.iOS7之後,蘋果針對JavaScript出了一個官方的庫JavaScriptCore,是Objective-C封裝了WebKit的JavaScript引擎,使我們可以脫離WebView執行JS程式碼。所以在iOS7之後想要實現互動,採用JavaScriptCore也是一種不錯的選擇,前提是你的專案不需要相容到iOS7之前(覺得現在應該不那麼強調要相容到iOS7了吧)
4.iOS8釋出的時候,蘋果又推出了WKWebView,對之前的UIWebView進行了一次脫胎換骨的重構(將UIWebView和UIWebViewDelegate重構成了14個類和3個協議),功能也更加完善和強大,穩定性和效能也明顯提高。
一,方法互調(首先宣告的是無論如何互調,都需要兩邊配合的,有點像與後臺的互動)
1.1 oc 呼叫js方法
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
示例:
if (sender.tag == 234) {
[self.webView stringByEvaluatingJavaScriptFromString:@"alertSendMsg('18870707070','週末爬山真是件愉快的事情')"];
}
//引數無限制
直接oc呼叫js的函式程式碼,也是強悍!
對應的js:
<html>
<!--描述網頁資訊-->
<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呼叫JS的方法列表
function alertSendMsg(num,msg) {
alert('這是我的手機號:' + num + ',' + msg + '!!')
}
</script>
</head>
</html>
1.2 js呼叫oc 的方法(那就麻煩咯)
js那邊不麻煩,也就加個連結
<html>
<!--描述網頁資訊-->
<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響應方法列表
function btnClick3() {
location.href = "rrcc://showSendNumber_msg_?13300001111&go climbing this weekend"
}
</script>
</head>
<!--網頁具體內容-->
<body>
<br/><br/>
<div>
<label>小黃:13300001111</label>
</div>
<br/><br/>
<div>
<button class="btn" type="button" onclick="btnClick3()">發簡訊給小紅</button>
</div>
</body>
</html>
ps:"_"用作OC方法名中冒號的替換(這個應該是特殊字元的轉義吧)
麻煩的是oc這邊(其實就是對js傳過來的url進行處理,分解出方法名和引數,通過OC執行選擇器(selector)方法,來實現,不過這種方式最多隻能傳遞引數的個數為2個,如果需要多個引數,可以從資料結構的組織方面入手)
#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@",NSStringFromSelector(_cmd));
//OC呼叫JS是基於協議攔截實現的 下面是相關操作
NSString *absolutePath = request.URL.absoluteString;
NSString *scheme = @"rrcc://";
if ([absolutePath hasPrefix:scheme]) {
NSString *subPath = [absolutePath substringFromIndex:scheme.length];
if ([subPath containsString:@"?"]) {//1個或多個引數
if ([subPath containsString:@"&"]) {//多個引數
NSArray *components = [subPath componentsSeparatedByString:@"?"];
NSString *methodName = [components firstObject];
methodName = [methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"];
//這段處理後的methodName結果是@"showSendNumber:msg:"(為了利用OC執行選擇器(selector)方法,來實現)
SEL sel = NSSelectorFromString(methodName);
NSString *parameter = [components lastObject];
NSArray *params = [parameter componentsSeparatedByString:@"&"];
if (params.count == 2) {
if ([self respondsToSelector:sel]) {
//OC執行選擇器(selector)方法關鍵是這一句了
[self performSelector:sel withObject:[params firstObject] withObject:[params lastObject]];
}
}
} else {//1個引數
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 {//沒有引數
NSString *methodName = [subPath stringByReplacingOccurrencesOfString:@"_" withString:@":"];
SEL sel = NSSelectorFromString(methodName);
if ([self respondsToSelector:sel]) {
[self performSelector:sel];
}
}
}
return YES;
}
二,內容上的互動
就目前所知,oc 直接修改webview的內容比較方便,但是,js 想直接修改oc 的介面內容貌似不可以。(不知道是不是蘋果方面出於安全方面的考慮,不給隨隨便便的一個網頁這種許可權?)
2.1 oc 修改webView的內容
這些操作,貌似都是在這個delegate裡進行的
// 網頁檢視載入完畢會呼叫代理的這個方法
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
}
2.1.1 取
首先必須強調的是除非有且僅有唯一的標籤,比如網頁只有一個<title></title>
那麼就可以直接拿
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
//獲取URL
NSString *curURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
而有多個<div></div>確沒有標示,是拿不了的(不過這種情況少啊)
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
好像找不到“增”和“查”啊,擦~
最後
當然也有一些封裝的庫,不過還是建議用蘋果提供的吧(JavaScriptCore)
相關文章
- OC WKWebView的JS與OC互動、Cookie管理WebViewJSCookie
- JS 與 OC 互動的三種方法JS
- oc 與 js互動之vue.jsVue.js
- Cordova JS OC互動方法JS
- JS原生互動JS
- WebViewJavascriptBridge JS和OC互動WebViewJavaScriptJS
- iOS開發:網頁JS與OC互動(JavaScriptCore)iOS網頁JSJavaScript
- HTML5接入與OC互動HTML
- iOS下JS與原生OC互相呼叫(總結)iOSJS
- swift3.0與OC的互動注意事項Swift
- OC與C++ 混編的檔案互動C++
- Flutter 與Native原生互動Flutter
- RN 與android原生互動Android
- webview與JS的互動WebViewJS
- Android 原生和 JS 互動實踐AndroidJS
- js 與WKWebView 互動JSWebView
- WKWebView與JS互動WebViewJS
- Android 原生 WebView 與 JavaScript 互動AndroidWebViewJavaScript
- 原生App與javascript互動之JSBridge介面原理、設計與實現APPJavaScriptJS
- js和原生應用常用的資料互動方式JS
- vue 與原生app的對接互動(混合開發)VueAPP
- RN與原生互動(二)——資料傳遞
- WKWebView和WebView與JS的互動方式WebViewJS
- ios/oc中的結構體 與字串互轉iOS結構體字串
- H5與安卓/IOS進行原生互動H5安卓iOS
- React native 與Android原生互動方式(一)React NativeAndroid
- WebView與JS的互動,以及注意事項WebViewJS
- Android webview 與 js(Vue) 互動AndroidWebViewJSVue
- iOS 與 JS 互動手冊 - JavaScriptCoreiOSJSJavaScript
- iOS 與JS Html常見互動iOSJSHTML
- angularjs與伺服器互動AngularJS伺服器
- Flutter與原生互動(安卓、iOS),實現原生分享 | 掘金技術徵文Flutter安卓iOS
- WKWebView與Js實戰(OC版)WebViewJS
- Flutter使用JsBridge與WebView互動FlutterJSWebView
- Flutter WebView與JS互動簡易指南FlutterWebViewJS
- flutter和Android原生互動FlutterAndroid
- jsp的互動性JS
- GraphQL.js 與服務端互動的新方式JS服務端