序文
最近iOS7オープンJavaScriptCoreにおけるフレームワークで使用されるリンゴの側面と対話知識OCを開発JS以前に使用したのUIWebView JSのOCの側面と対話するために、プロジェクトで使用され、使用することは非常に便利な、JavaScriptCoreにおけるソースコードが興味を持って、開いていますあなたは見つけるために行くことができます。
iOS8以来、アップルのUIWebViewのパフォーマンスが良くありません、我々はWKWebViewを立ち上げ、そして最もWKWebViewを両立させWebViewJavascriptBridge最新バージョン内のgithubの上の高得点します。
達成する方法
だから、道の私の概要は、のUIWebView、WKWebView、およびサードパーティWebViewJavascriptBridgeジェネリック版を指して、実現されました。
- UIWebViewでJSのOCとの対話
- JS OCでWKWebView(のみiOS8およびそれ以降のバージョン)との対話
- UIWebViewのためWebViewJavascriptBridgeはWKWebViewプロセスに同意します。
WebViewJavascriptBridge
利点
本質的に同じを使用してWKWebViewのUIWebView
使用すると便利WebViewJavascriptBridge
AndroidのバージョンとiOS版WebViewJavascriptBridge、同じの実現とJSネイティブ相互作用は、何の両端が異なるコードに設定されていません
基本的な
OCとJSと通信するためにかなりの橋をWebViewJavascriptBridge。
JSをコールするようにOC方法は、ブリッジに登録されました。
JSブリッジへの登録方法、そのためOCを呼び出します。
下図のように誰が登録されていることは、と呼ばれるのを待っています。
手順を使用します
- インポートWebViewJavaScriptBridgeプロジェクトの枠組み
pod ‘WebViewJavascriptBridge’
- インポートヘッダファイル
#import <WebViewJavascriptBridge.h>
-
初期化WKWebView /のUIWebViewのプロキシ設定
それはのUIWebView UIWebViewDelegate設定されている場合
WKWebViewはその後WKNavigationDelegate、WKUIDelegateを設定した場合、
コードは以下の通りであります:
//初始化WKWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
webView.navigationDelegate = self;
webView.UIDelegate = self;
[self.view addSubview:webView];
//或者初始化UIWebView
UIWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
webView.delegate = self;
[self.view addSubview:webView];
- WebViewのにJSとOjbC間のブリッジを構築
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[self.bridge setWebViewDelegate:self];
- OC 2つのメソッドを登録し、JSコールウェイティング、responseCallback()の戻りjsのデータが通過しない場合があります
//registerHandler 注册,等着JS调用 responseCallback是返回js的数据
[self.bridge registerHandler:@"getUserIdFromObjC" handler:^(id data, WVJBResponseCallback responseCallback) {
if (responseCallback) {
responseCallback(@{@"userId":@"123456"});
}
}];
//js调用的这个方法不需要给js反馈数据
[self.bridge registerHandler:@"notReturnFromJS" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"data -- %@",data);
}];
- JSを呼び出し、イベントCLIK OnOCCallJSClickイベントを追加
- (void) OnOCCallJSClick:(id)sender {
//这种调用js方式,不需要js在给返回值
[self.bridge callHandler:@"getInfoFromJS" data:@{@"name":@"张三"}];
//callHandler 调用JS 这个方式是,调用js,js有返回值的话,responseData就是js返回的
[self.bridge callHandler:@"getInfoFromJS" data:@{@"name":@"张三"} responseCallback:^(id responseData) {
}];
}
- あなたは<SCRIPT> </ SCRIPT>内のHTMLを読み込むOC JSビルド橋を作ることができ、均一コードを記述する必要があります。
<script>
window.onerror = function(err) {
log('window.onerror: ' + err)
}
/*这段代码是固定的,必须要放到js中*/
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)
}
/*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/
setupWebViewJavascriptBridge(function(bridge) {
var uniqueId = 1
function log(message, data) {
var log = document.getElementById('log')
var el = document.createElement('div')
el.className = 'logLine'
el.innerHTML = uniqueId++ + '. ' + message + ':<br/>' + JSON.stringify(data)
if (log.children.length) {
log.insertBefore(el, log.children[0])
} else {
log.appendChild(el)
}
}
/* Initialize your app here */
/*我们在这注册一个js调用OC的方法,不带参数,
*且不用ObjC端反馈结果给JS:打开本demo对应的博文
*/
bridge.registerHandler('openWebviewBridgeArticle', function() {
confirm("郭杨和小代是好朋友吗?");
log("openWebviewBridgeArticle was called with by ObjC")
})
/*JS给ObjC提供公开的API,在ObjC端可以手动调用JS的这个API。
*接收ObjC传过来的参数,且可以回调ObjC
*/
bridge.registerHandler('getUserInfos', function(data, responseCallback) {
log("Get user information from ObjC: ", data)
responseCallback({'userId': '123456', 'blog': '标哥的技术博客'})
})
/*JS给ObjC提供公开的API,ObjC端通过注册,就可以在JS端调用此API时,得到回调。
*ObjC端可以在处理完成后,反馈给JS,这样写就是在载入页面完成时就先调用
*/
bridge.callHandler('getUserIdFromObjC', function(responseData) {
log("JS call ObjC's getUserIdFromObjC function, and js received response:", responseData)
})
})
</script>
JSはまた、この方法でOCを待って呼び出すための登録方法をregisterHandlerを持っています
JS callHandlerのように、OCのメソッドを呼び出すには
JS responseCallbackデータは、OC、OCは合格しない場合があります返さresponseCallbackは空です
注意を払います
あなたがWebViewJavascriptBridgeを達成するためにWKWebviewを使用している場合は、まだプロンプトポップアップボックスがブロックされたコールシステム、警報を、確認するので、私たちはネイティブの傍受後の三つの方法UIDelegateプロキシ、ポップポップアップボックスを実装する必要があります
#pragma mark - WKUIDelegate
//! alert(message)
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
//! confirm(message)
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Confirm" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}];
[alertController addAction:cancelAction];
[alertController addAction:confirmAction];
[self presentViewController:alertController animated:YES completion:nil];
}
//! prompt(prompt, defaultText)
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = defaultText;
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text);
}];
[alertController addAction:confirmAction];
[self presentViewController:alertController animated:YES completion:nil];
}
エンディング
より便利に使い、パスの一端限り、デバッグをAndroidのフロントエンドの両方を避けるだけでなく、iOS版と書かれたJSのOCの相互作用を記述するために、使用されているWebViewJavascriptBridge、すべてのAndroidとiOSのAndroidのバージョンがありますWebViewJavascriptBridge 、JSは、iOSとAndroidを使用すると、iOSのアンドリュースの問題を解決することがありさまざまな問題を持っているので、団結がより重要である、そこではない、問題には何もないはずなトラブルシューティングを容易にします。(一部が不十分ください批判や満足感を持っているとして、その後~~~賞賛を与えます)