如何使用歸檔

首先,我們需要讓 Album 實現(xiàn) NSCoding 協(xié)議,聲明這個類是可被歸檔的。打開 Album.swift 在 class 那行后面加上 NSCoding :

class Album: NSObject, NSCoding {

然后添加如下的兩個方法:

required init(coder decoder: NSCoder) {
    super.init()
    self.title = decoder.decodeObjectForKey("title") as! String
    self.artist = decoder.decodeObjectForKey("artist")as! String
    self.genre = decoder.decodeObjectForKey("genre") as! String?
    self.coverUrl = decoder.decodeObjectForKey("cover_url")as! String
    self.year = decoder.decodeObjectForKey("year") as! String
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(title, forKey: "title")
    aCoder.encodeObject(artist, forKey: "artist")
    aCoder.encodeObject(genre, forKey: "genre")
    aCoder.encodeObject(coverUrl, forKey: "cover_url")
    aCoder.encodeObject(year, forKey: "year")
}

encodeWithCoder 方法是 NSCoding 的一部分,在被歸檔的時候調(diào)用。相對的, init(coder:) 方法則是用來解檔的。很簡單,很強大。
現(xiàn)在 Album 對象可以被歸檔了,添加一些代碼來存儲和加載 Album 數(shù)據(jù)。
在 PersistencyManager.swift 里添加如下代碼:

func saveAlbums() {
    let filename = NSHomeDirectory().stringByAppendingString("/Documents/albums.bin")
    let data = NSKeyedArchiver.archivedDataWithRootObject(albums)
    data.writeToFile(filename, atomically: true)
}

這個方法可以用來存儲專輯。 NSKeyedArchiver 把專輯數(shù)組歸檔到了 albums.bin 這個文件里。
當(dāng)我們歸檔一個包含子對象的對象時,系統(tǒng)會自動遞歸的歸檔子對象,然后是子對象的子對象,這樣一層層遞歸下去。在我們的例子里,我們歸檔的是 albums 因為 Array 和 Album 都是實現(xiàn) NSCopying 接口的,所以數(shù)組里的對象都可以自動歸檔。
用下面的代碼取代 PersistencyManager 中的 init 方法:

override init() {
    super.init()
    if let data = NSData(contentsOfFile: NSHomeDirectory().stringByAppendingString("/Documents/albums.bin")) {
        let unarchiveAlbums = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! [Album]
        if let unwrappedAlbum : [Album]  = unarchiveAlbums {
            albums = unwrappedAlbum
        }
    } else {
        createPlaceholderAlbum()
    }
}

func createPlaceholderAlbum() {
    //Dummy list of albums
    let album1 = Album(title: "Best of Bowie",
             artist: "David Bowie",
             genre: "Pop",
             coverUrl: "http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png",
             year: "1992")

    let album2 = Album(title: "It's My Life",
           artist: "No Doubt",
           genre: "Pop",
           coverUrl: "http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png",
           year: "2003")

    let album3 = Album(title: "Nothing Like The Sun",
               artist: "Sting",
           genre: "Pop",
           coverUrl: "http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png",
           year: "1999")

    let album4 = Album(title: "Staring at the Sun",
           artist: "U2",
           genre: "Pop",
           coverUrl: "http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png",
           year: "2000")

    let album5 = Album(title: "American Pie",
           artist: "Madonna",
           genre: "Pop",
           coverUrl: "http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png",
           year: "2000")
    albums = [album1, album2, album3, album4, album5]
    saveAlbums()
}

我們把創(chuàng)建專輯數(shù)據(jù)的方法放到了 createPlaceholderAlbum 里,這樣代碼可讀性更高。在新的代碼里,如果存在歸檔文件, NSKeyedUnarchiver 從歸檔文件加載數(shù)據(jù);否則就創(chuàng)建歸檔文件,這樣下次程序啟動的時候可以讀取本地文件加載數(shù)據(jù)。
我們還想在每次程序進入后臺的時候存儲專輯數(shù)據(jù)??雌饋憩F(xiàn)在這個功能并不是必須的,但是如果以后我們加了編輯功能,這樣做還是很有必要的,那時我們肯定希望確保新的數(shù)據(jù)會同步到本地的歸檔文件。
因為我們的程序通過 LibraryAPI 來訪問所有服務(wù),所以我們需要通過 LibraryAPI 來通知 PersistencyManager 存儲專輯數(shù)據(jù)。
在 LibraryAPI 里添加存儲專輯數(shù)據(jù)的方法:

func saveAlbums() {
    persistencyManager.saveAlbums()
}

這個方法很簡單,就是把 LibraryAPI 的 saveAlbums 方法傳遞給了 persistencyManager 的 saveAlbums 方法。
然后在 ViewController.swift 的 saveCurrentState 方法的最后加上:

LibraryAPI.sharedInstance.saveAlbums()

在 ViewController 需要存儲狀態(tài)的時候,上面的代碼通過 LibraryAPI 歸檔當(dāng)前的專輯數(shù)據(jù)。
運行一下程序,檢查一下沒有編譯錯誤。
不幸的是似乎沒什么簡單的方法來檢查歸檔是否正確完成。你可以檢查一下 Documents 目錄,看下是否存在歸檔文件。如果要查看其他數(shù)據(jù)變化的話,還需要添加編輯專輯數(shù)據(jù)的功能。
不過和編輯數(shù)據(jù)相比,似乎加個刪除專輯的功能更好一點,如果不想要這張專輯直接刪除即可。再進一步,萬一誤刪了話,是不是還可以再加個撤銷按鈕?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 你可以下載the project source from the end of part 1與我們共同來探索 這是...
    木易林1閱讀 518評論 0 0
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,666評論 30 472
  • 2015/04/22更新:最新更新到Xcode6.3和Swfit 1.2。 更新日志:這個教程由Vicent Ng...
    木易林1閱讀 414評論 0 0
  • 數(shù)據(jù)持久化的相關(guān)知識 四種將數(shù)據(jù)持久化存儲到iOS文件系統(tǒng)的機制: plist 對象歸檔 iOS的嵌入式關(guān)系數(shù)據(jù)庫...
    melouverrr閱讀 728評論 0 0
  • 前一年多我們都沒有太多交集。我為了他去他的物理老師那里補課。見他一眼都笑嘻嘻的。后來有一天,我們接吻了。關(guān)系密切了...
    里漾33閱讀 138評論 0 0

友情鏈接更多精彩內(nèi)容