前阵子遇到个需求,需要使用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);
}];