将 UIWebView 替换为 WKWebView,但 Apple 仍然出现相同的错误
Replaced UIWebView with WKWebView, but still same error from Apple
我已经从我的应用程序中删除了 UIWebView。但是当我在 iTunes 上上传 iOS 应用程序时,我仍然收到相同的消息 "Re: ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs"
我在项目中全局搜索了UIWebView,没有搜索到结果。这仅仅意味着 UIWebView 被删除了。
我也更新了pods。
我已经使用以下代码验证了应用存档中 UIWebView 的存在:
grep -r "UIWebView" .
响应是
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
Binary file ./dSYMs/Eureka.framework.dSYM/Contents/Resources/DWARF/Eureka matches
如何检查仍然导致 UIWebView 错误的代码?
如何检查 UIWebView 是否已从项目中完全删除?
解决方法是:
- 打开终端。在终端中打开项目根文件夹。
- 运行 命令:grep -r "UIWebView"。
- 此命令将列出所有包含“UIWebView”的pods。不要更新这些 pods 或删除这些 pods 并再次执行第 2 步命令。重复直到所有“UIWebView”匹配都没有被删除。
以下是指导您将现有 UIWebView 更新为 WKWebView 的一些步骤。
将“WebKit
”class导入控制器。
假设您正在使用名为“webViewMain”的 UIWebView。然后转到您的故事板,只需将 UIWebView 替换为 UIView。确保您已将添加到 UIWebView 的相同约束添加到 UIView。从新的 UIView 中绘制 @IBOutlet 到现有的 UIWebView 的@IBOutlet。
这里需要把@IBOutlet的class从UIWebView改成UIView,因为你已经把UIWebView换成UIView了
旧代码:@IBOutlet weak var webViewMain: UIWebView!
新代码:@IBOutlet weak var webViewMain: UIView!
然后新建一个变量来创建一个新的WKWebView。
代码:var webView : WKWebView!
在 UIWebView 中加载 request/html 的位置添加以下代码:
// WKWebView
// init and load request in webview.
webView = WKWebView(frame: self.webViewMain.frame)
webView.navigationDelegate = self
self.webView.load(request)
self.webViewMain.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
// Adding constraints from webView(WKWebView) to webViewMain (UIView)
webView.leadingAnchor.constraint(equalTo: webViewMain.leadingAnchor, constant: 0).isActive = true
webView.trailingAnchor.constraint(equalTo: webViewMain.trailingAnchor, constant: 0).isActive = true
webView.topAnchor.constraint(equalTo: webViewMain.topAnchor, constant: 0).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewMain.bottomAnchor, constant: 0).isActive = true
// WKWebView
到现在你已经用 WKWebView 替换了 UIWebView 。
现在是委托方法。
UIWebView 有委托 class: UIWebViewDelegate
WKWebView 有委托 class: WKNavigationDelegate
用 WKNavigationDelegate 替换 UIWebViewDelegate。
现在是 UIWebView 与 WKWebView 的委托方法比较:
UIWeb 视图:func webViewDidFinishLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
UIWeb 视图:func webViewDidStartLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
UIWeb 视图:func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool
这里我们用returntrue/false到load/cancel的导航。
WKWebView: func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
这里我们 returndecisionHandler(.allow)/decisionHandler(.cancel) 到 load/cancel 导航。
缩放纵横比适合 webView (WKWebView) 的内容。
var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(scriptContent, completionHandler: nil)
设置webView的高度:
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
self.constraintWebViewProductDescriptionHeight.constant = height as! CGFloat
})
}
})
我已经从我的应用程序中删除了 UIWebView。但是当我在 iTunes 上上传 iOS 应用程序时,我仍然收到相同的消息 "Re: ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs"
我在项目中全局搜索了UIWebView,没有搜索到结果。这仅仅意味着 UIWebView 被删除了。 我也更新了pods。
我已经使用以下代码验证了应用存档中 UIWebView 的存在:
grep -r "UIWebView" .
响应是
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/F4DBB519-4BC9-3C29-B017-4C0BD603D250.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:l_OBJC_LABEL_PROTOCOL_$_UIWebViewDelegate
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:-[Crashlytics monitorErrorsForUIWebView:]
./BCSymbolMaps/63FADF77-FD8F-31A1-9B4E-2799F044786E.bcsymbolmap:CLSWebViewIsUIWebViewAlreadyMonitored
Binary file ./dSYMs/Eureka.framework.dSYM/Contents/Resources/DWARF/Eureka matches
如何检查仍然导致 UIWebView 错误的代码?
如何检查 UIWebView 是否已从项目中完全删除?
解决方法是:
- 打开终端。在终端中打开项目根文件夹。
- 运行 命令:grep -r "UIWebView"。
- 此命令将列出所有包含“UIWebView”的pods。不要更新这些 pods 或删除这些 pods 并再次执行第 2 步命令。重复直到所有“UIWebView”匹配都没有被删除。
以下是指导您将现有 UIWebView 更新为 WKWebView 的一些步骤。
将“WebKit
”class导入控制器。
假设您正在使用名为“webViewMain”的 UIWebView。然后转到您的故事板,只需将 UIWebView 替换为 UIView。确保您已将添加到 UIWebView 的相同约束添加到 UIView。从新的 UIView 中绘制 @IBOutlet 到现有的 UIWebView 的@IBOutlet。 这里需要把@IBOutlet的class从UIWebView改成UIView,因为你已经把UIWebView换成UIView了
旧代码:@IBOutlet weak var webViewMain: UIWebView!
新代码:@IBOutlet weak var webViewMain: UIView!
然后新建一个变量来创建一个新的WKWebView。
代码:var webView : WKWebView!
在 UIWebView 中加载 request/html 的位置添加以下代码:
// WKWebView
// init and load request in webview.
webView = WKWebView(frame: self.webViewMain.frame)
webView.navigationDelegate = self
self.webView.load(request)
self.webViewMain.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
// Adding constraints from webView(WKWebView) to webViewMain (UIView)
webView.leadingAnchor.constraint(equalTo: webViewMain.leadingAnchor, constant: 0).isActive = true
webView.trailingAnchor.constraint(equalTo: webViewMain.trailingAnchor, constant: 0).isActive = true
webView.topAnchor.constraint(equalTo: webViewMain.topAnchor, constant: 0).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewMain.bottomAnchor, constant: 0).isActive = true
// WKWebView
到现在你已经用 WKWebView 替换了 UIWebView 。 现在是委托方法。 UIWebView 有委托 class: UIWebViewDelegate WKWebView 有委托 class: WKNavigationDelegate
用 WKNavigationDelegate 替换 UIWebViewDelegate。
现在是 UIWebView 与 WKWebView 的委托方法比较:
UIWeb 视图:func webViewDidFinishLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
UIWeb 视图:func webViewDidStartLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
UIWeb 视图:func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool
这里我们用returntrue/false到load/cancel的导航。
WKWebView: func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
这里我们 returndecisionHandler(.allow)/decisionHandler(.cancel) 到 load/cancel 导航。
缩放纵横比适合 webView (WKWebView) 的内容。
var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(scriptContent, completionHandler: nil)
设置webView的高度:
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
self.constraintWebViewProductDescriptionHeight.constant = height as! CGFloat
})
}
})