在 Swift 應用里構造和修改 NSURL

作者:Nick Hanan,原文鏈接,原文日期:2016-03-17
譯者:BigbigChai;校對:walkingway;定稿:CMB

許多應用程序都有訪問文件的需求。也許是應用 bundle 或文件系統的文件,又或許是網上的資源。在代碼里需要調用某些方法來指向這些文件。對于 Apple 平臺而言,基本上只有兩個選擇:使用 String 或 NSURL。

使用過地址欄或任何終端的話,Swift 字符串將是一個非常容易理解的選擇。我的意思是,所有的文本都是在地址欄的,對吧?Cocoa 和 Cocoa Touch SDK 中一些較舊的 API 都接收 NSURL 和字符串(通常在這些 API 中稱為“路徑”)作為參數,但是都越來越朝著只使用 NSURL 的方向發展。和 String 路徑相比,NSURL 有許多優點,最明顯的是可以訪問 URL 各個部分的屬性,而不必另外編寫代碼來從路徑的字符串解析出這些組件。

請繼續關注如何在 Swift 應用程序中學習創建和使用 NSURL。

在 Swift 中創建 NSURL

在 Swift 中,有幾個構造器和工廠方法可以用于創建 NSURL,但是我只打算說明其中比較有用的一部分。

init?(string URLString: String)

這是最普通,也許也是最常用的方法。這需要 Swift 字符串版本的 URL,并將其轉換為 NSURL 對象。 這個構造器允許失敗,因為不是所有字符串都能生成合法的 URL。有一些字符無法在 URL 中使用,因此需要使用 % 編碼,它的出現表示了可以在 URL 中發送的編碼。我個人最常見的是 %20,”空格“字符。這個構造器只接收有效的字符,它不會另外做 % 編碼。因此,如果任何無法轉換為合法 URL 的內容或字符串出現時,該構造器將返回 nil。

    let NSHipster = NSURL(string: "http://nshipster.com/")                  //returns a valid URL
    let invalidURL = NSURL(string: "www.example.com/This is a sentence");   //Returns nil

這實際上是以下構造器的便利構造器。

init?(string URLString: String, relativeToURL baseURL: NSURL?)

這是允許定制的構造器。類似上一個構造器,它也是可失敗的,接收類似的 URL Swift 字符串,同時也接受一個可選的 baseURL 對象(本身也是 NSURL)。如果 baseURL 為空,則完全使用 URLString 創建 URL,這也許就是第一個構造器的內在實現。

let NSHipsterTwo = NSURL(string: "http://nshipster.com/", relativeToURL: nil)   //Returns valid NSHipster URL
let article = NSURL(string: "ios9/", relativeToURL: NSHipster)

init(fileURLWithPath path: String, isDirectory isDir: Bool)

這類似于上面的構造器,只是用于指向本地文件或目錄。我不確定為什么本地文件需要一個特殊版本,但我猜測它進行了一些優化(至少是以文件 scheme 開頭,而不是 http 之類)。有另一個版本沒有 isDirectory 參數,但已知路徑是否目錄的話,頭文件建議使用這個方法。也許因為另一個版本將需要再執行檢查,而這一個方法讓用戶提供了答案,能省下檢查的步驟。

public init(fileURLWithPath path: String, isDirectory isDir: Bool, relativeToURL baseURL: NSURL?)

這是 iOS 9 中新增的方法。與上個方法類似,只是還加了 relativeToURL 參數。類似之前的構造器,這將返回一個NSURL,并將路徑附加到 baseURL 后。如果有一個目錄內的幾個文件,有需求對這些文件進行迭代的時候,就可以利用這個方法了。可以提供文件所在的目錄作為 baseURL,然后只需使用文件名作為 Swift 字符串路徑創建 URL。

將 URL 轉換回 Swift 字符串

有時候,特別是在處理較舊的 API 或要向用戶展示時,需要將 NSURL 轉換回 Swift 字符串。好在 NSURL 提供了一個簡單的只讀屬性 absoluteString 來獲取字符串。 NSURL 對象只需調用該屬性就能獲得:

let articleString = article?.absoluteString
//ArticleString now contains: "http://nshipster.com/ios9/"

在這種情況,接收了之前使用 relativeToURL 版本的構造器定義的 article 常量,從 scheme 直到結尾(在這種情況下是一個路徑)把它解析成一個完整的 URL。如果一個 URL 包含文件擴展名(file extension),查詢(query)和片段(fragment),也會把它們解析出來。可失敗的構造器返回了原來的 article 對象,因此仍然有那個表示 Swift 可選鏈的問號。

修改 NSURL

這些函數都是基于被調用的 NSURL 返回一個新的、根據需求修改過的 NSURL。他們改變被調用的NSURL。

func URLByAppendingPathComponent(pathComponent: String, isDirectory: Bool) -> NSURL

這個方法給 URL 添加更多的路徑組件,例如說你要添加一個文件到當前目錄(存儲在調用的 NSURL)。跟其他一些構造器一樣,它有另一個沒有 isDirectory 參數的版本。但如果能明確它是否為目錄的話,建議使用這一個。因為這能省去用來確定是否目錄的元數據檢查。

var URLByDeletingLastPathComponent: NSURL? {get}

此屬性將返回一個新的、刪除了最后一個路徑組件的 NSURL。這只修改 URL 的路徑組件,URL 的其他組件(例如域名)不受影響。我們可以這樣寫:

//articleTwo now contains "http://nshipster.com/ios9/"
 
let deletePathComp = articleTwo?.URLByDeletingLastPathComponent
//deletePathComp now contains "http://nshipster.com/"

沒有路徑信息的話,結果可能會變得有點詭異。為了好玩,我鏈式調用了幾個URLByDeletingLastPathComponent,但最后只是在后面附加了“../”,類似命令行(cd ..)返回上一個目錄。

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

Conclusion

All code in this post was tested in Xcode 7.3.1.

如果你好奇 URL 格式規范的細節,可以查看 Apple 的 NSURL 類型參考在處理 URL 部分提到的 RFC 文檔。初始化 URL 時使用的字符串必須符合 RFC 2396,并且 URL 本身根據 RFC 1738RFC 1808 進行解析。這些規范內容很多,但你能找到所有可能關于 URL,URI 等的信息。

NSURL 中還有很多其他的屬性。如果你想要一個完全解析的 NSURL,baseURL,主機(host),查詢(query),片段(fragment)等,你可以查看 Apple 的 NSURL 類型參考。但對我個人而言,主要使用了 absoluteString,偶爾也會用到 pathExtension。

希望這篇文章對你有幫助。如果有,請在 Twitter 或任何社交媒體上分享這個帖子,每次分享都有裨益。當然,如果有任何問題,也請在聯系頁面 或 Twitter @CodingExplorer 上聯系我,我會盡量解答的。謝謝!

參考來源

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,229評論 4 61
  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應用程序 ...
    大L君閱讀 3,301評論 3 25
  • “沒能力,自己去學習 沒人脈,自己去勾搭 沒渠道,自己去建立 千萬不要把自己的前途,建立在任何人身上。“ 以上幾句...
    小小故事大智慧閱讀 481評論 0 0
  • 我把公寓套房租給王女士。我的套房一房一廳,簡單裝修,已經使用了好幾年了,又正好處在大樓的設計死角,房間呈三角形,因...
    陳旭山閱讀 640評論 7 9