在你的 Swift 應用中建立或修改 URL

SwiftGG翻譯組發表於2018-10-15

作者:codingexplorer,原文連結,原文日期:2018-07-18譯者:Damonwong;校對:numbbbbbBigNerdCoding;定稿:Forelax

譯者注:此篇文章以前我們曾經翻譯過,原文作者在今年對這篇文章進行了更新,我們也對更新後的文章進行了翻譯並再次釋出。

對於大部分應用來說,都需要訪問一些檔案資源。這些檔案資源可能在你的應用安裝包中,或者在檔案系統內,亦或者在某個網站伺服器上。你需要用某種方法將它們體現在程式碼中。對於蘋果平臺而言,你主要有兩種選擇,用字串或者 URL

如果你使用過瀏覽器的位址列或者在終端中輸入過地址,你可能會選擇使用字串,畢竟,在這些地方你只能輸入字串。雖然在 CocoaCocoa Touch SDKs 中許多舊的 API 同時採用 URL 和字串 (對於這些 API 來說,這些字串通常被稱為 “path”) 作為引數,但是越來越多的 API 傾向於只能用 URL 物件。相比較於字串路徑來說,URL 物件有更多的優勢,最明顯的優勢就是你可以直接通過屬性訪問 URL 的不同的部分,而不需要自己編寫一個解析元件來解析路徑字串的不同部分。

緊跟我的步伐,接下來我們學習如何在 Swift 應用中建立和使用 URL 物件。

在 Swift 中建立一個 URL 物件

在 Swift 中有好幾個構造器和工廠方法可用於建立 URL 物件,下面我要講一些更有用的初始化方法。

init?(string URLString: String)

這個是普通的,也是最常用的初始化方法。將一個用於表示 URL 的 Swift 字串轉變成一個 URL 物件。但並不是所有的字串都可以有效的表示一個 URL,所以這是一個可失敗構造器。由於有些字元不能在 URL 中使用,因此需要進行 URL 編碼,將這些不能使用的字元轉化為可以在 URL 中傳送的編碼。我個人見過最多的是 %20,也就是“空格”字元。這個構造器需要有效的字元,它不會為你進行 URL 編碼轉化。如果字串中包含無法轉換為有效 URL 的字元或者內容,構造器將會返回 nil

let NSHipster = URL(string: "http://nshipster.com/") //返回一個有效的 URLlet invalidURL = URL(string: "www.example.com/This is a sentence") //返回 nil複製程式碼

這個構造器其實是下面這個構造器的一個便利構造器。

init?(string: String, relativeTo: URL?)

這是一個指定構造器。和上面的構造器一樣,也是一個可失敗的構造器,而且需要一個類似 URL 的 Swift 字串和一個可選的 baseURL 物件,這個 baseURL 本身也是一個 URL 物件。如果 baseURLnil,那麼內部會像第一個構造器一樣,根據提供的 URL 字串生成一個 URL 物件。

let NSHipsterTwo = URL(string: "http://nshipster.com/", relativeTo: nil) //返回一個有效的 NSHipster URLlet article = URL(string: "ios9/", relativeTo: NSHipster) //返回 "http://nshipster.com/ios9/" URL 複製程式碼

init(fileURLWithPath: String, isDirectory: Bool)

該構造方法與上一個構造方法類似,但是他的字串引數指向的是本地檔案或者目錄。我不太確定為什麼會有一個本地檔案的特殊版本,我猜有可能是做了一些優化(至少需要是檔案 scheme 開頭,而不應該是 http 之類的)。雖然有一個不需要傳 isDirectory 引數的構造器,但如果你知道它是否是一個目錄時,蘋果建議你使用這個這個方法。在我看來,有可能另外一個構造器在內部自己判斷了輸入引數是否是一個目錄,而這個方法通過傳入引數避免了檢查。

init(fileURLWithPath: String, isDirectory: Bool, relativeTo: URL?)

這是在 iOS 9 中新加入的方法,這與前一個類似,但新增了 relativeToURL 引數。和之前的構造器一樣,它將返回一個將路徑附加到 baseURLURL 物件。當你需要為了某個事情重複訪問某個目錄下的不同檔案時,可以使用這個初始化方法。你可以將檔案所在的目錄作為 baseURL,然後只需要一個檔名作為 Swift 字串路徑來建立 URL 物件。

將 URL 轉回 Swift 字串

有時你需要將 URL 物件轉回 Swift 字串,特別是在處理舊的 API 或者向使用者展示情形下。值得慶幸的是,URL 提供了一個簡單的只讀屬性來解決這個問題: absoluteString。只需要在你的 URL 物件呼叫該屬性即可:

let articleString = article?.absoluteString// articleString 現在包含 = 的值是 "http://nshipster.com/ios9/"複製程式碼

在這個例子中,我們使用了 relativeToURL 版本的構造器定義了一個 article 常量,將其解析為從 scheme 開始的完整 URL (在這種情況下是一個路徑)。如果這個 URL 上有檔案擴充名,query 或者 fragment,它依舊可以被解析。原來的 article 物件是由一個可失敗構造器返回的,這就是為什麼那兒有一個 Swift 可選訪問。

修改一個 URL 物件

我們接下來所說的這些方法,每一個都會在請求修改完成時根據呼叫的 URL 物件返回一個新的 URL 物件。它們不會更改呼叫它們的 URL 物件。

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

這個方法可以為你的 URL 新增更多的路徑元件,比如當你要新增一個檔案到你所在的目錄(儲存在這個方法呼叫返回的 URL)時,這個方法就可以派上用處。像我們前面提到的那個初始化方法一樣,這個方法也有一個沒有 isDirectory 引數的版本,但是無論你是否知道它是不是一個目錄,都更推薦你使用這個方法來確保後設資料可以儲存在正確的目錄下。

func deletingLastPathComponent() ->
URL

這個方法將會返回刪除了最後一個路徑元件的新 URL 物件。這方法適用於 URL 的路徑部分,URL 的其他部分不受影響,比如域名。所以我們可以這樣子做:

let articleTwo = NSHipster?.appendingPathComponent("ios9", isDirectory: true)//articleTwo 現在包含的 URL 字元是 "http://nshipster.com/ios9/"let deletePathComp = articleTwo?.deletingLastPathComponent//deletePathComp 現在包含的 URL 字元是 "http://nshipster.com/"複製程式碼

譯者注:在 Swift 4.2 之前,deletingLastPathComponent 是一個屬性,因此在呼叫時不用加括號。在 4.2 版本中,deletingLastPathComponent 變成了方法因此如果你在 4.2 上執行上面一段程式碼,需要在 articleTwo?.deletingLastPathComponent 最後加一個括號才能正確執行

如果沒有路徑資訊,可能有點兒奇怪。為了好玩,我鏈式呼叫了幾次 URLByDeletingLastPathComponent,最後只是新增了 “../”,類似於在命令列(cd ..)中上一個目錄。

當然還有幾種修改方法和屬性,但這些可能是最常用的。

總結

如果你對 URL 格式規範感興趣的話,可以去檢視蘋果的 URL 參考文件中,關於如何處理 URL 這部分提及到的 RFC 文件。用於初始化的字串必須符合 RFC 2396,並且 URL 將會根據 RFC 1738RFC 1808 被解析。這些規範內容很多,但你能找到所有可能關於 URL,URI 等的資訊。

如果你完整查閱 URL 的文件的話,還可以看到它擁有 baseURLhostqueryfragment 等等非常多的屬性,所有這些屬性都能在 Apple 文件中查詢到。不過對我來說,日常使用最多的還是 absoluteString,偶爾也會用到 pathExtension

我希望你能覺得這篇文章對你有所幫助。如果你覺得有用,請不要猶豫,在 Twitter 或者其他社交媒體上分享這篇文章。當然,如果你有任何疑問,請隨時通過 聯絡頁面 或者 Twitter@CodingExplorer 與我聯絡。我會盡可能的幫助你。謝謝。

參考

URL Class Reference – Apple Inc.

本文由 SwiftGG 翻譯組翻譯,已經獲得作者翻譯授權,最新文章請訪問 swift.gg

來源:https://juejin.im/post/5bc43bd9e51d4539701e9b57#comment

相關文章