文字っぽいの。

文字を書いています。写真も混ざります。

SwiftでURLやファイル拡張子から画像か動画か判別する。

やりたいこと

WKWebViewの

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)

でタップされたリンクが画像ならAという処理、動画ならBという処理をしたいという事がある。WebViewだけでなく、localのメディアに対するfile://path/to/fileというURLを取得した場合も同様に知りたいし、なんならファイル名だけ(hoge.png)だけからも知りたい。

よくある解決方法

ざっくり調べると拡張子をリストしておいて、それと合致するか調べる方法がよく出てくる。

let imageUrl = URL(string: "file://path/to/file.jpg")!

let imageExtensions = ["png", "jpg", "gif"]
if imageExtensions.contains(imageUrl.pathExtension) {
    print("これは画像です")
}

対応している拡張子が少ない場合や限定したい場合はこの方法が良い。

ただし、上記のコードでは .jpg はマッチするが .jpeg はマッチしないみたいな問題があるのと、「とりあえず画像なら処理Aをしたい」という場合には網羅するのが大変になってくる。

解決方法

UTType を利用すれば良い。

developer.apple.com

import UniformTypeIdentifiers

let movieUrl = URL(string: "file://path/to/file.mov")!

print(UTType(filenameExtension: movieUrl.pathExtension)!.conforms(to: .movie)) // => true
print(UTType(filenameExtension: movieUrl.pathExtension)!.conforms(to: .image)) // => false

let imageUrl = URL(string: "file://path/to/file.jpg")!

print(UTType(filenameExtension: imageUrl.pathExtension)!.conforms(to: .movie)) // => false
print(UTType(filenameExtension: imageUrl.pathExtension)!.conforms(to: .image)) // => true

ちなみに .video というのもあるが、そちらは音声が含まれない動画になる。作る機能によっては .video のみであったり .movie, .video の両方がマッチするように条件文を書く必要がある。