From 3a4670ad8f80fb377f4632de032fceab6fd39188 Mon Sep 17 00:00:00 2001 From: DouKing Date: Sat, 3 Apr 2021 13:36:37 +0800 Subject: [PATCH 1/3] support ios14 and promise --- .../project.pbxproj | 2 + STMScriptMessageHandler/Demo/index.html | 184 +++++++++++------- .../Source/STMScriptMessageHandler.h | 23 ++- .../Source/STMScriptMessageHandler.m | 53 ++++- .../Source/STMScriptMessageHandler_JS.h | 21 +- .../Source/STMScriptMessageHandler_JS.m | 53 +++-- .../Source/WKWebView+STMScriptMessage.h | 21 +- .../Source/WKWebView+STMScriptMessage.m | 30 ++- 8 files changed, 283 insertions(+), 104 deletions(-) diff --git a/STMScriptMessageHandler.xcodeproj/project.pbxproj b/STMScriptMessageHandler.xcodeproj/project.pbxproj index fac7e2e..cbec7e6 100644 --- a/STMScriptMessageHandler.xcodeproj/project.pbxproj +++ b/STMScriptMessageHandler.xcodeproj/project.pbxproj @@ -327,6 +327,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RQW526M45R; INFOPLIST_FILE = STMScriptMessageHandler/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -344,6 +345,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RQW526M45R; INFOPLIST_FILE = STMScriptMessageHandler/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/STMScriptMessageHandler/Demo/index.html b/STMScriptMessageHandler/Demo/index.html index b26964b..fb31012 100755 --- a/STMScriptMessageHandler/Demo/index.html +++ b/STMScriptMessageHandler/Demo/index.html @@ -1,75 +1,111 @@ - - - Demo - - - - - -
- + + + + + Demo + + + + + + + + + +
+ + + diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler.h b/STMScriptMessageHandler/Source/STMScriptMessageHandler.h index d8bebf9..4051018 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler.h +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler.h @@ -1,8 +1,25 @@ // // STMScriptMessageHandler.h -// Pods-STMWebViewController_Example // -// Created by DouKing on 2018/7/31. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // @import UIKit; @@ -13,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^STMResponseCallback)(id responseData); typedef void (^STMHandler)(id data, STMResponseCallback _Nullable responseCallback); -@interface STMScriptMessageHandler : NSObject +@interface STMScriptMessageHandler : NSObject @property (nonatomic, copy, readonly) NSString *handlerName; diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler.m b/STMScriptMessageHandler/Source/STMScriptMessageHandler.m index 56a3dad..7f7dcd1 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler.m +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler.m @@ -1,27 +1,39 @@ // // STMScriptMessageHandler.m -// Pods-STMWebViewController_Example // -// Created by DouKing on 2018/7/31. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "STMScriptMessageHandler.h" #import "STMScriptMessageHandler_JS.h" #define STM_JS_FUNC(x, ...) [NSString stringWithFormat:@#x ,##__VA_ARGS__] -#define WEAK_SELF __weak typeof(self) __weak_self__ = self -#define STRONG_SELF __strong typeof(__weak_self__) self = __weak_self__ - -static NSString * const kSTMApp = @"App"; -static NSString * const kSTMNativeCallback = @"nativeCallback"; -static NSString * const kSTMMethodHandlerReuseKey = @"kSTMMethodHandlerReuseKey"; -static NSString * const kSTMMethodHandlerIMPKey = @"kSTMMethodHandlerIMPKey"; static NSString * const kSTMMessageParameterNameKey = @"handlerName"; static NSString * const kSTMMessageParameterInfoKey = @"data"; static NSString * const kSTMMessageParameterResponseKey = @"responseData"; static NSString * const kSTMMessageParameterCallbackIdKey = @"callbackId"; static NSString * const kSTMMessageParameterResponseIdKey = @"responseId"; +static NSString * const kSTMMessageParameterResolveIdKey = @"resolveId"; +static NSString * const kSTMMessageParameterReplyKey = @"kSTMMessageParameterReplyKey"; static int gSTMCallbackUniqueId = 1; @@ -117,6 +129,19 @@ - (void)_flushReceivedMessage:(NSDictionary *)message { }; } else { responseCallback = ^(id responseData){ + if (!responseData) { + responseData = [NSNull null]; + } + void (^replyHandler)(id _Nullable reply, NSString *_Nullable errorMessage) = message[kSTMMessageParameterReplyKey]; + NSString *resolveId = message[kSTMMessageParameterResolveIdKey]; + if (replyHandler) { + replyHandler(responseData, nil); + } else if (resolveId) { + [self _dispatchMessage:@{ + kSTMMessageParameterResponseIdKey: resolveId, + kSTMMessageParameterResponseKey: responseData, + }]; + } }; } } @@ -192,6 +217,16 @@ - (void)userContentController:(WKUserContentController *)userContentController d [self _flushReceivedMessage:message.body]; } +- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message replyHandler:(void (^)(id _Nullable reply, NSString *_Nullable errorMessage))replyHandler API_AVAILABLE(macos(11.0), ios(14.0)) { + if (![message.name isEqualToString:self.handlerName]) { return; } + + NSMutableDictionary *parameters = [message.body mutableCopy]; + parameters[kSTMMessageParameterReplyKey] = replyHandler ?: ^(id _Nullable reply, NSString *_Nullable errorMessage){ + NSLog(@"reply handler is nil"); + }; + [self _flushReceivedMessage:parameters]; +} + #pragma mark - setter & getter - (NSMutableDictionary *)methodHandlers { diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.h b/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.h index 6ac24ef..0297d1b 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.h +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.h @@ -1,8 +1,25 @@ // // STMScriptMessageHandler_JS.h -// STMScriptMessageHandler // -// Created by DouKing on 2021/2/26. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.m b/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.m index e84d304..e84f42f 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.m +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler_JS.m @@ -1,14 +1,30 @@ // // STMScriptMessageHandler_JS.m -// STMScriptMessageHandler // -// Created by DouKing on 2021/2/26. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "STMScriptMessageHandler_JS.h" -// window.webkit.messageHandlers.bridge.postMessage() -// App = window.webkit.messageHandlers +// window.webkit.messageHandlers..postMessage() NSString * STMScriptMessageHandler_js(NSString *bridgeName) { #define __smhn_js_func__(x) #x @@ -47,19 +63,34 @@ function callHandler(handlerName, data, responseCallback) { responseCallback = data; data = null; } - _doSend({ handlerName: handlerName, data: data }, responseCallback); + return _doSend({ handlerName: handlerName, data: data }, responseCallback); } + function disableJavscriptAlertBoxSafetyTimeout() { dispatchMessagesWithTimeoutSafety = false; } function _doSend(message, responseCallback) { - if (responseCallback) { - var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime(); - responseCallbacks[callbackId] = responseCallback; - message['callbackId'] = callbackId; - } - window.webkit.messageHandlers.WebViewJavascriptBridge.postMessage(message) + if (responseCallback) { + var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime(); + responseCallbacks[callbackId] = responseCallback; + message['callbackId'] = callbackId; + window.webkit.messageHandlers.WebViewJavascriptBridge.postMessage(message); + } else { + var promise = new Promise((resolve, reject) => { + var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime(); + responseCallbacks[callbackId] = resolve; + message['resolveId'] = callbackId; + + var p = window.webkit.messageHandlers.WebViewJavascriptBridge.postMessage(message); + if (p instanceof Promise) { + p.then(result => resolve(result), error => reject(error)); + delete responseCallbacks[callbackId]; + delete message['resolveId']; + } + }); + return promise; + } } function _dispatchMessageFromObjC(messageJSON) { diff --git a/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.h b/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.h index 608dd10..0250445 100644 --- a/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.h +++ b/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.h @@ -1,8 +1,25 @@ // // WKWebView+STMScriptMessage.h -// STMScriptMessageHandler // -// Created by DouKing on 2019/6/15. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "STMScriptMessageHandler.h" diff --git a/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.m b/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.m index d7c4889..6c787b8 100644 --- a/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.m +++ b/STMScriptMessageHandler/Source/WKWebView+STMScriptMessage.m @@ -1,8 +1,25 @@ // // WKWebView+STMScriptMessage.m -// STMScriptMessageHandler // -// Created by DouKing on 2019/6/15. +// Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // #import "WKWebView+STMScriptMessage.h" @@ -45,7 +62,14 @@ - (void)stm_addScriptMessageHandler:(__kindof STMScriptMessageHandler *)msgHandl - (void)_stm_addScriptMessageHandler:(__kindof STMScriptMessageHandler *)messageHandler { WKUserContentController *userContentController = self.configuration.userContentController; [userContentController removeScriptMessageHandlerForName:messageHandler.handlerName]; - [userContentController addScriptMessageHandler:messageHandler name:messageHandler.handlerName]; + if (@available(iOS 14.0, *)) { + [userContentController addScriptMessageHandlerWithReply:messageHandler + contentWorld:WKContentWorld.pageWorld + name:messageHandler.handlerName]; + } else { + [userContentController addScriptMessageHandler:messageHandler + name:messageHandler.handlerName]; + } } - (void)_stm_removeScriptMessageHandler:(__kindof STMScriptMessageHandler *)messageHandler { From 0be72ef91582f602a9426d19a2c64fd16757754b Mon Sep 17 00:00:00 2001 From: DouKing Date: Sat, 3 Apr 2021 16:23:56 +0800 Subject: [PATCH 2/3] add log --- .../Demo/STMViewController.m | 1 + .../Source/STMScriptMessageHandler.h | 2 ++ .../Source/STMScriptMessageHandler.m | 30 ++++++++++++------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/STMScriptMessageHandler/Demo/STMViewController.m b/STMScriptMessageHandler/Demo/STMViewController.m index a47cc72..0d78eab 100644 --- a/STMScriptMessageHandler/Demo/STMViewController.m +++ b/STMScriptMessageHandler/Demo/STMViewController.m @@ -24,6 +24,7 @@ @implementation STMViewController - (void)viewDidLoad { [super viewDidLoad]; + [STMScriptMessageHandler enableLog]; [self prepareScriptMessageHandler]; NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; [self.webView loadHTMLString:[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil] baseURL:nil]; diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler.h b/STMScriptMessageHandler/Source/STMScriptMessageHandler.h index 4051018..44b3335 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler.h +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler.h @@ -34,6 +34,8 @@ typedef void (^STMHandler)(id data, STMResponseCallback _Nullable responseCallba @property (nonatomic, copy, readonly) NSString *handlerName; ++ (void)enableLog; + + (instancetype)new NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithScriptMessageHandlerName:(NSString *)handlerName forWebView:(WKWebView *)webView; diff --git a/STMScriptMessageHandler/Source/STMScriptMessageHandler.m b/STMScriptMessageHandler/Source/STMScriptMessageHandler.m index 7f7dcd1..860be86 100644 --- a/STMScriptMessageHandler/Source/STMScriptMessageHandler.m +++ b/STMScriptMessageHandler/Source/STMScriptMessageHandler.m @@ -25,8 +25,6 @@ #import "STMScriptMessageHandler.h" #import "STMScriptMessageHandler_JS.h" -#define STM_JS_FUNC(x, ...) [NSString stringWithFormat:@#x ,##__VA_ARGS__] - static NSString * const kSTMMessageParameterNameKey = @"handlerName"; static NSString * const kSTMMessageParameterInfoKey = @"data"; static NSString * const kSTMMessageParameterResponseKey = @"responseData"; @@ -49,6 +47,9 @@ @interface STMScriptMessageHandler () @implementation STMScriptMessageHandler +static BOOL gSTMEnableLog = NO; ++ (void)enableLog { gSTMEnableLog = YES; } + - (instancetype)initWithScriptMessageHandlerName:(NSString *)handlerName forWebView:(WKWebView * _Nonnull)webView { self = [super init]; if (self) { @@ -98,6 +99,7 @@ - (void)callMethod:(NSString *)methodName parameters:(id)parameters responseHand //给 js 端发送消息 - (void)_dispatchMessage:(NSDictionary *)message { + [self _debug:@"SEND" parameters:message]; NSString *messageJSON = [self _formatParameters:message]; NSString* javascriptCommand = [NSString stringWithFormat:@"%@._handleMessageFromObjC('%@');", self.handlerName, messageJSON]; [self _evaluateJavaScript:javascriptCommand]; @@ -108,7 +110,8 @@ - (void)_flushReceivedMessage:(NSDictionary *)message { if (![message isKindOfClass:NSDictionary.class]) { return; } - + [self _debug:@"RECEIVE" parameters:message]; + NSString *responseId = message[kSTMMessageParameterResponseIdKey]; if (responseId) { STMResponseCallback responseCallback = self.jsResponseHandlers[responseId]; @@ -135,6 +138,7 @@ - (void)_flushReceivedMessage:(NSDictionary *)message { void (^replyHandler)(id _Nullable reply, NSString *_Nullable errorMessage) = message[kSTMMessageParameterReplyKey]; NSString *resolveId = message[kSTMMessageParameterResolveIdKey]; if (replyHandler) { + [self _debug:@"SEND" parameters:responseData]; replyHandler(responseData, nil); } else if (resolveId) { [self _dispatchMessage:@{ @@ -170,7 +174,7 @@ - (void)_evaluateJavaScript:(NSString *)javaScriptString { [self.webView evaluateJavaScript:javaScriptString completionHandler:^(id _Nullable info, NSError * _Nullable error) { __strong typeof(__weak_self__) self = __weak_self__; if (error) { - NSLog(@"Error: %@", error); + [self _log:[NSString stringWithFormat:@"Error: %@", error]]; [self.webView reload]; } }]; @@ -185,9 +189,9 @@ - (void)_evaluateJavaScript:(NSString *)javaScriptString { } - (NSString *)_formatParameters:(NSDictionary *)parameters { - NSString *formatParameter = nil;; + NSString *formatParameter = nil; if ([NSJSONSerialization isValidJSONObject:parameters]) { - NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil]; + NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil]; formatParameter = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } else { formatParameter = parameters.description; @@ -203,10 +207,16 @@ - (NSString *)_formatParameters:(NSDictionary *)parameters { return formatParameter; } -- (void)_debug:(NSString *)name method:(NSString *)method parameters:(NSDictionary *)parameters { +- (void)_debug:(NSString *)action parameters:(NSDictionary *)parameters { +#ifdef DEBUG + if (!gSTMEnableLog) { return; } + NSLog(@"[%@] %@: %@", self.handlerName, action, parameters); +#endif +} + +- (void)_log:(NSString *)message { #ifdef DEBUG - NSString *debug = STM_JS_FUNC([%@] %@: %@, name, method, parameters); - NSLog(@"%@", debug); + NSLog(@"[%@] %@", self.handlerName, message); #endif } @@ -222,7 +232,7 @@ - (void)userContentController:(WKUserContentController *)userContentController d NSMutableDictionary *parameters = [message.body mutableCopy]; parameters[kSTMMessageParameterReplyKey] = replyHandler ?: ^(id _Nullable reply, NSString *_Nullable errorMessage){ - NSLog(@"reply handler is nil"); + [self _log:@"reply handler is nil"]; }; [self _flushReceivedMessage:parameters]; } From 5474c58dedf05e415457b4c2e92cfb7a1186f7bd Mon Sep 17 00:00:00 2001 From: DouKing Date: Sat, 3 Apr 2021 17:15:31 +0800 Subject: [PATCH 3/3] edit README --- LICENSE.MIT | 2 +- LICENSE.NPL | 2 +- README.md | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/LICENSE.MIT b/LICENSE.MIT index 83887ce..9d1819a 100644 --- a/LICENSE.MIT +++ b/LICENSE.MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 DouKing +Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LICENSE.NPL b/LICENSE.NPL index b821c88..c33446c 100644 --- a/LICENSE.NPL +++ b/LICENSE.NPL @@ -1,4 +1,4 @@ -Copyright (c) 2019 DouKing +Copyright (c) 2021-2025 DouKing (https://github.com/DouKing/) "Anti 996" License Version 1.0 (Draft) diff --git a/README.md b/README.md index 955e3ff..e7c8f41 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,15 @@ # STMScriptMessageHandler -![capture](./Capture.gif) + +The `STMScriptMessageHandler` is used to comunicate with js for `WKWebView`. It implements `WKScriptMessageHandler` and `WKScriptMessageHandlerWithReply` protocol. A `STMScriptMessageHandler` corresponding a js object. When your `WKWebView` add a `STMScriptMessageHandler`, the js side add a object on the window automatically. The handlerName of `STMScriptMessageHandler` is the js object's name. -The `STMScriptMessageHandler` is used to comunicate with js for `WKWebView`. It implements `WKScriptMessageHandler` protocol. A `STMScriptMessageHandler` corresponding a js object. When your `WKWebView` add a `STMScriptMessageHandler`, the js side add a object automatically. The handlerName of `STMScriptMessageHandler` is the js object's name. +## Features +- [x] Support multi message handlers +- [x] Support Promise +- [x] Compatible with `WebViewJavascriptBridge` ## Requirements @@ -15,7 +19,7 @@ iOS 8.0+ ## Usage -- Native side +#### Native side ```objectivec @@ -33,12 +37,12 @@ STMScriptMessageHandler *page = [[STMScriptMessageHandler alloc] initWithScriptM ``` -- JS side +#### JS side ```javascript // Use js object `window.Bridge` call native method or register method for native. -window.Bridge.callMethod('testNativeMethod', {foo:'foo1', bar: 'bar1'}, function(data){ - log('JS got native `testNativeMethod` response', data); +window.Bridge.callHandler('nslog', data, function (data) { + log('JS got native `nslog` response', data); }); window.Bridge.registerMethod('log', function(data, callback){ @@ -46,7 +50,29 @@ window.Bridge.registerMethod('log', function(data, callback){ log('Native calling js method `log`', message); callback({key: 'from js', value: 'something'}); }); - + +// Support Promise +async function promise(data) { + // window.Bridge.callHandler('nslog', data).then( + // result => log('JS got native `nslog` response', result), + // error => log('JS got native `nslog` error', error) + // ) + + var p = window.Bridge.callHandler('nslog', data); + var result = await p; + log('JS got native `nslog` response', result); +} +``` + +#### Migrate from `WebViewJavascriptBridge` + +If you register a message handler named `WebViewJavascriptBridge` at native side, the js side dones not need modify any code. + +```objectivec + +// The bridge's name is `WebViewJavascriptBridge` +self.bridge = [self.webView stm_addScriptMessageHandlerUseName:@"WebViewJavascriptBridge"]; + ``` ## Installation