Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm showing html page in a
WKWebView
. My html contains links with embedded pdf as follow:
<td><div class="truncate"><a id="allegato1" class="link" href="data:octet-stream;base64,JVBERi0xLjIgCiXi48/
.........................................................
Ao3OTA2MiAKJSVFT0YgCg==%0A" download="FATCLI_19244324.PDF">FATCLI_19244324.PDF</a></div></td>
Now, I have to intercept click in the above links, save pdf on disk and then open the file with a reader. I'm able to do this as follow:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
if navigationAction.navigationType == .linkActivated, let url = navigationAction.request.url {
if url.scheme == "data" {
let splitted = url.absoluteString.components(separatedBy: "base64,")
if splitted.count == 2 {
let documentName = .... // What should I do?
if let data = Data(base64Encoded: splitted[1]) {
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(documentName)
try data.write(to: fileURL, options: .atomicWrite)
// Show pdf with via UIDocumentInteractionController
decisionHandler(.cancel)
return
} catch {
// Manage the error
decisionHandler(.cancel)
return
decisionHandler(.allow)
} else {
decisionHandler(.allow)
What I am trying to do is find a way to read document name from element download
or from tag a
value (FATCLI_19244324.PDF in this case). But it seems to be no way to do this in webView(_:decidePolicyFor:decisionHandler:)
method.
Can anyone help me?
I solved my problem by injecting some javascript in my WKWebView
.
override func viewDidLoad() {
super.viewDidLoad()
let configuration = WKWebViewConfiguration()
let userController:WKUserContentController = WKUserContentController()
userController.add(self, name: "linkClicked")
let js:String = """
var links = document.getElementsByClassName("link");
Array.prototype.forEach.call(links, function(link) {
// Disable long press
link.style.webkitTouchCallout='none';
link.addEventListener("click", function() {
var messageToPost = {'download': link.getAttribute("download"), 'href': link.getAttribute("href")}; window.webkit.messageHandlers.linkClicked.postMessage(messageToPost);
},false);
let userScript:WKUserScript = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
userController.addUserScript(userScript)
WKUserContentController
configuration.userContentController = userController;
myWebView = WKWebView(frame: webViewContainer.bounds, configuration: configuration)
......
In this way I can read download
and href
elements in userContentController(_:didReceive:)
method and save pdf on disk with right name.
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let body = message.body as? [String: Any] else { return }
guard let documentName = body["download"] as? String, let href = body["href"] as? String, let url = URL(string: href) else { return }
if url.scheme == "data" {
let splitted = url.absoluteString.components(separatedBy: "base64,")
if splitted.count == 2 {
if let data = Data(base64Encoded: splitted[1]) {
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(documentName)
try data.write(to: fileURL, options: .atomicWrite)
// Show pdf with via UIDocumentInteractionController
} catch {
// Manage the error
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.