Search code examples
iosobjective-cswiftobjective-c-swift-bridge

Circumvent ObjC to Swift bridge with KVC?


Recently ran into a crash in our app:

EXC_BREAKPOINT 0x00000001c5c8986c
static URLRequest._unconditionallyBridgeFromObjectiveC(_:)

It's coming from a webView decide policy where we access the request property:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
   let req = navigationAction.sourceFrame.request
}

I believe the problem is on this line in swift lib: https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/URLRequest.swift#L298

There are no guards in place here, and it seems like on the objc side it's possible that the request is nil.

My question is regarding how to get around the objc to swift bridge. Would KVC avoid that?

if let req = navigationAction.sourceFrame.value(forKey: "request") as NSURLRequest {
    //do stuff
}

If there's no way to circumvent the objc to swift bridge it's a crash we will have to live with? It is not happening too frequently, but enough that we would love to fix.


Solution

  • I think you are right assuming that request is nil, when the error occurs. A similar problem is described here.
    Since URLRequest.swift, as defined in apple/swift-corelibs-foundation that your cited will definitively crash if request is nil, one cannot use it in this situation.
    One alternative is definitively to use KVO, since func value(forKey key: String) -> Any? can return nil values, see here.
    However, you can only use it, if the object, in which the function is called, adopted the NSKeyValueCoding protocol, which is ensured if the object is a subclass of NSObject, which I cannot tell from your code fragment.
    But since you suggested this already in your question, did you try it?