Нет описания

WKWebViewJavascriptBridge.m 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // WKWebViewJavascriptBridge.m
  3. //
  4. // Created by @LokiMeyburg on 10/15/14.
  5. // Copyright (c) 2014 @LokiMeyburg. All rights reserved.
  6. //
  7. #import "WKWebViewJavascriptBridge.h"
  8. #if defined supportsWKWebView
  9. @implementation WKWebViewJavascriptBridge {
  10. __weak WKWebView* _webView;
  11. __weak id<WKNavigationDelegate> _webViewDelegate;
  12. long _uniqueId;
  13. WebViewJavascriptBridgeBase *_base;
  14. }
  15. /* API
  16. *****/
  17. + (void)enableLogging { [WebViewJavascriptBridgeBase enableLogging]; }
  18. + (instancetype)bridgeForWebView:(WKWebView*)webView {
  19. WKWebViewJavascriptBridge* bridge = [[self alloc] init];
  20. [bridge _setupInstance:webView];
  21. [bridge reset];
  22. return bridge;
  23. }
  24. - (void)send:(id)data {
  25. [self send:data responseCallback:nil];
  26. }
  27. - (void)send:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
  28. [_base sendData:data responseCallback:responseCallback handlerName:nil];
  29. }
  30. - (void)callHandler:(NSString *)handlerName {
  31. [self callHandler:handlerName data:nil responseCallback:nil];
  32. }
  33. - (void)callHandler:(NSString *)handlerName data:(id)data {
  34. [self callHandler:handlerName data:data responseCallback:nil];
  35. }
  36. - (void)callHandler:(NSString *)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback {
  37. [_base sendData:data responseCallback:responseCallback handlerName:handlerName];
  38. }
  39. - (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
  40. _base.messageHandlers[handlerName] = [handler copy];
  41. }
  42. - (void)removeHandler:(NSString *)handlerName {
  43. [_base.messageHandlers removeObjectForKey:handlerName];
  44. }
  45. - (void)reset {
  46. [_base reset];
  47. }
  48. - (void)setWebViewDelegate:(id<WKNavigationDelegate>)webViewDelegate {
  49. _webViewDelegate = webViewDelegate;
  50. }
  51. - (void)disableJavscriptAlertBoxSafetyTimeout {
  52. [_base disableJavscriptAlertBoxSafetyTimeout];
  53. }
  54. /* Internals
  55. ***********/
  56. - (void)dealloc {
  57. _base = nil;
  58. _webView = nil;
  59. _webViewDelegate = nil;
  60. _webView.navigationDelegate = nil;
  61. }
  62. /* WKWebView Specific Internals
  63. ******************************/
  64. - (void) _setupInstance:(WKWebView*)webView {
  65. _webView = webView;
  66. _webView.navigationDelegate = self;
  67. _base = [[WebViewJavascriptBridgeBase alloc] init];
  68. _base.delegate = self;
  69. }
  70. - (void)WKFlushMessageQueue {
  71. [_webView evaluateJavaScript:[_base webViewJavascriptFetchQueyCommand] completionHandler:^(NSString* result, NSError* error) {
  72. if (error != nil) {
  73. NSLog(@"WebViewJavascriptBridge: WARNING: Error when trying to fetch data from WKWebView: %@", error);
  74. }
  75. [_base flushMessageQueue:result];
  76. }];
  77. }
  78. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  79. if (webView != _webView) { return; }
  80. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  81. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFinishNavigation:)]) {
  82. [strongDelegate webView:webView didFinishNavigation:navigation];
  83. }
  84. }
  85. - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
  86. if (webView != _webView) { return; }
  87. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  88. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) {
  89. [strongDelegate webView:webView decidePolicyForNavigationResponse:navigationResponse decisionHandler:decisionHandler];
  90. }
  91. else {
  92. decisionHandler(WKNavigationResponsePolicyAllow);
  93. }
  94. }
  95. - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
  96. if (webView != _webView) { return; }
  97. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  98. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didReceiveAuthenticationChallenge:completionHandler:)]) {
  99. [strongDelegate webView:webView didReceiveAuthenticationChallenge:challenge completionHandler:completionHandler];
  100. } else {
  101. completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
  102. }
  103. }
  104. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
  105. if (webView != _webView) { return; }
  106. NSURL *url = navigationAction.request.URL;
  107. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  108. if ([_base isWebViewJavascriptBridgeURL:url]) {
  109. if ([_base isBridgeLoadedURL:url]) {
  110. [_base injectJavascriptFile];
  111. } else if ([_base isQueueMessageURL:url]) {
  112. [self WKFlushMessageQueue];
  113. } else {
  114. [_base logUnkownMessage:url];
  115. }
  116. decisionHandler(WKNavigationActionPolicyCancel);
  117. return;
  118. }
  119. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
  120. [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
  121. } else {
  122. decisionHandler(WKNavigationActionPolicyAllow);
  123. }
  124. }
  125. - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
  126. if (webView != _webView) { return; }
  127. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  128. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) {
  129. [strongDelegate webView:webView didStartProvisionalNavigation:navigation];
  130. }
  131. }
  132. - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
  133. if (webView != _webView) { return; }
  134. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  135. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) {
  136. [strongDelegate webView:webView didFailNavigation:navigation withError:error];
  137. }
  138. }
  139. - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
  140. if (webView != _webView) { return; }
  141. __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;
  142. if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:didFailProvisionalNavigation:withError:)]) {
  143. [strongDelegate webView:webView didFailProvisionalNavigation:navigation withError:error];
  144. }
  145. }
  146. - (NSString*) _evaluateJavascript:(NSString*)javascriptCommand {
  147. [_webView evaluateJavaScript:javascriptCommand completionHandler:nil];
  148. return NULL;
  149. }
  150. @end
  151. #endif