【Swift】ファイルやディレクトリのパスが長すぎていやだ - URL.shortPath()

ファイルやディレクトリを操作していると、

パスの確認をしますよね。

例えば、


let documents = URL.documentsDirectory

としておいて、


print(documents.path)

あれ、Deprecated ですか。


print(documents.path())

として表示すると、


/Users/me/Library/Developer/Xcode/UserData/Previews/Simulator Devices/AA651DE-1A5C-4AA0-80D0-ADC0FF5AA467/data/Containers/Data/Application/35DFAAB4-E576-4318-9F17-DEC9F0DA259A/Documents

長い、長すぎる。

なんせ URL.homeDirectory までが長すぎる。

ファイル操作ごときが、

なぜか辛く感じるのは、

これのせいでしょうか。

短縮形のエクステンソン作ります。

ただの置換です。


extension URL {
  func shortPath(percentEncoded: Bool = true) -> String {
    path(percentEncoded: percentEncoded)
      .replacingOccurrences(
        of: URL.homeDirectory.path(percentEncoded: percentEncoded),
        with: "/HOME/"
      )
  }
}

いくつかの URL で確認。


print(documents.shortPath())
// /HOME/Documents/

print(
  documents
    .appending(component: "Documents and Settings/")
    .shortPath()
)
// /HOME/Documents/Documents%20and%20Settings/

print(
  documents
    .appending(component: "Documents and Settings", directoryHint: .isDirectory)
    .shortPath(percentEncoded: false)
)
// /HOME/Documents/Documents and Settings/

これで、ログウィンドウがスッキリしました!

ごときが !

 

🤔 参考

👉 【Swift】URL で特定のディレクトリやファイルを指す hatena-bookmark



【Swift】URL で特定のディレクトリやファイルを指す

これで、URLを使って操作するファイルやディレクトリを指していきますが。


func appending<S>(
    component: S,
    directoryHint: URL.DirectoryHint = .inferFromPath
) -> URL where S : StringProtocol

👉 appending(component:directoryHint:) | Apple Developer Documentation hatena-bookmark

一つ目の引数の末尾の「/(スラッシュ)」で、

そのURLが指しているものが、

「ディレクトリなのかファイルなのか」

が変わる。

実体ではなく、指しているもの。

指す側の認識。


let home = URL.homeDirectory

let documents = URL.documentsDirectory
let documents1 = home.appending(component: "Documents/")
let documents2 = home.appending(component: "Documents", directoryHint: .isDirectory)

let documents3 = home.appending(component: "Documents")
let documents4 = home.appending(component: "Documents/", directoryHint: .notDirectory)

print(
  documents == documents1,  // true
  documents == documents2,  // true
  documents1 == documents2, // true

  documents == documents3,  // false
  documents == documents4   // false
)

2つ目の引数 directoryHint は、その指定を上書きする。

デフォルトは .inferFromPath

楽になったような、逆に混乱するような、

どうなんだろ。



【Swift】URL appendingPathComponent() vs appending(component:)

どれを使ったらいいのか分かりづらかったので歴史。

 

🤔 iOS 8.0-17.5 Deprecated


func appendingPathComponent(_ pathComponent: String) -> URL

👉 appendingPathComponent(_:) | Apple Developer Documentation hatena-bookmark


func appendingPathComponent(
    _ pathComponent: String,
    isDirectory: Bool
) -> URL

👉 appendingPathComponent(_:isDirectory:) | Apple Developer Documentation hatena-bookmark

 

🤔 iOS 14.0+


func appendingPathComponent(
    _ partialName: String,
    conformingTo contentType: UTType
) -> URL

👉 appendingPathComponent(_:conformingTo:) | Apple Developer Documentation hatena-bookmark


UTType.plainText 
UTType.text  // markup
UTType.utf8PlainText

👉 UTType | Apple Developer Documentation hatena-bookmark

 

🤔 iOS 16.0+ (2022-09リリース 2年前 現シェア9割)


func appending<S>(
    component: S,
    directoryHint: URL.DirectoryHint = .inferFromPath
) -> URL where S : StringProtocol

👉 appending(component:directoryHint:) | Apple Developer Documentation hatena-bookmark


case checkFileSystem
case inferFromPath // default
case isDirectory
case notDirectory

👉 URL.DirectoryHint | Apple Developer Documentation hatena-bookmark


Bundle.main.bundleURL.appending(component: "hogehoge.file", directoryHint: .notDirectory)

👉 [Swift] パフォーマンスが気になる場面ではappendingPathComponentの使い方に注意する hatena-bookmark

 

🤔 まとめ

まずは、


appending(component: "newfile.txt")

からでお願いします。

こういう歴史的経緯系が混乱します。

 

🤔 参考

👉 Foundation URL Improvements - Development / Core Libraries - Swift Forums hatena-bookmark
👉 [Back from revision] Foundation URL Improvements - Development / Core Libraries - Swift Forums hatena-bookmark
👉 🚀 iOS version Market Share hatena-bookmark