在 Swift 應用裏構造和修改 NSURL

做者:Nick Hanan,原文連接,原文日期:2016-03-17
譯者:BigbigChai;校對:walkingway;定稿:CMBhtml

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

使用過地址欄或任何終端的話,Swift 字符串將是一個很是容易理解的選擇。個人意思是,全部的文本都是在地址欄的,對吧?Cocoa 和 Cocoa Touch SDK 中一些較舊的 API 都接收 NSURL 和字符串(一般在這些 API 中稱爲「路徑」)做爲參數,可是都愈來愈朝着只使用 NSURL 的方向發展。和 String 路徑相比,NSURL 有許多優勢,最明顯的是能夠訪問 URL 各個部分的屬性,而沒必要另外編寫代碼來從路徑的字符串解析出這些組件。git

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

在 Swift 中建立 NSURL

在 Swift 中,有幾個構造器和工廠方法能夠用於建立 NSURL,可是我只打算說明其中比較有用的一部分。swift

init?(string URLString: String)

這是最普通,也許也是最經常使用的方法。這須要 Swift 字符串版本的 URL,並將其轉換爲 NSURL 對象。 這個構造器容許失敗,由於不是全部字符串都能生成合法的 URL。有一些字符沒法在 URL 中使用,所以須要使用 % 編碼,它的出現表示了能夠在 URL 中發送的編碼。我我的最多見的是 %20,」空格「字符。這個構造器只接收有效的字符,它不會另外作 % 編碼。所以,若是任何沒法轉換爲合法 URL 的內容或字符串出現時,該構造器將返回 nil。app

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,這也許就是第一個構造器的內在實現。post

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

相關文章
相關標籤/搜索