My app contains HTML information pages opened in WKWebView, containing some hyperlinks. These used to work, but stopped working with recent iOS releases with error messages, containing words
Could not create sandbox extension
Connection to daemon was invalidated
When I apply WKNavigation delegate with the following code
extension InformationPageController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: ((WKNavigationActionPolicy) -> Void)) {
var policy = WKNavigationActionPolicy.allow
if navigationAction.navigationType == .linkActivated {
// Neither of commented lines below works!
// webView.load(navigationAction.request)
// webView.loadHTMLString(navigationAction.request.url!.absoluteString, baseURL: nil)
UIApplication.shared.openURL(navigationAction.request.url!)
policy = .cancel
}
decisionHandler(policy)
}
}
the pages are opened in an external browser, but not inside the app.
Is there a way to open the links as before, within same WKWebView?
https
protocol is currently accepted by WKWebView. If you have just http
, WKWebView will complain about insecure protocol and won't open. After I changed http-s to https-s, the pages opened, but not AppStore pages. This leads to another issue.
https://apps.apple.com/...
, iOS (but not macOS) redirects it to itms-appss://apps.apple.com/...
for opening in AppStore app, causing WKWebView to come up with the error: Redirection to URL with a scheme that is not HTTP(S)
. Similar problem with mailto
urls.To bypass these issues I modified code to the following:
extension InformationPageController: WKNavigationDelegate {
static let disallowedUrlPrefixes = ["https://apps.apple.com", "mailto:"]
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: ((WKNavigationActionPolicy) -> Void)) {
var policy = WKNavigationActionPolicy.allow
if navigationAction.navigationType == .linkActivated,
let url = navigationAction.request.url {
let urlString = url.absoluteString
if InformationPageController.disallowedUrlPrefixes.first(where:{urlString.starts(with: $0)}) != nil {
UIApplication.shared.openURL(url)
policy = .cancel
}
}
decisionHandler(policy)
}
}
Now the 'troublesome' pages are opened with an external browser, all others are opened within WKWebView. Unfortunately that's the best I can currently think of.