WKWebView
JS调原生
- 引入
#import <WebKit/WebKit.h>
- 声明
@property (nonatomic, strong) WKWebView *webView;
- 当前控制器遵循协议
WKScriptMessageHandler
- webView
- (void)createUI {
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
configuration.userContentController = userContentController;
self.webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:configuration];
self.webView.backgroundColor = [UIColor cyanColor];
[self.view addSubview:self.webView];
}
- 解决移除script不走dealloc问题,这么做
#pragma mark -解决不走dealloc问题
//解决JS与原生交互时造成的循环引用
//self -> webView -> config -> userContentController -> self
// viewWillAppear:添加JS监听 viewWillDisappear:移除监听
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"jsToMobile"];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"jsToMobile"];
}
- 为了测试,导入一个简单的html本地文件
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=utf8">
<title>WKScriptMessageHandler</title>
<script language = "javascript">
//! 加载URL
function loadURL(url) {
window.location.href = url;
}
//! JS调用OC的
//邀请
function invite() {
window.webkit.messageHandlers.jsToMobile.postMessage('inviting_friends');
}
//礼物
function gift() {
window.webkit.messageHandlers.jsToMobile.postMessage('giftVoucher');
}
//贷款
function loan() {
window.webkit.messageHandlers.jsToMobile.postMessage('my_loan');
}
</script>
</head>
<body>
<h3>功能按钮</h3>
<button onclick = "invite()" style = "font-size: 18px;">邀请好友</button>
<button onclick = "gift()" style = "font-size: 18px;">礼物</button>
<button onclick = "loan()" style = "font-size: 18px;">贷款</button>
</body>
</html>
- 加载本地html
- (void)loadHtml {
NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"htm"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
- 实现WKScriptMessageHandler协议方法
#pragma mark -WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
/*
@interface WKScriptMessage : NSObject
@property (nonatomic, readonly, copy) id body;
@property (nullable, nonatomic, readonly, weak) WKWebView *webView;
@property (nonatomic, readonly, copy) WKFrameInfo *frameInfo;
@property (nonatomic, readonly, copy) NSString *name;
@property (nonatomic, readonly) WKContentWorld *world API_AVAILABLE(macos(11.0), ios(14.0));
@end
*/
/**
JS调用原生 方法:
window.webkit.messageHandlers.<#对象名#>.postMessage(<#参数#>)
*/
if ([message.name isEqualToString:@"jsToMobile"]) {
NSString *param = message.body;
NSString *title = @"";
if ([param isEqualToString:@"inviting_friends"]) {
title = @"Friends";
} else if ([param isEqualToString:@"giftVoucher"]) {
title = @"Gift";
} else if ([param isEqualToString:@"my_loan"]) {
title = @"Loan";
}
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:confirm];
[self presentViewController:alert animated:YES completion:nil];
}
}
- 调用
[self createUI];
[self loadHtml];
效果:
2021-09-28 16.44.55.gif
原生调JS
- (void)nativeCallJs {
/**
原生调用JS
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
*/
// 此处是设置需要调用的js方法以及将对应的参数传入,需要以字符串的形式
// 这里调js的invite方法
NSString *jsFounction = [NSString stringWithFormat:@"invite()"];
// 调用API方法
[self.webView evaluateJavaScript:jsFounction completionHandler:^(id object, NSError * _Nullable error) {
NSLog(@"obj:%@---error:%@", object, error);
}];
}
网友评论