JS调iOS方法
-
UIWebView Swift方法同理
- WebView代理中拦截Url跳转
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(@"%@", request.URL.absoluteString);
if ([request.URL.absoluteString containsString:@"https://www.hntzdzkj.com.cn/index.php?course-phone-course&csid="]) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
ViewController *vc = [[ViewController alloc] init];
vc.urlStr = request.URL.absoluteString;
[self.navigationController pushViewController:vc animated:YES];
});
return NO;
}
return YES;
}
-
WKWebView OC方法同理
WKWebView主要是依靠WKScriptMessageHandler协议类和WKUserContentController两个类:WKUserContentController对象负责注册JS方法,设置处理接收JS方法的代理,代理遵守WKScriptMessageHandler,实现捕捉到JS消息的回调方法。
- 添加代理 解决循环引用问题
class WeakScriptMessageDelegate: NSObject, WKScriptMessageHandler {
weak var delegate : WKScriptMessageHandler?
init(delegate:WKScriptMessageHandler) {
self.delegate = delegate
super.init()
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
self.delegate?.userContentController(userContentController, didReceive: message)
}
}
- 初始化
WKWebViewConfiguration
,注册一个name为call_ios的JS方法,设置处理接收JS方法的代理
lazy var wkConfig : WKWebViewConfiguration = {
let tempConfig = WKWebViewConfiguration.init()
tempConfig.allowsInlineMediaPlayback = false
tempConfig.userContentController.add(WeakScriptMessageDelegate.init(delegate: self as WKScriptMessageHandler), name: "call_ios")
if #available(iOS 9.0, *) {
tempConfig.allowsPictureInPictureMediaPlayback = true
}
return tempConfig
}()
注意:WKWebView初始化方法要注册WKWebViewConfiguration
配置
let tempWebView = WKWebView.init(frame: self.view.bounds, configuration: self.wkConfig)
- 遵循
WKScriptMessageHandler
代理,实现以下方法
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "call_ios" {
// 自定义方法 拦截跳转原生页面
self.pushToLogin()
}
}
iOS调JS方法 原生方法比较简单
-
UIWebView
首先从WebView中获取到JSContext对象,然后通过JSContext对象注入JS代码。
注意:该注入方法要放在WebView加载完成的方法中。
// webViewDidFinishLoad方法
// OC版 无参
NSString *textJS = [NSString stringWithFormat:@"call_ios()"];
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
[context evaluateScript:textJS];
// Swift版 传参
let context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext
let textJS = String(format: "call_ios('%@')", imageStr)
context.evaluateScript(textJS)
-
WKWebView
直接使用UIWebView的方法,会出现崩溃。因为WKWebView无法获取JSContext,H5布局和javascript是在另一个进程上处理的。
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key documentView.'
WKWebView的原生调JS方法很简单,只需要使用WKWebView提供的evaluateJavaScript
方法即可。
// OC
NSString *jsString = [NSString stringWithFormat:@"setAddress('%@')", @"JS参数"];
[self.webView evaluateJavaScript:jsString completionHandler:^(id _Nullable data, NSError * _Nullable error) {
}];
// Swift
let jsonStr = RBTool.convert(toJsonData: self?.jsonDic)!
let textJS = String(format: "setAddress('%@')", jsonStr)
self?.webView.evaluateJavaScript(textJS, completionHandler: { (item, error) in
})
至此,iOS原生与JS交互就掌握的差不多了!由于项目中用到了很多,每次交互的时候都要去网上查阅资料,所以在此总结了一下,希望能帮到你!
如有不对,请大家指教!