JS与OC交互(调用h5 action,返回回调callback)

878 阅读1分钟

前阵子遇到个需求,需要使用JS注入客户端本地的登录数据,去调用h5的jS方法,返回客户端想要的数据。这里封装了个辅助类,可以根据不同的action调用不同的方法

1.创建JSHandler辅助类,继承自NSObject,JSHandle.h方法如下

/// 多个webView需要自行初始化JSHander使用。
@interface JSHandler : NSObject<WKScriptMessageHandler>

@property (nonatomic, weak) WKWebView *webView;
@property (nonatomic, copy) NSMutableDictionary *JSCallbacks;

/// 初始化webView,设置JS登录监听
/// @param webView 传入需要响应动作的webview控件
/// @param callback 动作回调
+ (void)handlerJSLogin:(WKWebView *)webView onXXXClicked:(void (^)(id))callback;

/// 刷新JS变量值
/// @param userData 变量字符串,内容不能引起js语法错误
+ (void)refreshJSUserData:(NSString *)userData;

/// 移除web回调
+ (void)removeAllCallback;


2.初始化wkwebview,以及js变量

- (void)setWebView:(WKWebView *)webView {
    if (_webView == nil) {
        WKUserScript *usrScript = [[WKUserScript alloc] initWithSource:@"var xxx={};"
                                                         injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                      forMainFrameOnly:YES];
        [webView.configuration.userContentController addUserScript:usrScript];
    }
    _webView = webView;
}

3.添加调用Action和返回回调的callback

- (void)addAction:(NSString *)action onClicked:(void (^)(id))callback {
    assert(self.webView);
    NSString *jsToOCAction = [NSString stringWithFormat:@"JS注入代码",action,action];
    WKUserScript *usrScript = [[WKUserScript alloc] initWithSource:jsToOCAction
                                                     injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                  forMainFrameOnly:YES];
    [self.webView.configuration.userContentController addUserScript:usrScript];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:action];
    callback?[self.JSCallbacks setObject:callback forKey:action]:nil;
}

4.暴露方法,提供本地调用

注意这里仅支持单webview调用,如果是多个webview需要再次初始化

+ (void)handlerJSXXX:(WKWebView *)webView onXXXClicked:(void (^)(id))callback{
    //添加响应方法
    if([JSHandler shareInstance].webView&&[JSHandler shareInstance].webView != webView) NSLog(@"Warning:单例会覆盖之前webView响应");
    [JSHandler shareInstance].webView = webView;
    [[JSHandler shareInstance] addAction:@"XXXX" onClicked:callback];
}

5.VC调用实例

 [JSHandler handlerJSXXX:self.wkWebView onLoginClicked:^(id _Nonnull args) {
        
    //跳转动作或其他处理 args可以是h5返回的参数
    NSLog(@"%@",args);
        
 }];