UIWebView: ics and vcard-Links are not processed

I have UIWebView

one that includes a generic URL; unfortunately vcard and ical-Links are not processed, i.e. nothing happens when i click on them.

I tried to install all the data detectors, unfortunately it fails.

In Xcode-log, I get this here when I click on a link like this:

2017-07-14 13:43:00.982413+0200 xxx[2208:967973] WF: _userSettingsForUser mobile: {
    filterBlacklist =     (
    );
    filterWhitelist =     (
    );
    restrictWeb = 1;
    useContentFilter = 0;
    useContentFilterOverrides = 0;
    whitelistEnabled = 0;
}

      

The same stuff works as expected in Safari.

If I use UIApplication.shared.openURL(icsOrVcardUrl)

Safari opens and from there everything works as expected, but I don't want the user to leave the app ...

EDIT This also doesn't work:

    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if let url = request.url {
        if url.absoluteString.contains("=vcard&") || url.absoluteString.contains("/ical/") {
            let sessionConfig = URLSessionConfiguration.default
            let session = URLSession(configuration: sessionConfig)
            let request = URLRequest(url:url)
            let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
                if let tempLocalUrl = tempLocalUrl, error == nil {
                    DispatchQueue.main.async {
                        self.documentController.url = tempLocalUrl
                        self.documentController.presentPreview(animated: true)
                    }
                }
            }
            task.resume()
            return false
        }
    }
    return true
}

      

+3


source to share


1 answer


Use UIDocumentInteractionController to preview without leaving the app. I quickly tested it with an .ics file and it works great.

Implement the protocol UIDocumentInteractionControllerDelegate

extension MainViewController: UIDocumentInteractionControllerDelegate {
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self;
    }
}

      

Create an instance of the interaction controller:

let documentController = UIDocumentInteractionController()

      

Intercept clicks in UIWebView in shouldStartLoadWithRequest

, return false for the links you want to render, with an in-app preview and true for everyone else. Finally:

func previewDocument(_ url: URL) {
    documentController.url = url
    documentController.presentPreview(animated: true)
}

      



Here he is in the simulator

enter image description here

EDIT:

In response to a comment on this answer: The reason it doesn't work for you is because it UIDocumentInteractionController

depends on the file extension. Temporary file extension .tmp

Renaming the file after uploading solves the problem. A quick and dirty example:

let task = session.downloadTask(with: url!) { (tempLocalUrl, response, error) in
    if let tempLocalUrl = tempLocalUrl, error == nil {
        do {
            let filemgr = FileManager.default
            let newUrl = tempLocalUrl.appendingPathExtension("ics")
            try filemgr.moveItem(at: tempLocalUrl, to: newUrl)
            DispatchQueue.main.async {
                self.documentController.url = newUrl
                self.documentController.presentPreview(animated: true)
            }
        } catch let error {
            print("Error!!!: \(error.localizedDescription)")
        }

    }
}
task.resume()

      

In this case, it is recommended to clean up after itself because the file will not be deleted after the task completes, although the OS will eventually delete it when space is needed. If you access the same URLs frequently, there Library/Caches/

might be a better place for these files, just come up with the correct naming scheme and check if the file doesn't already exist.

+2


source







All Articles