[Swift] URLを理解する (2: ファイルパス を扱う)

     
⌛️ 2 min.

URL型で ファイルパス を扱う時の方法を確認します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS15.0.1 Sequoia
  • Xcode 16.1 Beta3
  • iOS 18.1
  • Swift 5.9
URL 説明シリーズ
[Swift] URLを理解する (1: URI を扱う) [Swift] URLを理解する (2: ファイルパス を扱う) [Swift] URLを理解する (3: パスを操作する) [Swift] URLを理解する (4: ApplePlatform)

URL

URL という型は、リソースの位置を(それがローカルにあるのかリモートにあるのかにかかわわず) 表現する型です。


参考
URLApple Developer Documentation

ちなみに、URL は “Uniform Resource Locator” の省略型です。

file を扱う

URL の使い道の1つは、ファイルを指し示すことです。

この記事では、ファイルパスを表す URL について 確認していきます。

注意

HTML中に、半角文字で file:// と書くと、うまくレンダリングできなかったので、コード中では、file:// と全角文字で表現しています。コードで試す時には、置き換えてください。

イニシャライザ (init)

まずは、イニシャライザです。

URL でファイルパスを扱う時に使用する イニシャライザは、URL.init(filePath:directoryHint:relativeTo:) です。

参考
init(filePath:directoryHint:relativeTo:)Apple Developer Documentation

MEMO

URL.init(fileURLWithPath: ) は、Deprecated になっています。

import Testing
import Foundation

struct URLetcTests {
    @Test func filePath_init() async throws {
        let myFilePath = URL(filePath: "/tmp/myTempFile.jpg")

        #expect(myFilePath.absoluteString == "file:///tmp/myTempFile.jpg")
    }
}

init(filePath:) で作成した URL は、”file” スキーマに沿った表現になっています。
(スキーマは、URI で出てきました。https や ftp のことです。ここではファイルへのパスなので、file ということです。)

具体的には、”file://” で始まる 表現になっています。

ファイルパスは、絶対パスではなく 相対パスから作成することも可能です。

import Testing
import Foundation

struct URLetcTests {
    @Test func filePath_relativeInit() async throws {
        let baseURL = URL(filePath: "/tmp/")
        let myRelativeFilePath = URL(filePath: "myTempFile.jpg", relativeTo: baseURL)

        #expect(myRelativeFilePath.baseURL?.absoluteString == "file:///tmp/")
        #expect(myRelativeFilePath.relativeString == "myTempFile.jpg")

        #expect(myRelativeFilePath.standardized.absoluteString == "file:///tmp/myTempFile.jpg")
    }
}

上記のように、relativeTo へ、相対パスのベースとなるパスを渡すことで、その位置からの相対パスでファイルパスを作成できます。

なお、”..”(親ディレクトリ)や “.”(カレントディレクトリ)を含むを展開するには、”standardized” を使用します。(と ドキュメントには書かれているのですが、有用なケースを見つけられませんでした・・・orz)


参考
standardizedApple Developer Documentation

MEMO

特にドキュメントに言及はありませんが、baseURL に渡すファイルパスは、ディレクトリでなければいけないようです。
具体的には、”/” で終わっていることが必要のようです。

上記の例でも、baseURL に “/tmp” とすると、期待通りには動作しません。

取得

ファイルパスの部分的な情報を取得したいことはよくあります。

以下のようなファイルパスの情報を取得できるようなメソッドが用意されています。

isFileURL: Bool
ファイルパスを表現した URLか
hasDirectoryPath: Bool
ディレクトリを指し示すURLか
path(): String
ファイルパスを(String で)取得
pathComponents: [String]
ファイルパスをセパレータで分割して取得
lastPathComponent: String
最終要素(ファイル名相当)の取得
pathExtension
ファイルの拡張子を取得

先ほどの例で作成した2つのURLについて取得例です。

struct URLetcTests {

    @Test func filePath_init() async throws {
        let sut = URL(filePath: "/tmp/myTempFile.jpg")

        #expect(sut.absoluteString == "file:///tmp/myTempFile.jpg")

        // file path handling
        #expect(sut.isFileURL == true)
        #expect(sut.hasDirectoryPath == false) // since it does not end with "/"
        #expect(sut.path() == "/tmp/myTempFile.jpg")
        #expect(sut.pathComponents == ["/", "tmp", "myTempFile.jpg"])
        #expect(sut.lastPathComponent == "myTempFile.jpg")
        #expect(sut.pathExtension == "jpg")
    }

    @Test func filePath_relativeInit() async throws {
        let baseURL = URL(filePath: "/tmp/")
        let sut = URL(filePath: "myTempFile.jpg", relativeTo: baseURL)

        #expect(sut.baseURL?.absoluteString == "file:///tmp/")
        #expect(sut.relativeString == "myTempFile.jpg")

        #expect(sut.absoluteString == "file:///tmp/myTempFile.jpg")
        #expect(sut.standardized.absoluteString == "file:///tmp/myTempFile.jpg")

        // file path handling
        #expect(sut.isFileURL == true)
        #expect(sut.hasDirectoryPath == false) // since it does not end with "/"
        #expect(sut.path() == "myTempFile.jpg")
        #expect(sut.pathComponents == ["/", "tmp", "myTempFile.jpg"])
        #expect(sut.lastPathComponent == "myTempFile.jpg")
        #expect(sut.pathExtension == "jpg")
    }
    

まとめ

URL でファイルパスを扱うときのメソッドを確認しました。

ファイルパスを扱う URL
  • URL(filePath:) で init する
  • 絶対パス、相対パス のいずれからも作成できる
  • 相対パスから作成するときはベースのディレクトリパスが必要
  • ファイル名(パスの最終要素)、拡張子等を取得するメソッドが用意されている
  • ファイルパスを分解して取得するメソッドも用意されている

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です