ios - iOS WKWebView - 发布正文 (EXC_BAD_ACCESS) 上的 WKURLSchemeHandler 崩溃
问题描述
我使用我的自定义WKURLSchemeHandler
拦截来自WKWebView
.
它适用于GET
请求,但在某些请求上崩溃POST
。
先决条件:
设置WKURLSchemeHandler
为WKWebView
like this
let config = WKWebViewConfiguration()
config.setURLSchemeHandler(WKURLSchemeHandlerImplementedClass(), forURLScheme: CUSTOM_SCHEME)
let webView = WKWebView(frame: CGRect.init(x: 0, y: 0, width: self.webViewContainer.frame.width, height: self.webViewContainer.frame.height), configuration: config)
程序:
1.加载支持上传文件的URL WKWebView
。
例如https://cgi-lib.berkeley.edu/ex/fup.html
(https 应更改为CUSTOM_SCHEME
)
2. 从输入文件表单中选择任何文件。
3. 按一个按钮上传文件。
-> 崩溃
调用栈:
WebViewProtocol
在WKURLSchemeHandlerImplementedClass
上面。
#0 0x00007fff4b8d6a3e in WebCore::blobRegistry() ()
#1 0x00007fff4b9052ad in WebCore::createHTTPBodyCFReadStream(WebCore::FormData&) ()
#2 0x00007fff4b905d18 in WebCore::setHTTPBody(_CFURLRequest*, WebCore::FormData*) ()
#3 0x00007fff4a851e0c in WebCore::ResourceRequest::doUpdatePlatformHTTPBody() ()
#4 0x00007fff4b8fe47d in WebCore::ResourceRequestBase::updatePlatformRequest(WebCore::HTTPBodyUpdatePolicy) const ()
#5 0x00007fff4a8506de in WebCore::ResourceRequest::nsURLRequest(WebCore::HTTPBodyUpdatePolicy) const ()
#6 0x00007fff2d1950ea in WebKit::WebURLSchemeTask::nsRequest() const ()
#7 0x0000000105f082f4 in WebViewProtocol.webView(_:start:) at /Users/t_honda/iOSProjects/smartdb-mobile-ios/smartdb/DocumentDetail/webView/WebViewProtocol.swift:30
#8 0x0000000105f09989 in @objc WebViewProtocol.webView(_:start:) ()
#9 0x00007fff2d13b41f in WebKit::WebURLSchemeHandlerCocoa::platformStartTask(WebKit::WebPageProxy&, WebKit::WebURLSchemeTask&) ()
#10 0x00007fff2d1940ca in WebKit::WebURLSchemeHandler::startTask(WebKit::WebPageProxy&, WebKit::WebProcessProxy&, unsigned long long, WebCore::ResourceRequest&&, WTF::CompletionHandler<void (WebCore::ResourceResponse const&, WebCore::ResourceError const&, WTF::Vector<char, 0ul, WTF::CrashOnOverflow, 16ul> const&)>&&) ()
#11 0x00007fff2d165864 in WebKit::WebPageProxy::startURLSchemeTaskShared(WTF::Ref<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, WebKit::URLSchemeTaskParameters&&) ()
#12 0x00007fff2d1657db in WebKit::WebPageProxy::startURLSchemeTask(WebKit::URLSchemeTaskParameters&&) ()
#13 0x00007fff2d3cd225 in void IPC::handleMessage<Messages::WebPageProxy::StartURLSchemeTask, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WebKit::URLSchemeTaskParameters&&)>(IPC::Decoder&, WebKit::WebPageProxy*, void (WebKit::WebPageProxy::*)(WebKit::URLSchemeTaskParameters&&)) ()
#14 0x00007fff2cf4582e in IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) ()
#15 0x00007fff2d190448 in WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) ()
#16 0x00007fff2cf31802 in IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) ()
#17 0x00007fff2cf345a4 in IPC::Connection::dispatchIncomingMessages() ()
我在 上确认了崩溃iOS
13.3
。
class WKURLSchemeHandlerImplementedClass:NSObject, WKURLSchemeHandler {
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
guard let customUrl = urlSchemeTask.request.url else { return }
var comps = URLComponents(url: customUrl, resolvingAgainstBaseURL: false)!
comps.scheme = "https"
let httpsUrl = comps.url!
// Send HTTP Request with service-specific headers via service-specfic proxy
// Crash occurrs on referring to urlSchemeTask.request
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
}
}
解决方案
受 Eugene Pavlyuk 回复的启发,方法“_setLoadResourcesSerially:”对我有用。
速写:
let selector = sel_registerName("_setLoadResourcesSerially:")
if let wv = NSClassFromString("WebView") as? NSObject.Type,
wv.responds(to: selector) {
wv.perform(selector, with: false as Any)
}
推荐阅读
- javascript - 点击内部地图功能后隐藏按钮-Redux
- javascript - ES6 Promises.all() does not execute all (no error caught in promises)
- sql - 如何将值从一个选择传递到查询中的另一个选择?
- python - 在 PCA 脚本上输入 .mat 文件的 Pandas DataFrame 错误
- python - 如何使用铅将 stdout 和 stderr 重定向到两个不同的文件?
- java - 更改 Graphics2D 坐标的原点
- c# - 有没有一种稳定的方法可以在 Android 设备上获取电话号码?
- jsp - JavaEE如何将文件上传到glassfish4服务器?
- android - 如何支持具有非标准 DPI 的屏幕
- swagger - 如何使用 OpenAPI/Swagger 定义数组项的排除类型?