はじめに
タイトル通り。swift の Bundle
の url(forResource:withExtension:)
の動作についてです。
動作
Xcode のプロジェクトに下記のようにファイルを追加します。
ファイル名と拡張子指定
let url = Bundle.main.url(forResource: "test", withExtension: "json")
通常の指定方法です。test.json
の URL が取得できます。
指定なし
let url1 = Bundle.main.url(forResource: "", withExtension: "")
let url2 = Bundle.main.url(forResource: nil, withExtension: nil)
引数を無しにします。url1
も url2
も当然 nil
になります。
ファイル名のみ指定(拡張子なし)
let url1 = Bundle.main.url(forResource: "test", withExtension: "")
let url2 = Bundle.main.url(forResource: "test", withExtension: nil)
引数の拡張子指定を無しにします。url1
も url2
も nil
になります。
ファイル名のみ指定(拡張子あり)
let url1 = Bundle.main.url(forResource: "test.json", withExtension: "")
let url2 = Bundle.main.url(forResource: "test.json", withExtension: nil)
引数のファイル名に拡張子まで指定し、引数の拡張子を無しにします。url1
も url2
も test.json
の URL が取得できます。
拡張子のみ指定
let url1 = Bundle.main.url(forResource: "", withExtension: "json")
let url2 = Bundle.main.url(forResource: nil, withExtension: "json")
引数のファイル名指定を無しにします。url1
も url2
も test.json
の URL が取得できます。んっ!? なんか取れた...
公式のドキュメントを見てみると下記のように書いてあります。
If you specify nil, the method returns the first resource file it finds with the specified extension.
なんか最初に見つけたやつ返してくれるみたいです。詳しい動作はわかりませんが、どこかにキャッシュを持ってるらしく clean build してもプロジェクトから指定のファイルを消しても最初に取れた URL が取れました。(プロジェクトから指定のファイルを消してアプリを削除して入れ直すとまた別のファイルが取れました)取れるファイルはアルファベット順とか Copy Bundle Resources
の追加順ていうわけではなさそうだったので、どのファイルが取れるのかはよくわかりません。
まとめ
url(forResource:withExtension:)
はちゃんと指定しなくても何か返してくれる。ちなみに path(forResource:ofType:)
も動作は同じっぽい。
さいごに
ファイル名が nil
なのになんかファイルを返却してくれるのはどこかで役に立つんだろうか?
func url(forResource name: String?, withExtension ext: String?) -> URL?
返却値がオプショナルなんで nil
でも良さそうなのに...