iOSとJavaScriptの相互作用
10491 ワード
方案一:伝統的なインタラクション
利点:ページのロードが完了するまで待つ必要はなく、該当するコードが実行されるとOCを呼び出すことができる方法(JavaScripptCoreと比較して)欠点:文字列を複雑に説明して対応する方法名と送信値を得る必要があり、呼び出しの方法もリターン値を伝えることができません.
1、OC呼び出しJS
webViewブロックurlリンクは、カスタムプロトコルの内容を取得し、結果を処理します.
利点:アップルの公式フレームは、シンプルで効率的です.短所:OC JSの呼び出しは、HTMLのロードが完了するまで待つ必要があります.
1、OC呼び出しJS
WebView JavascriptBridgeはUID WeViewとWKWebViewを同時にサポートしています.JSがOCを呼び出しても、OCがJSを呼び出しても、正常な値と戻り値ができます.また、ページにロードする時はJSコードが実行されている限り、相互作用ができます.上記の2つの案の欠点がないので、今は相互作用を処理する主流のやり方です.
利点:ページのロードが完了するまで待つ必要はなく、該当するコードが実行されるとOCを呼び出すことができる方法(JavaScripptCoreと比較して)欠点:文字列を複雑に説明して対応する方法名と送信値を得る必要があり、呼び出しの方法もリターン値を伝えることができません.
1、OC呼び出しJS
stringByEvaluatingJavaScriptFromString
方法を使用して、javascriptをページに埋め込むことができます.UICWebViewのページの読み込みが完了したら呼び出す必要があります.- (void)viewDidLoad{
[super viewDidLoad];
webview.backgroundColor = [UIColor clearColor];
webview.scalesPageToFit =YES;
webview.delegate =self;
NSURL *url =[[NSURL alloc] initWithString:@"https://www.google.com.hk"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[webview loadRequest:request];
}
//1、OC JS , webViewDidFinishLoad javascript
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//1.1、 url
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
//1.2、 title
NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
//1.3、 ( google :“Terence” 。)
NSString *js_result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName('q')[0].value='Terence';"];
//1.4、
NSString *js_result2 = [webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "];
//1.5、 js ( js , , :)
// a、 js script ,type 'text/javascript'。
// b、 , :myFunction, google 。
// c、 stringByEvaluatingJavaScriptFromString myFunction 。
[webView stringByEvaluatingJavaScriptFromString:
@"var script = document.createElement('script');"
"script.type = 'text/javascript';"
"script.text = \"function myFunction() { "
"var field = document.getElementsByName('q')[0];"
"field.value='Terence';"
"document.forms[0].submit();"
"}\";"
"document.getElementsByTagName('head')[0].appendChild(script);"// head
];
[webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];
//2.1、 JS
[webView stringByEvaluatingJavaScriptFromString:@"clickme();"];
//2、OC JS
NSString *value = @“ ”;
[self.webView stringByEvaluatingJavaScriptFromString:@“transValue(‘%@‘)”,value];
}
html
function clickme() {
alert(' !');
}
function transValue(insert) {
alert(insert);
}
OC JS
2、JS呼び出しOCwebViewブロックurlリンクは、カスタムプロトコルの内容を取得し、結果を処理します.
//JS
function sendToOC(){
var para1 = document.getElementById("element1").value;
var para2 = document.getElementById("element2").value;
// "gallery://" ;para1¶2 OC , ","
var url = "gallery://"+para1+","+para2;
document.loc ation = url;
}
// UIWebViewDelegate 。
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
// url
NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding];
// url "gallery://"
if ([requestStr hasPrefix:@"gallery://"]) {
// "://" url , arr
NSArray *arr = [requestStr componentsSeparatedByString:@"://"];
//
NSString *paramStr = arr[1];
// "," url ,
NSArray *paraArray = [paramStr componentsSeparatedByString:@","];
// ,
if (paraArray.count) {
NSLog(@" ");
[self doSomeThingWithParamA:paraArray[0] andParamB:paraArray[1]];
}else{
NSLog(@" ");
}
return NO;
}
return YES;
}
// JS
- (void)doSomeThingWithParamA:(id)paramA andParamB:(id)paramB{
NSLog(@"para1:%@--para2:%@", paramA, paramB);
}
案二:JavaScriptCore.framework
フレーム利点:アップルの公式フレームは、シンプルで効率的です.短所:OC JSの呼び出しは、HTMLのロードが完了するまで待つ必要があります.
1、OC呼び出しJS
//
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
// JSContext ( webView jscontext)
JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// js
NSString *alertJS=@"alert('test')";
// oc js alert( webview , js )
[context evaluateScript:alertJS];
}
2、JS呼び出しOC#import
-(void)webViewDidFinishLoad:(UIWebView *)webView{
// 1.
JSContext *jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 2.
jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@" :%@", exceptionValue);
};
// 3. (sendFunc,sendParam JS )
//
jsContext[@"sendFunc"] = ^{
NSArray *args = [JSContext currentArguments];
for (id obj in args){
NSLog("parameter:%@",obj);
}
}
//
jsContext[@"sendParam"] = ^(NSDictionary *dic){
NSLog("params:%@",dic);
}
}
// jsendToOC js , args js , js oc 。
jsコード:function onClick(){
var para1 = document.getElementById("element1").value;
var para2 = document.getElementById("element2").value;
sendFunc(para1,para2);
}
//
OC , click , sendToOC 。
案3:WebViewJavascriptBridge
第三のフレーム(githubアドレス)WebView JavascriptBridgeはUID WeViewとWKWebViewを同時にサポートしています.JSがOCを呼び出しても、OCがJSを呼び出しても、正常な値と戻り値ができます.また、ページにロードする時はJSコードが実行されている限り、相互作用ができます.上記の2つの案の欠点がないので、今は相互作用を処理する主流のやり方です.
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
setupWebViewJavascriptBridge(function (bridge){
//OC JS 'wevViewJSHandler' ;'data' OC ;'responseCallback' JS OC
bridge.registerHandler('webViewJSHandler', function(data, responseCallback) {
// OC
log('ObjC called wevViewJSHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
// , oc
responseCallback(responseData)
})
var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button'))
callbackButton.innerHTML = ' , oc '
callbackButton.onclick = function(e) {
e.preventDefault()
bridge.callHandler('loginAction', {'userId':'zhangsan','name': ' '}, function(response) {
// oc
alert(' oc :'+response)
})
}
})
}
#immport "WebViewJavascriptBridge.h"
-(void)viewDidLoad{
[super viewDidLoad];
//1. WebViewJavascriptBridge
if (_bridge) { return; }
[WebViewJavascriptBridge enableLogging]; // Bridge
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[_bridge setWebViewDelegate:self]; // bridge
// html, : h5 , oc
[self loadExamplePage:webView];
// js oc , ,h5 ,oc
[self JS2OC];
// :2 ,oc js
// : , html , oc ; ,webview request ( [self loadExamplePage:webView] [self OC2JS] , )
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self OC2JS];
});
}
//JS OC
-(void)JS2OC{
/*
:JS OC
@param registerHandler ( loginAction)
@param handel block block
*/
[_bridge registerHandler:@"loginAction" handler:^(id data, WVJBResponseCallback responseCallback) {
// data js ,
NSLog(@"JS OC, ");
// data
NSDictionary *dict = (NSDictionary *)data;
NSString *str = [NSString stringWithFormat:@" :%@ :%@",dict[@"userId"],dict[@"name"]];
[self renderButtons:str];
// responseCallback js
responseCallback(@" ,oc js ");
}];
}
//OC JS
-(void)OC2JS{
/*
:OC JS
@param callHandler ,
@param data id , ,
, callHandler 3 ,
*/
//[_bridge callHandler:@"registerAction" data:@" oc js "];
[_bridge callHandler:@"registerAction" data:@"uid:123 pwd:123" responseCallback:^(id responseData) {
NSLog(@"oc js :%@",responseData);
}];
}
:OC JS , 。