第一节:WKWebView的一些处理

1、Cookie设置
1.1、在请求实例中设置cookie
extension URLRequest {
    mutating func setCookies(_ cookies: [String: Any]) {
        let cookieString = cookies.map { "\($0.key)=\($0.value)" }.joined(separator: ";")
        setValue(cookieString, forHTTPHeaderField: "Cookie")
    }
}
1.2、通过脚本设置cookie
extension WKUserScript {
    convenience init(cookie key: String, value: Any) {
        let domin: String = ".***" // ***为域名通用部分        
        let userScript = "document.cookie = '\(key)=\(value);path=/;domain=\(domin);expiresDate=\(Date(timeIntervalSinceNow: 2629743))'"
        self.init(source: userScript, injectionTime: .atDocumentStart, forMainFrameOnly: false)
    }
}

// 或
// 这种设置方式适合与webview已经加载完成,但是需要更新cookie的情况
func evaluateCookieJavaScript() {
    if let sid = NetworkingManager.manager.sid {
        let cookieString = "document.cookie = 'sid=\(sid);path=/;domain=.****;expiresDate=\(Date(timeIntervalSinceNow: 2629743))'"
        self.evaluateJavaScript(cookieString, completionHandler: nil)
    }
}
1.3、通过WKWebsiteDataStore设置cookie
extension HTTPCookie {
    convenience init?(name: String, value: String) {
        let domin: String = ".***"        
        let properties: [HTTPCookiePropertyKey : Any] = [HTTPCookiePropertyKey.domain: domin,
                                                         HTTPCookiePropertyKey.path: "/",
                                                         HTTPCookiePropertyKey.name: name,
                                                         HTTPCookiePropertyKey.value: value,
                                                         HTTPCookiePropertyKey.expires: Date(timeIntervalSinceNow: 2629743),
                                                         HTTPCookiePropertyKey.version: 0,
                                                         HTTPCookiePropertyKey("HttpOnly"): false]
        self.init(properties: properties)
    }
}

let configuration = WKWebViewConfiguration()
for element in cookies {
    if let cookie = HTTPCookie(name: element.key, value: element.value) {
        configuration.websiteDataStore.httpCookieStore.setCookie(cookie, completionHandler: nil)
    }
}
2、WKWebView内自动播放音视频
let configuration = WKWebViewConfiguration()
configuration.mediaTypesRequiringUserActionForPlayback = []
3、webview 白屏解决
3.1、WKCompositingView 被收回导致白屏解决方案
// 这种情况一般出现在通过evaluateJavaScript调用前端方法刷新页面数据时
// 可在evaluateJavaScript方法调用后调用下面两种方案中的一种解决
// 调用webview的私有方法
#pragma clang diagnostic ignored "-Wundeclared-selector"
#pragma clang diagnostic push
if ([self respondsToSelector:@selector(_updateVisibleContentRects)]) {
    [self performSelector:@selector(_updateVisibleContentRects)];
}
#pragma clang diagnostic pop

// 或
webView.setNeedsLayout()
4、WKWebView设置自定义字体

一般加载本地HTML时,可以通过更改路径的方式设置自定义字体。

下述方案是将字体准换为base64字符串,通过脚本注入的方式,设置自定义字体。这种方式适合非本地网页。

extension WKUserScript {
      // fontPath:本地字体包路径
      // fontName:字体名,非字体包名
    convenience init?(fontPath: URL, fontName: String) {
        do {
            let data = try Data(contentsOf: fontPath)
            let base64 = data.base64EncodedString(options: [])
            let javascript = String(format: "var boldcss = '@font-face { font-family: \"%@\"; font-display: block; src: url(data:font/ttf;base64,%@) format(\"truetype\"); }'; var body = document.getElementsByTagName('body')[0], style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = boldcss; body.appendChild(style);", fontName, base64, fontName)
            self.init(source: javascript, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        } catch {
            return nil
        }
    }
}

results matching ""

    No results matching ""