WKWebView 基础使用
封装WebViewController 基类 包含WebView 的本地HTML、远程URL的加载;JS调用OC并传递参数以及OC调用JS并传递参数。
具体实现
webView 初始化
// 网页配置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
// 初始化网页视图
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
[self.view addSubview:self.webView];
weakSelf(self);
[self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(weakSelf.view);
}];
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
加载webView (根据传入的参数,判断是本地HTMT,还是远程网页)
// 加载webView
- (void)loadWebViewWithURL:(id)url {
NSURL *loadURL = nil;
// 对url进行检查
if (!url) {
return;
}
if ([url hasSuffix:@"html"]) { // 本地html
NSString *path = [[NSBundle mainBundle] pathForResource:url ofType:nil]; // 如果Bundle中没有该文件会返回nil
if (!path) {
NSLog(@"未查找到文件: %@",url);
return;
}
loadURL = [NSURL fileURLWithPath:path];
}
else if ([url isKindOfClass:[NSURL class]]) { // URL
loadURL = url;
}
else if ([url isKindOfClass:[NSString class]]) { // URL Stirng
[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
loadURL = [NSURL URLWithString:url];
}
else {
NSLog(@"格式错误:url- %@",url);
}
// 加载web页面
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:loadURL];
[self.webView loadRequest:request];
[KMProgerssHUD showHUDTitle:nil toView:self.view];
}
加载代理 WKUIDelegate WKNavigationDelegate
#pragma mark WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
NSLog(@"页面关闭");
}
#pragma mark WKNavigationDelegate
// 页面数据请求完成,开始加载网页到页面
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"当主框架的内容开始加载");
}
// 加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"加载完成");
}
// 加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
NSLog(@"加载失败");
}
JS和OC交互 写法
JS-->OC
Objective-C代码
页面注册JavaScript方法名 (tipFunc)
WKUserContentController *userContentControl = [[WKUserContentController alloc] init];
[userContentControl addScriptMessageHandler:self name:@"tipFunc"];
config.userContentController = userContentControl;
点击页面中的按钮,webView 回调
#pragma mark- WKScriptMessageHandler
// js调用 配置的jsMessage时的回调方法
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
}
JavaScript代码
html页面中点击按钮的事件调用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>E</title>
<script>
function clickFunc() {
var parmas = { "name": "chaman", "age": "18", "sex": "male"};
window.webkit.messageHandlers.tipFunc.postMessage(parmas);
}
</script>
</head>
<body>
<input type="button" value = "按钮" onclick = "clickFunc()"/>
</body>
</html>
OC-->JS
注意: 传参数格式一定要正确,并且一定要在页面加载完成后调用,否则会出现JavaScript异常错误
OC代码
/**
原生执行JavaScript方法 可以传参(如果为普通字符串要加 '',如果为JSON字符串不用)
例如:
NSArray *arr = @[@"A",@"A",@"A",@"A",@"A",@"A"];
NSData *data = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *javaScriptFunction = [NSString stringWithFormat:@"reportLoad(%@,%@)",jsonString,@"'abc'"];
@param JSFunctions 需要调用的参数
*/
- (void)evaluateJavaScript:(NSString *)JSFunction {
[self.webView evaluateJavaScript:JSFunction completionHandler:^(id _Nullable response, NSError * _Nullable error) {
if (!error) {
// 成功
NSLog(@"%@",response);
} else {
// 失败
NSLog(@"%@",error.localizedDescription);
}
}];
}
JS代码
<script>
function reportLoad(obj,theTitle) {
var a= obj;
var b = theTitle;
};
</script>
开发中遇到的问题:
Q: WKWebView加载本地HTML和CSS样式或者JavaScript时不起作用?
A: 主要原因是在本地的HTML中写了路径名称如:
<script src="EChartsDemo_files/hm_002.js"></script
加入到iOS bundle目录后,js不能识别,所以去掉路径(EChartsDemo_files/)即可<script src="hm_002.js"></script>
Q: 加载webView时报 Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service 日志?
A: 可能为script或者其他配置错误,导致加载不出来或者加载失败。
Q: 通过OC调用JS方法时,出现 JavaScript异常?
A: 一个可能是 OC中js方法格式错误,另一个可能为调用出现在web页面加载完成之前,或者其他低级错误,如:JS中未定义要调用的方法等。