iOS JSとOCのインタラクション/JSとnativeの相互呼び出し
js呼び出しnative OCコード
第一のメカニズム
(1)最もよく使われるのは-(BOOL)webView:(UIWebView*)web View shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebView NavigationType)navigationTypeというUIWebViewエージェントメソッドでJSから送信されたリクエストをブロックし,約束されたリクエストであればローカルで実行すべきOCメソッドをトリガーする
よく使われる2つのシーンに遭遇しました.
(1.1)ページバッファロード中にこのshouldStartLoadWithRequest:複数の要求をブロックし、約束のキーワードを検索し、約束の要求をロックすればローカルOCをトリガーする
(1.2)ページにボタンカテゴリのフォーカス領域があり、トリガー要求をクリックし、shouldStartLoadWithRequest:リクエストを判断し、ローカルOCをトリガーする
例:html共有ボタン
<html>
<header>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">function shareClick() {
loadURL("iOS//:shareAction");// iOS
}
script>
header>
<body>
<h2> webView OC h2>
<button type="button" onclick="shareClick()"> button>
body>
html>
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *requestUrl = request.URL.absoluteString;
DLog(@" URL:%@",requestUrl);
//
if(![NSString isEmpty:requestUrl] && [requestUrl hasPrefix:@"hfmall://"])
{// "hfmall://" , json 64
NSRange range = [requestUrl rangeOfString:@"hfmall://"];
if (range.length > 0) {
NSString *shangpinId = [requestUrl substringFromIndex:range.length];
GoodsDetailViewController *detailVC = [[GoodsDetailViewController alloc] init];
detailVC.shangpin_id = shangpinId;
[self.navigationController pushViewController:detailVC animated:YES];
return NO; // NO
}
}
// UIWebView OC
//
NSRange range1 = [requestUrl rangeOfString:@"ios//:shareAction"];
if (range1.length != 0) {
[self share]; //
return NO;
}
//TODO:
return YES;//
}
第2のメカニズム
JavaScripCore
このフレームワークはiOS 7で始まり、jsとnative OCのオリジナルインタラクションを実現し、ヘッダファイル#importを追加することができます.
[webView loadRequest:request];リクエスト開始またはリクエスト完了後にjsコンテキストを取得
(1)js自由選択タイミング呼び出しnative端OCコード
html端子
<html>
<header>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function secondClick() {
iosHideBottomBar(' 1',' 2');// OC
}
script>
header>
<body>
<h2> js native OC h2>
<button type="button" onclick="secondClick()"> button>
body>
html>
// js
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"iosHideBottomBar"=^(){//@"iosHideBottomBar"はjsと約束して実行するメソッド名であり、jsはタイミング呼び出しnativeエンドOCコードを自由に選択できる
DLog(@"%@",[NSThread currentThread]);//現在のスレッドの印刷
NSArray *args = [JSContext currentArguments];// js iosHideBottomBar
for (JSValue *jsVal in args) {
DLog(@"%@", jsVal.toString);
}
__block JSContext *contextObject = context;
dispatch_async(dispatch_get_main_queue(), ^{
self.isShowLikeFooter = NO;
[self handleHiddenBottomBar];
NSString *jsString=@"xxxxx(' ')"; // js xxxxx
[contextObject evaluateScript:jsString];
});
};
// , UI XCode 8.0 5s 8.3
/**
2016-11-11 17:05:54.447 dailylife[4163:181210] {number = 7, name = (null)}
(lldb) po [NSThread currentThread]
{number = 1, name = main}
**/
:
:
a. js , OC , OC ,
b. js OC iosHideBottomBar JSContext webView js , js OC , ( ).
, webView , . , url , " " , ,
native OC js
webFinishLoad ,
(1)stringByEvaluatingJavaScriptFromString : webView
NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
@"document.title" js (js call native)
js title (native call js)
stringByEvaluatingJavaScriptFromString ,
oc js
: webview js , stringByEvaluatingJavaScriptFromString,
, , js
(2)
// context js
JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; \
NSString *jsString=@"iosHideBottomBar(' 1',' 2')"; // js iOS 1 2
[context evaluateScript:jsString];// oc js iosHideBottomBar
:
, ,
:
http://blog.devtang.com/2012/03/24/talk-about-uiwebview-and-phonegap/
http://www.jianshu.com/p/d19689e0ed83
:https://www.cnblogs.com/someonelikeyou/p/6054547.html