WKWebView的H5交互使用说明
2018-02-27 本文已影响0人
willianm
引言:苹果说了iOS 8.0和OS 10.10以后,使用WKWebView在App的内部添加网页的内容。不要再使用UIWebView或WebView了。下面就是WKWebView的使用干货。
1.导入需要的框架
#import <WebKit/WebKit.h>
2.准守相关的代理协议创建控件指定代理
@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
@property(nonatomic, strong) WKWebView *webView;
@end
- (void)viewDidLoad {
[super viewDidLoad];
//下文会给出file:///Users/your_name/Desktop/wktest.html的完整H5内容
NSURL *requestURL = [NSURL URLWithString:@"file:///Users/your_name/Desktop/wktest.html"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];
//使用WKView
_webView = [[WKWebView alloc] init];
[self.view addSubview:_webView];
_webView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
[_webView loadRequest:request];
}
3.实现相关的代理方法
3.1网页加载相关的代理方法
#pragma mark WKViewDelegateAbout;
//加载一个新的网页
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString *url= navigationAction.request.URL.absoluteString;
NSLog(@"%@",url);
if([url hasPrefix:@"https://itunes.apple.com/app/apple-store/"]){
NSURL *URL=[NSURL URLWithString:url];
NSDictionary *dict = [NSDictionary dictionary];
[[UIApplication sharedApplication]openURL:URL options:dict completionHandler:^(BOOL success) {
}];
decisionHandler(WKNavigationActionPolicyCancel);
}
decisionHandler(WKNavigationActionPolicyAllow);
}
//加载一个新的网页完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
}
//加载一个新的网页失败
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
{
}
3.2很多人会发现为什么H5里的alert()方法和confirm()方法在苹果手机里无法显示弹框,这是因为苹果把这两个方法作为代理由客户端来实现了需要添加如下代理方法
#pragma mark WKUIDelegate
//JS调用alert()函数的代理 不实现这个方法JS调用alert()方法无效
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alerController = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[alerController addAction:cancelAction];
[self presentViewController:alerController animated:YES completion:^{
completionHandler();
}];
}
//JS调用confirm()函数的代理,不实现这个方法JS调用confirm()无效
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
{
UIAlertController *alerController = [UIAlertController alertControllerWithTitle:@"需要确认" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//回传用户的确认结果
completionHandler(NO);
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//回传用户的确认结果
completionHandler(YES);
}];
[alerController addAction:cancelAction];
[alerController addAction:confirmAction];
[self presentViewController:alerController animated:YES completion:^{
}];
}
3.3实现H5调用OC需要的方法
a.我们有一个OC的方法
//被h5调用的方法
- (void)OCMeth:(id)object
{
NSDictionary *dict = (NSDictionary *)object;
//打印网页端传过来的参数值
NSLog(@"%@",dict);
}
b 向网页端注册这个方法(此方法多在网页加载完成后调用)
//注册被网页调用的OC方法
- (void)registBeCalledOCMeth{
//注册一个名字是OCMeth的函数(要和JS约定函数名和参数格式)
[_webView.configuration.userContentController addScriptMessageHandler:self name:@"OCMeth"];
}
c 实现网页端调用以后的代理方法
#pragma mark WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
if ([message.name isEqualToString:@"OCMeth"]) {
[self OCMeth:message.body];
}
}
3.4实现OC调用H5的函数(要和JS约定函数名和参数格式)
//去调用h5里面的方法
- (void)JSMeth{
[self.webView evaluateJavaScript:@"show(true)" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
}];
}
这样基本的主要功能就实现了下面是H5的完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" charset="utf-8" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minmum-scale=1.0, user-scalable=1.0">
<script>
function callOCMeth()
{
var par = JSON.stringify({"message":"www.baidu.com"}) //这里传了一个OC中的字典
window.webkit.messageHandlers.OCMeth.postMessage(par); //调用OC的share方法
}
function show(str){
if(str == true )
{
var hElement = document.querySelector("h1");
hElement.style.backgroundColor = "red";
}else
{
var hElement = document.querySelector("h1");
hElement.style.backgroundColor = "yellow";
}
}
function testAlertPanel()
{
alert("一条警告信息")
}
function testConfirmPanel()
{
var r = confirm("Press a button"); //弹出一个确认选择框
if(r == true)
{
var hElement = document.querySelector("h1");
hElement.style.backgroundColor = "green";
} else
{
var hElement = document.querySelector("h1");
hElement.style.backgroundColor = "red";
}
}
</script>
</head>
<body >
<div>
<button onclick="show()">
测试JS中JS函数互相调用
</button>
</div>
<div>
<button onclick="testConfirmPanel()">
弹出Confirm框
</button>
</div>
<div>
<button onclick="testAlertPanel()">
弹出Alert框
</button>
</div>
<div>
<button onclick="callOCMeth()">调用OC的方法</button>
</div>
<h1>颜色会随着用户的选择改变</h1>
</body>
</html>