Swift 4 の URL は -[NSURL fileReferenceURL] に非対応
- Apple
- 開発
-[NSURL fileReferencceURL]
を使用すると AppleScript でいうところの alias
みたいな1、ファイルの場所に依存しない特別な URL を取得できる。
NSURL* url = [NSURL fileURLWithPath: @"/Applications/"]; //1
url.fileReferenceURL //2
1: file:///Applications/
2: file:///.file/id=3534367.8613694728/
これを Swift で使うのが今回の話。
Swift から呼ぶと
Swift で同じ内容を書いてみる。まず期待を裏切られるのは URL
に対して「fileRe
」まで入力しても補完されないことだ。...どうやらこの機能は NSURL
にしか用意されていないらしい。
まあ焦ることもない。NSString
の機能を使いたいときと同じように as NSURL
してから呼べばすべて解決するだろう。
import Foundation
let url = URL(fileURLWithPath: "/Applications/") //1
let fileReferenceUrl = (url as NSURL).fileReferenceURL() //2
1: file:///Applications/
2: Optional(file:///Applications/)
プロパティ扱いになっていないようで ()
が必要なのが気持ち悪いくらいか。クラッシュせずに動くし、解決!
...してない。これよく見ると普通の URL じゃないか!
変換できない
調べてみると、どうやら fileReferenceURL
というのは一瞬でも Swift の URL
に変換したら通常の URL に変化してしまうらしい。普通に呼んだだけなのに失敗した理由は何かというと、このメソッドは NSURL
のものであるけれど Swift 上では返り値の型が URL?
なのでそこで変換されてしまったということか。
Workaround
対処法は、 Swift による変換が入らないようにすることだ。以下のように as NSURL?
をつけるのが正解。似てるけど as? NSURL
はダメだから注意しよう。
let url = URL(fileURLWithPath: "/Applications/") //1
if let fileReferenceUrl = (url as NSURL).fileReferenceURL() as NSURL? {
fileReferenceUrl //2
}
if let fileReferenceUrl = (url as NSURL).fileReferenceURL() as? NSURL {
fileReferenceUrl //3
}
1: file:///Applications/
2: file:///.file/id=3534367.8613694728/
3: file:///Applications/
Swift の URL
が対応しないのは目をつぶるにしても、せめて型が NSURL?
になるように修正してほしいものである...
保存するなら
Apple の説明によると、この fileReferenceURL
は特定のタイミングで無効になる値らしい。保存するなら Bookmark Data を作成する必要があるそうだ。
A file reference URL's path should never be persistently stored, because it is not valid across system restarts or remounts of volumes. If you need to store a persistent reference to a file system object, use a bookmark instead. You can create a bookmark by calling bookmarkData(options:includingResourceValuesForKeys:relativeTo:).
-
よく調べずに書いたが本当? ↩︎
Share
リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。