123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- //
- // WKWebViewJavascriptBridge.m
- //
- // Created by @LokiMeyburg on 10/15/14.
- // Copyright (c) 2014 @LokiMeyburg. All rights reserved.
- //
- #import "WKWebViewJavascriptBridge.h"
- #if defined supportsWKWebView
- @implementation WKWebViewJavascriptBridge {
- __weak WKWebView* _webView;
- __weak id<WKNavigationDelegate> _webViewDelegate;
- long _uniqueId;
- WebViewJavascriptBridgeBase *_base;
- }
- /* API
- *****/
- + (void)enableLogging { [WebViewJavascriptBridgeBase enableLogging]; }
- + (instancetype)bridgeForWebView:(WKWebView*)webView {
- WKWebViewJavascriptBridge* bridge = [[self alloc] init];
- [bridge _setupInstance:webView];
- [bridge reset];
- return bridge;
- }
- - (void)send:(id)data {
- [self send:data responseCallback:nil];
- }
- - (void)send:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
- [_base sendData:data responseCallback:responseCallback handlerName:nil];
- }
- - (void)callHandler:(NSString *)handlerName {
- [self callHandler:handlerName data:nil responseCallback:nil];
- }
- - (void)callHandler:(NSString *)handlerName data:(id)data {
- [self callHandler:handlerName data:data responseCallback:nil];
- }
- - (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
- [_base sendData:data responseCallback:responseCallback handlerName:handlerName];
- }
- - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
- _base.messageHandlers[handlerName] = [handler copy];
- }
- - (void)removeHandler:(NSString *)handlerName {
- [_base.messageHandlers removeObjectForKey:handlerName];
- }
- - (void)reset {
- [_base reset];
- }
- - (void)setWebViewDelegate:(id<WKNavigationDelegate>)webViewDelegate {
- _webViewDelegate = webViewDelegate;
- }
- - (void)disableJavscriptAlertBoxSafetyTimeout {
- [_base disableJavscriptAlertBoxSafetyTimeout];
- }
- /* Internals
- ***********/
- - (void)dealloc {
- _base = nil;
- _webView = nil;
- _webViewDelegate = nil;
- _webView.navigationDelegate = nil;
- }
- /* WKWebView Specific Internals
- ******************************/
- - (void) _setupInstance:(WKWebView*)webView {
- _webView = webView;
- _webView.navigationDelegate = self;
- _base = [[WebViewJavascriptBridgeBase alloc] init];
- _base.delegate = self;
- }
- - (void)WKFlushMessageQueue {
- [_webView evaluateJavaScript:[_base webViewJavascriptFetchQueyCommand] completionHandler:^(NSString* result, NSError* error) {
- if (error != nil) {
- NSLog(@"WebViewJavascriptBridge: WARNING: Error when trying to fetch data from WKWebView: %@", error);
- }
- [_base flushMessageQueue:result];
- }];
- }
- - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
- if (webView != _webView) { return; }
-
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishNavigation:)]) {
- [strongDelegate webView:webView didFinishNavigation:navigation];
- }
- }
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
- if (webView != _webView) { return; }
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) {
- [strongDelegate webView:webView decidePolicyForNavigationResponse:navigationResponse decisionHandler:decisionHandler];
- }
- else {
- decisionHandler(WKNavigationResponsePolicyAllow);
- }
- }
- - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
- if (webView != _webView) { return; }
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didReceiveAuthenticationChallenge:completionHandler:)]) {
- [strongDelegate webView:webView didReceiveAuthenticationChallenge:challenge completionHandler:completionHandler];
- } else {
- completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
- }
- }
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
- if (webView != _webView) { return; }
- NSURL *url = navigationAction.request.URL;
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
-
- if ([_base isWebViewJavascriptBridgeURL:url]) {
- if ([_base isBridgeLoadedURL:url]) {
- [_base injectJavascriptFile];
- } else if ([_base isQueueMessageURL:url]) {
- [self WKFlushMessageQueue];
- } else {
- [_base logUnkownMessage:url];
- }
- decisionHandler(WKNavigationActionPolicyCancel);
- return;
- }
-
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
- [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
- } else {
- decisionHandler(WKNavigationActionPolicyAllow);
- }
- }
- - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
- if (webView != _webView) { return; }
-
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) {
- [strongDelegate webView:webView didStartProvisionalNavigation:navigation];
- }
- }
- - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
- if (webView != _webView) { return; }
-
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) {
- [strongDelegate webView:webView didFailNavigation:navigation withError:error];
- }
- }
- - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
- if (webView != _webView) { return; }
-
- __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
- if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailProvisionalNavigation:withError:)]) {
- [strongDelegate webView:webView didFailProvisionalNavigation:navigation withError:error];
- }
- }
- - (NSString*) _evaluateJavascript:(NSString*)javascriptCommand {
- [_webView evaluateJavaScript:javascriptCommand completionHandler:nil];
- return NULL;
- }
- @end
- #endif
|