关键类
LeakAvoider.h
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface LeakAvoider : NSObject<WKScriptMessageHandler>
- (instancetype)initWithMessageHandler:(id <WKScriptMessageHandler>)messageHander;
@end
NS_ASSUME_NONNULL_END
LeakAvoider.m
#import "LeakAvoider.h"
@interface LeakAvoider ()
@property (nonatomic, weak) id <WKScriptMessageHandler> scriptDelegate;
@end
@implementation LeakAvoider
- (instancetype)initWithMessageHandler:(id <WKScriptMessageHandler>)messageHander {
if (self = [super init]) {
_scriptDelegate = messageHander;
}
return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if (self.scriptDelegate && [self.scriptDelegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
[self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
}
@end
使用方式
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WebVC : UIViewController
@end
NS_ASSUME_NONNULL_END
@interface WebVC ()<WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation WebVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
webView.customUserAgent = @"Mozilla/5.0 (iPad; CPU OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1";
webView.UIDelegate = self;
webView.navigationDelegate = self;
// [webView.configuration.userContentController addScriptMessageHandler:self name:@"Share"];
[webView.configuration.userContentController addScriptMessageHandler:[[LeakAvoider alloc] initWithMessageHandler:self] name:@"Share"];
[self.view addSubview:webView];
_webView = webView;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:content baseURL:nil];
// NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
// req.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
// [self.webView loadRequest:req];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@", message);
}
- (void)dealloc {
NSLog(@"%@ 销毁了", self);
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Share"];
}
@end
总结
1、addScriptMessageHandler时不要用self了
2、控制器中的dealloc方法中记得调用removeScriptMessageHandlerForName
附:用到的本地html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<script language="javascript">
//JS执行window.webkit.messageHandlers.Share.postMessage(<messageBody>)
function shareClick() {
window.webkit.messageHandlers.Share.postMessage({title:'测试分享的标题',content:'测试分享的内容',url:'https://github.com/maying1992'});
}
//分享回调结果显示
function shareResult(channel_id,share_channel,share_url) {
var content = channel_id+","+share_channel+","+share_url;
alert(content);
document.getElementById("returnValue").value = content;
}
//JS执行window.webkit.messageHandlers.Camera.postMessage(<messageBody>)
function cameraClick() {
window.webkit.messageHandlers.Camera.postMessage(null);
}
//调用相册回调结果显示
function cameraResult(result) {
alert(result);
document.getElementById("returnValue")/Users/zjt/Desktop/ceshiyinpin/ceshiyinpin/index.html.value = result;
}
</script>
</head>
<body>
<h1>这是按钮调用</h1>
<input type="button" value="分享" onclick="shareClick()" />
<input type="button" value="相机" onclick="cameraClick()" />
<h1>回调展示区</h1>
<textarea id ="returnValue" type="value" rows="5" cols="40">
</textarea>
<br/>
<font style="color:#666666"> 外部
<a style="text-decoration:none;color:red" href="https://www.baidu.com">百度一下</a>
</font>
</body>
</html>