您的位置:首页 > 移动开发

WKwebview 学习

2020-03-05 08:47 776 查看

<!doctype html>





WKWebview学习

WKWebview学习

WKWebView 是苹果在 iOS 8 中引入的新组件,目的是给出一个新的高性能的 Web View 解决方案,摆脱过去 UIWebView 的老旧笨重特别是内存占用量巨大的问题。

  1. 稳定、功能强大;
  2. 支持更多的H5;
  3. KVO;
  4. 支持高达 60 fps 的滚动刷新率,内置了手势探测;
  5. 14个类和3个协议

创建WKWebView

引入WebKit框架,首先配置WKWebView与网页交互的配置项WKWebViewConfiguration;

// 创建一个webiview的配置项
let configuretion = WKWebViewConfiguration()
//将TEST的ScriptMessageHandler注册到webiview的配置项中,这样在js中就可以向native传值     configuretion.userContentController.addScriptMessageHandler(self, name: "TEST")

初始化并配置WKWebView对象;

self.webview = WKWebView(frame: self.view.frame, configuration: configuretion)
self.webview.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.baidu.com/")!))
self.view.addSubview(self.webview)

WKWebView的三个代理

WKNavigationDelegate:与页面导航加载相关

1、该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。

// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;

2、页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)

// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;

WKUIDelegate:与JS交互时的ui展示相关:三种提示框;

/**
*  web界面中有弹出警告框时调用
*
*  @param webView           实现该代理的webview
*  @param message           警告框中的内容
*  @param frame             主窗口
*  @param completionHandler 警告框消失调用
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;

WKScriptMessageHandler:必须实现的方法,这个方法是提高App与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象

// 从web界面中接收到一个脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;

使用 Safari 自带的 Web View 调试工具

使用步骤,打开Safari偏好设置--》高级--》在菜单栏中先睡“开发”菜单(最下侧);

显示弹窗

在 UIWebView 里,js 的 alert() 弹窗会自动以系统弹窗的形式展示,但是 WKWebview 把这个接口也暴露给了我们,让我们自己 handle js 传来的 alert()。 在控制台中输入

alert(1)
即可调用native中的提示框。

func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void) {
let ac = UIAlertController(title: webView.title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
ac.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: { (aa) -> Void in
completionHandler()
}))
self.presentViewController(ac, animated: true, completion: nil)
}
}
网页向APP传数据、调用APP类方法

在初始化webview时已配置WKWebViewConfiguration;使用

window.webkit.messageHandlers.TEST.postMessage()
向APP传值;

苹果在 WKWebView 中的 js runtime 里事先注入了一个 window.webkit.messageHandlers.OOXX.postMessage() 方法,我们可以使用这个方法直接向 Native 层传值,异常方便

随便在控制台post一个数据便可在xcode控制台看到

//    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
//
//        print(message.name)
//        print(message.body.description)
//
//    }

传js对象(js 对象的 键 不用加双引号)

在safari控制台中传输js对象,

实现
:在APP中获取js对象,并根据对象内容,获取相应的类与该类中的方法。

window.webkit.messageHandlers.TEST.postMessage({className: "ClassName", functionName: "ClassFunc"})

实现WKScriptMessageHandler代理中的方法

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
//根据定义的key来判断message
if message.name == "TEST" {
//转换为字典,并获取key/value
if let dic = message.body as? NSDictionary,
className = dic["className"]?.description,
functionName = dic["functionName"]?.description {
//运行时获取指定类
if let cls = NSClassFromString(NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName")!.description + "." + className) as? NSObject.Type{
//初始化类对象并调用其方法
let obj = cls.init()
let functionSelector = Selector(functionName)
if obj.respondsToSelector(functionSelector) {
obj.performSelector(functionSelector)
} else {
print("方法未找到!")
}
} else {
print("类未找到!")
}
}
}
}

//创建类以供js调用
class ClassName: NSObject {
func ClassFuc() {
print("js调用APP类方法")
}
}
参考文档

WKWebView的新特性与使用

标哥的技术博客

吕文翰_JohnLui博客

转载于:https://www.cnblogs.com/OnNineMonkey/p/5405842.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
diejuehui0853 发布了0 篇原创文章 · 获赞 0 · 访问量 16 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: