天天看點

iOS - Swift 資料持久化1、Sandbox 沙箱2、NSBundle 路徑3、NSURL 路徑4、資料持久化

iOS 為每個應用提供了獨立的檔案空間,一個應用隻能直接通路為本應用配置設定的檔案目錄,不可以通路其他目錄,每個應用自己獨立的通路空間被稱為該應用的沙盒。也就是說,一個應用與檔案系統的互動絕大部分都被限制在它自己的應用沙盒内。

1)在新 App 被安裝時,安裝器會為應用建立一系列角色不同的容器(container)。

iOS - Swift 資料持久化1、Sandbox 沙箱2、NSBundle 路徑3、NSURL 路徑4、資料持久化

iOS 8.0 之後,bundle 目錄和沙盒目錄 (Data) 是分開的。iOS 7.0 及以前版本 bundle 目錄和沙盒目錄 (Data) 是在一起的。

1> Bundle Container:

MyApp.app :這就是應用的運作包(bundle),這個目錄包含應用的可執行檔案和所有資源檔案。使用者從 App Store 購買應用後,iTunes 安裝到手機上的就是這個目錄檔案。這個目錄是隻讀的,而且該目錄在安裝時進行了簽名,安裝後對該目錄進行的任何寫操作都會改變目錄的簽名内容,進而使的該應用無法啟動,該應用本身能獲得 bundle 中的任何檔案的讀權限。

2> Data Container:

iTunes 在與 iPhone 同步時,備份所有的 Documents 和 Library 檔案。iPhone 在重新開機時,會丢棄所有的 tmp 檔案。

(1) Documents:

儲存由使用者産生的檔案或者資料,例如一個日記應用中使用者寫的日記檔案,或者音樂播放器中使用者下載下傳的歌曲,塗鴉程式生成的圖檔,遊戲關卡記錄等。建議将使用者可操作的檔案資料都放到該目錄。該檔案夾下的内容不會被系統自動删除,但是嚴格規定必須是使用者自己想要儲存的。

該目錄下的所有檔案都可以通過 iTunes 進行備份和恢複。存儲在這裡的所有檔案會自動備份到 iCloud。該目錄下如果儲存了從網絡下載下傳的檔案,在上架審批的時候,會被拒。

Documents/Inbox :該目錄用來通路被外部應用所請求目前應用打開的檔案。例如,我們的應用 MyApp 向系統注冊了可以打開 doc 類型的檔案,另一個應用 A 中有一個檔案 read.doc ,并申請 MyApp 打開此檔案,這時候系統會先将 read.doc 檔案拷貝到 MyApp 應用中的 Documents/Inbox 目錄下,MyApp 可以在 Inbox 目錄下進行檔案讀取和删除,但是不能建立檔案或者對已有檔案進行寫入。如果使用者要對檔案進行編輯,需要先将檔案移動到其他目錄。

(2) Library:

該目錄用來存儲非使用者資料,它下面包括幾個标準的子目錄,你可以将檔案放到其中之一,也可以自己建立子目錄。iOS 應用通常用到的子目錄有 Preferences 和 Caches 。Library 目錄下的檔案通常是不應該暴露給使用者的,該目錄下除了 Caches 子目錄外,其它目錄及其檔案都可以通過 iTunes 進行備份。

Library/Preferences :常用來放置配置檔案、資料檔案、模闆等應用在運作中與使用者相關,而又希望對使用者不可見的檔案,如系統偏好設定,使用者偏好設定等檔案。使用 NSUserDefaults 類進行偏好設定檔案的建立、讀取和修改。

Library/Caches :用來存放緩存檔案,儲存從網絡下載下傳的請求資料,後續仍然需要繼續使用的檔案,例如網絡下載下傳的離線資料,圖檔,視訊檔案等。該目錄中的檔案系統不會自動删除,可以做離線通路。它的存放時間比 tmp 下的長,但是不如 Library 下的其它目錄。總的來說 Caches 目錄下存放的資料不能是應用程式運作所必需的,但是能提高應用通路性能的。可寫入應用支援檔案,儲存應用程式再次啟動需要的資訊。

iTunes 不會對這個目錄的内容進行備份。要求程式員必需提供一個完善的清除緩存目錄的 "解決方案"。

(3) tmp:

該目錄用來存儲臨時檔案,那些在下次重新開機中不需要再次載入的臨時資訊可以存放到該目錄下。在應用不運作時,系統可能會對該目錄下的内容進行清理。

這個目錄的内容不會通過 iTunes 備份。程式員不需要管 tmp 檔案夾中的釋放。

2)iOS 中同一個應用在不同的手機中配置設定的路徑可能是不同的,是以我們無法通過寫死指定完整路徑名來找到對應檔案。Foundation 架構提供了一組專門的接口來擷取應用沙箱不同位置的目錄路徑。

該函數傳回一組路徑的數組,如果僅是查找使用者的目錄,這個數組隻包含一個元素,如果第二個參數包含多個值,該數組會包含多個元素。當為 iOS 編寫程式時,第二個參數應是 NSUserDomainMask,并且得到一個包含單個路徑的數組作為傳回。在 iOS 中後兩個參數是不變的。

directory :指定查找的目錄範圍。

NSSearchPathDirectory

說明

<code>ApplicationDirectory</code>

<code>/Applications</code>

<code>LibraryDirectory</code>

<code>/Library</code>

<code>DocumentDirectory</code>

<code>/Documents</code>

<code>ApplicationSupportDirectory</code>

<code>/Library/Application Support</code>

<code>UserDirectory</code>

<code>/Users</code>

<code>CachesDirectory</code>

<code>/Library/Caches</code>

domainMask :指定查找的檔案系統域,可以是多值。

NSSearchPathDomainMask

<code>UserDomainMask</code>

<code>使用者域,指向目前使用者的 home 目錄(~)</code>

<code>LocalDomainMask</code>

<code>本地域,指向對所有使用者可用的目前機器範圍</code>

<code>NetworkDomainMask</code>

<code>網絡域,指向 /Network</code>

<code>SystemDomainMask</code>

<code>系統域,指向 /System</code>

expandTilde :指定是否展開路徑中的代字元(~)。

在 iOS 中提到的 NSBundle 是檔案系統中的一個特殊位置,它存放的是應用可執行檔案及相關資源檔案。這個位置的所有檔案在系統運作時隻具有可讀或者可執行的權限,不能進行修改。

應用程式 bundle 中主要有以下幾種類型的檔案:

Info.plist:用來配置應用的基本參數資訊。包括版本号,指向的可執行檔案名、包名等。

可執行檔案:每個應用程式必須要有一個可執行檔案。

資源檔案:是可執行檔案以外的資料檔案,常用的如圖像、圖示、音頻檔案、視圖檔案、配置檔案等。

應用程式 bundle 的配置資訊都存在 Info.plist 檔案中。它裡面各項都以 key-value 的形式進行描述,包括了應用程式唯一辨別名、版本号、可執行檔案名等資訊。

bundle 配置資訊主要參數:

key

友好顯示名

value

CFBundleDisplayName

Bundle display name

程式的應用名,安裝後顯示在桌面上的那個名稱,可以進行本地化設定

CFBundleExecutable

Executable file

應用可執行程式的名稱

CFBundleIdentifier

Bundle identifier

應用程式的唯一辨別

CFBundleVersion

Bundle version

應用編譯版本号

CFBundleShortVersionString

Bundle version string, short

應用 release 釋出版版本号

當建立一個應用時,系統存儲了應用相關聯的所有資料(其中包括圖檔、本地化字元串、圖示等),将這些内容放入一個稱為應用包(application bundle)的包中。在應用中添加一個資源時很友善的:僅需将檔案拖到 Xcode 的左邊窗格中。當出現對話框時,通常選擇複制資源檔案到你的項目目錄中,這樣你的項目都是自包含的。

command-line tool 是沒有 bundle 的,是以用 NSBundle 的時候一直是 null,如果要使用 bundle 擷取項目中的資源,必須要使用 application。

Bundle 常見問題

項目裡面的某個 .swift 檔案無法使用

檢查 TARGETS =&gt; Build Phases =&gt; Compile Sources 裡是否包含此 .swift 檔案。

項目裡面的某個資源檔案(比如 plist、音頻等)無法使用

檢查 TARGETS =&gt; Build Phases =&gt; Copy Bundle Resources 裡是否包含此資源檔案。

擷取 NSBundle 資源

在檔案系統中,檔案和目錄都是使用完整檔案路徑來唯一辨別的。我們可以使用 NSString 和 NSURL 兩種對象來描述檔案路徑。官方建議使用 NSURL 。

NSURL 是用來表示 URL 位址的類,通過 URL 我們可以定位一個遠端 web 伺服器上的資源位置,也可以定位硬碟上的一個本地檔案的路徑。對于 web 資源,往往結合 NSURLSession、NSURLConnection、NSURLDownload 等使用,對于本地資源,一般結合 NSFileManager、NSFileHandle、NSBundle 使用。

NSURLComponents 隻支援 iOS7.0 及以上的 API 類,它可以實作對 URL 各個部分的讀寫。NSURLComponents 對 URL 各個部分的内容都有兩種格式的屬性來表示:

原生格式

URL-Encoded

scheme

host

percentEncodedHost

port

path

percentEncodedPath

query

percentEncodedQuery

fragment

percentEncodedFragment

user

percentEncodedUser

password

percentEncodedPassword

1)NSURL 結構:

2)URL 的建立

3)URL 的擷取

4)URL 的判斷

5)URL 的路徑拼接

6)NSURLComponents

在 iOS 開發過程中,不管是做什麼應用,都會碰到資料儲存的問題。将資料儲存到本地,能夠讓程式的運作更加流暢,不會出現讓人厭惡的菊花形狀,使得使用者體驗更好。下面介紹一下資料儲存的方式:

1、NSKeyedArchiver

2、NSUserDefaults

3、Write to file

4、SQLite