Open1

Swift: Application Supportフォルダでハマった話

kabeyakabeya

NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)で、例えば/var/mobile/Containers/Data/Application/FCA6162A-BC31-415F-B053-AABBED1BA710/Library/Application Supportなどというフォルダパス(の配列)が取れてくるのですが、これでハマりました。

上で取れてくるのはパス文字列なのですが、これをURL(filePath:)でURLに変換し、それをまた別の箇所でurl.path()で戻してファイル操作しようとしたら、失敗しまくります。

Application Supportというフォルダ名にはスペースが含まれていて、URLにしたときには%20に変換されます。url.path()はそのままだと%20%20のまま返してきます。

このため、
/var/mobile/Containers/Data/Application/FCA6162A-BC31-415F-B053-AABBED1BA710/Library/Application Support
URL(filePath:)
file:///var/mobile/Containers/Data/Application/FCA6162A-BC31-415F-B053-AABBED1BA710/Library/Application%20Support
url.path()
/var/mobile/Containers/Data/Application/FCA6162A-BC31-415F-B053-AABBED1BA710/Library/Application%20Support

で、もとのパスと違うパスになってしまっていました。
url.path()ではなくurl.path(percentEncoded: false)を使う必要があります。
percentEncoded:falseを指定すると%20が残らなくなります(デコードされます)。

NSSearchPathForDirectoriesInDomains.documentDirectoryを指定するとうまくいくのでディレクトリの書き込みパーミッションなのかとか、そもそもApplication Supportフォルダを自前で作らないといけないのかとか、起動するたびに上記パスに含まれるUUIDが変わるのがいけないのか、とか、色々悩みましたが、原因が分かれば単純な話でした。