5

My app navigates to a mobile web page with a WKWebView. What I'm looking for is how to check whether or not the web page is downloadable (e.g. a .csv or .pdf). Right now, I'm doing something hacky to read the URL, but I know there must be a more elegant way.

I'm using WKNavigationDelegate - can anyone provide some insight on how to tell whether a page provides downloadable content or not? Or how I can read a type of "text/csv"?

Please let me know if I can clarify at all.

ArielSD
  • 829
  • 10
  • 27

2 Answers2

7

You should be able to inspect the response and get the MIME type before the page loads, using the webView(_:decidePolicyFor:decisionHandler:) method of your WKNavigationDelegate.

Set an object as the navigationDelegate for your WKWebView, and give it a method like this:

func webView(_ webView: WKWebView, 
        decidePolicyFor navigationResponse: WKNavigationResponse, 
        decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {

    if let mimeType = navigationResponse.response.mimeType {
        // do some thing with the MIME type
    } else {
        // response has no MIME type, do some special handling
    }
    decisionHandler(.allow)
}
Aaron Frary
  • 906
  • 1
  • 13
  • 24
  • 1
    There may be a server issue on my end, since this still logs a mimeType of "html/text" even though the URL has a downloadable .csv. It's getting routed through the back end. – ArielSD Sep 28 '17 at 21:51
  • 1
    @ArielSD you can check if mimeType is "html/text" and the url pathExtension == "csv" https://stackoverflow.com/questions/36231061/wkwebview-open-links-from-certain-domain-in-safari/36231713?s=1|5.4860#36231713 – Leo Dabus Sep 28 '17 at 22:05
  • It's a good though, we tried that: The link that points to a .csv doesn't have an extension like that. – ArielSD Sep 28 '17 at 22:30
2

You can use the framework Swime for this. You use it like this:

import Swime

let path = "/path/to/some-file.jpg"
let url = URL(fileURLWithPath: path, isDirectory: false)
let data = try! Data(contentsOf: url)
let mimeType = Swime.mimeType(data: data)

mimeType?.type == .jpg // true
mimeType! // MimeType(mime: "image/jpeg", ext: "jpg", type: .jpg)

switch mimeType?.type {
  case .jpg?:
    ....
  case .png?:
    ....
  case .wmv?:
    ....

  case ...
}

Here are the list of available MimeTypeExtension:

public enum MimeTypeExtension {
  case amr
  case ar
  case avi
  case bmp
  case bz2
  case cab
  case cr2
  case crx
  case deb
  case dmg
  case eot
  case epub
  case exe
  case flac
  case flif
  case flv
  case gif
  case gz
  case ico
  case jpg
  case jxr
  case lz
  case m4a
  case m4v
  case mid
  case mkv
  case mov
  case mp3
  case mp4
  case mpg
  case msi
  case mxf
  case nes
  case ogg
  case opus
  case otf
  case pdf
  case png
  case ps
  case psd
  case rar
  case rpm
  case rtf
  case sevenZ // 7z, Swift does not let us define enum that starts with a digit
  case sqlite
  case swf
  case tar
  case tif
  case ttf
  case wav
  case webm
  case webp
  case wmv
  case woff
  case woff2
  case xpi
  case xz
  case z
  case zip
}
Rashwan L
  • 38,237
  • 7
  • 103
  • 107
  • Thanks for the quick response. This looks like it's assumed that the file is downloaded already - do you know of a way to do a similar thing with a page in a WKWebView? I want to check if the page is downloadable, and then download the contents if I can. Does that make sense? – ArielSD Sep 28 '17 at 20:27
  • @ArielSD, okey now I get it. Checkout [this](https://stackoverflow.com/a/40003309/5576310) post then. Is this what you need? – Rashwan L Sep 28 '17 at 20:47
  • Thanks for the list of MimeTypeExtension :-) – Yogesh Patel Aug 23 '21 at 11:25