WKWebView 的一些小总结

WKWebView 的一些小总结,第1张

概述WKWebView是  在iOS 8后推出要替代UIWebView。相对于成熟的UIWebView来讲,这个后生仔在使用上还是有点点小坑的~ 使用 在初始化上,WKWebView 和 UIWebView 没有多大的差异。 // WKWebViewlet wkWeb = WKWebView(frame: view.bounds)// 一些代理wkWeb.navigationDelegate

WKWebVIEw是  在iOS 8后推出要替代UIWebVIEw。相对于成熟的UIWebVIEw来讲,这个后生仔在使用上还是有点点小坑的~

使用

在初始化上,WKWebVIEwUIWebVIEw 没有多大的差异。

// WKWebVIEwlet wkWeb = WKWebVIEw(frame: vIEw.bounds)// 一些代理wkWeb.navigationDelegate = selfwkWeb.uIDelegate = self// UIWebVIEwlet web = UIWebVIEw(frame: vIEw.bounds)// 一些代理web.delegate = self

二者在初始化上还是蛮像的。一个图样的我。(逃

仔细翻开了WKWebVIEw,发现其还提供一个初始化方法。

public init(frame: CGRect,configuration: WKWebVIEwConfiguration)

也就是可以用WKWebVIEwConfigurationinit一个WKWebVIEw

后面再继续港 WKWebVIEwConfiguration

那几个协议 WKNavigationDelegate

WKNavigationDelegate的协议方法还是挺多的。

// 1)接受网页信息,决定是否加载还是取消。必须执行肥调 decisionHandler 。逃逸闭包的属性func webVIEw(_ webVIEw: WKWebVIEw,decIDePolicyFor navigationAction: WKNavigationAction,decisionHandler: @escaPing (WKNavigationActionPolicy) -> VoID) {    print("\(#function)")}// 2) 开始加载func webVIEw(_ webVIEw: WKWebVIEw,dIDStartProvisionalNavigation navigation: WKNavigation!) {    print("\(#function)")}// 3) 接受到网页 response 后,可以根据 statusCode 决定是否 继续加载。allow or cancel,必须执行肥调 decisionHandler 。逃逸闭包的属性func webVIEw(_ webVIEw: WKWebVIEw,decIDePolicyFor navigationResponse: WKNavigationResponse,decisionHandler: @escaPing (WKNavigationResponsePolicy) -> VoID) {    print("\(#function)")   guard let httpResponse = navigationResponse.response as? httpURLResponse else {        decisionHandler(.allow)        return    }        let policy : WKNavigationResponsePolicy = httpResponse.statusCode == 200 ? .allow : .cancel    decisionHandler(policy)        }// 4) 网页加载成功 func webVIEw(_ webVIEw: WKWebVIEw,dIDFinish navigation: WKNavigation!) {    print("\(#function)")}// 4) 加载失败func webVIEw(_ webVIEw: WKWebVIEw,dIDFail navigation: WKNavigation!,withError error: Error) {    print("\(#function)")   print(error.localizedDescription)}
WKUIDelegate

主要讲讲网页Js的一些函数——

alert()

comfirm()

prompt()

UIWebVIEw中,Js使用上述三个函数,是可以成功d出的。但是在WKWebVIEw中,使用着三个函数,是不会用任何反应的。原因是,把这三个函数都分别封装到WKUIDelegate的方法中。但Js使用这些函数时,那么客户端会在以下几个协议方法中,监测到发送过来的信息,然后需要用原生代码去实现一个alert。累cry~~~

// MARK: alertfunc webVIEw(_ webVIEw: WKWebVIEw,runJavaScriptAlertPanelWithMessage message: String,initiatedByFrame frame: WKFrameInfo,completionHandler: @escaPing () -> VoID) {    let alert = UIAlertController(Title: "这是本地代码d窗",message: message,preferredStyle: .alert)    lert.addAction(UIAlertAction(Title: "ok",style: .cancel,handler: { _ in            // 必须加入这个 肥调,不然会闪 (逃        completionHandler()  }))    present(alert,animated: true,completion: nil)}    // MARK: comfirmfunc webVIEw(_ webVIEw: WKWebVIEw,runJavaScriptConfirmPanelWithMessage message: String,completionHandler: @escaPing (Bool) -> VoID) {    let alert = UIAlertController(Title: "这是本地代码d窗",preferredStyle: .alert)    alert.addAction(UIAlertAction(Title: "❤️",style: .default,handler: { _ in        completionHandler(true)    }))    alert.addAction(UIAlertAction(Title: "不❤️",handler: { _ in        completionHandler(false)    }))    present(alert,completion: nil)}    // MARK: promptfunc webVIEw(_ webVIEw: WKWebVIEw,runJavaScriptTextinputPanelWithPrompt prompt: String,defaultText: String?,completionHandler: @escaPing (String?) -> VoID) {        let alert = UIAlertController(Title: "这是本地代码d窗",message: prompt,preferredStyle: .alert)    alert.addTextFIEld { textFIEld in        textFIEld.placeholder = defaultText    }    alert.addAction(UIAlertAction(Title: "ok",handler: { _ in        completionHandler(alert.textFIElds?.last?.text)    }))    present(alert,completion: nil)    }
踩坑 网页适配

有些网页在客户端上显示,会出现一些不适配的情况。使用UIWebVIEw的话,我们可以用使用其的scaletoFit属性。即webVIEw.scaletoFit = true。但是在WKWebVIEw里,并没有这个属性,我们只能使用到Js注入进行修改。

// 这句相当于给网页注入一个 <Meta> 标签,<Meta name="vIEwport" content="wIDth=device-wIDth">let JsToScaleFit = "var Meta = document.createElement('Meta'); Meta.setAttribute('name','vIEwport'); Meta.setAttribute('content','wIDth=device-wIDth'); document.getElementsByTagname('head')[0].appendChild(Meta);"let scaletoFitScript = WKUserScript(source: JsToScaleFit,injectionTime: .atdocumentEnd,forMainFrameOnly: true)        let userController = WKUserContentController()userController.addUserScript(scaletoFitScript)        let config = WKWebVIEwConfiguration()config.userContentController = userController        let wkWeb = WKWebVIEw(frame: vIEw.bounds,configuration: config!)

不过,还是不太推荐客户端去注入适配代码。最好还是告知前端,让他们去搞定这问题。个人觉得,两端少点干涉还是比较好滴~~~ (逃

客户端 -> 网页

有时间,我们需要客户端去调用前端的一些代码。e.g.

// 比如获取网页内容高度let JsToGetWebHeight = "document.body.offsetHeight"wkWeb?.evaluateJavaScript(JsToGetWebHeight,completionHandler: { (data,error) in    print(error?.localizedDescription ?? "执行正确")    // data 是一个 any 类型,因此需要做好类型判断    if let webHeight : CGfloat = data as? CGfloat {        print(webHeight)    }})
网页 -> 客户端

不像UIWebVIEwWKWebVIEw无法使用JaveSciptCore。我们需要使用到WKScriptMessageHandler这个协议去进行一系列交互。

首先,在初始化阶段,需要使用到WKWebVIEwConfiguration。放个文档注释先。

/*! @abstract Adds a script message handler.
@param scriptMessageHandler The message handler to add.
@param name The name of the message handler.
@discussion Adding a scriptMessageHandler adds a function window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all frames. */

open func add(_ scriptMessageHandler: WKScriptMessageHandler,name: String)

name是客户端自定义好的一个字符串类型的命名空间。可以有多个name。网页的Js代码,需要在进行交互的地方,使用上

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)

来发送消息。

上个栗子 总结

以上是内存溢出为你收集整理的WKWebView 的一些小总结全部内容,希望文章能够帮你解决WKWebView 的一些小总结所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1060309.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存