如何使用归档

作者: YangPu | 来源:发表于2017-03-29 14:07 被阅读21次

首先,我们需要让 Album 实现 NSCoding 协议,声明这个类是可被归档的。打开 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 的一部分,在被归档的时候调用。相对的, init(coder:) 方法则是用来解档的。很简单,很强大。
现在 Album 对象可以被归档了,添加一些代码来存储和加载 Album 数据。
在 PersistencyManager.swift 里添加如下代码:

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

这个方法可以用来存储专辑。 NSKeyedArchiver 把专辑数组归档到了 albums.bin 这个文件里。
当我们归档一个包含子对象的对象时,系统会自动递归的归档子对象,然后是子对象的子对象,这样一层层递归下去。在我们的例子里,我们归档的是 albums 因为 Array 和 Album 都是实现 NSCopying 接口的,所以数组里的对象都可以自动归档。
用下面的代码取代 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()
}

我们把创建专辑数据的方法放到了 createPlaceholderAlbum 里,这样代码可读性更高。在新的代码里,如果存在归档文件, NSKeyedUnarchiver 从归档文件加载数据;否则就创建归档文件,这样下次程序启动的时候可以读取本地文件加载数据。
我们还想在每次程序进入后台的时候存储专辑数据。看起来现在这个功能并不是必须的,但是如果以后我们加了编辑功能,这样做还是很有必要的,那时我们肯定希望确保新的数据会同步到本地的归档文件。
因为我们的程序通过 LibraryAPI 来访问所有服务,所以我们需要通过 LibraryAPI 来通知 PersistencyManager 存储专辑数据。
在 LibraryAPI 里添加存储专辑数据的方法:

func saveAlbums() {
    persistencyManager.saveAlbums()
}

这个方法很简单,就是把 LibraryAPI 的 saveAlbums 方法传递给了 persistencyManager 的 saveAlbums 方法。
然后在 ViewController.swift 的 saveCurrentState 方法的最后加上:

LibraryAPI.sharedInstance.saveAlbums()

在 ViewController 需要存储状态的时候,上面的代码通过 LibraryAPI 归档当前的专辑数据。
运行一下程序,检查一下没有编译错误。
不幸的是似乎没什么简单的方法来检查归档是否正确完成。你可以检查一下 Documents 目录,看下是否存在归档文件。如果要查看其他数据变化的话,还需要添加编辑专辑数据的功能。
不过和编辑数据相比,似乎加个删除专辑的功能更好一点,如果不想要这张专辑直接删除即可。再进一步,万一误删了话,是不是还可以再加个撤销按钮?

相关文章

  • 如何使用归档

    首先,我们需要让 Album 实现 NSCoding 协议,声明这个类是可被归档的。打开 Album.swift ...

  • oracle删除归档

    oracle删除归档,可以使用rman删除归档,也可以使用rm直接删除! 1.使用rm删除归档: 删除所有归档:f...

  • iOS archive(归档)的总结

    一、使用archiveRootObject进行简单的归档 使用NSKeyedArichiver进行归档、NSKey...

  • Oracle归档日志

    显示归档日志信息 1,使用ARCHIVE LOG LIST命令可以显示日志操作模式,归档位置,自动归档机器要归档的...

  • 谈谈MJExtension和YYmodel归档反归档搭配NSUs

    使用归档反归档需要遵守NSCoding协议,实现协议里的归档和反归档方法等等,很是麻烦。(网上很多介绍这里不进行介...

  • Oracle归档日志操作

    查询日志的归档模式: 查询归档日志的信息: 查询正在使用的组所对应的日志文件: 查看归档信息:

  • iOS对象归档

    终结一下iOS的对象归档问题. 1:这个对象为什么需要归档 2:使用归档的时候需要注意什么 3:归档以后写进本地,...

  • 浅谈Oracle归档日志

    什么是归档日志 归档日志(Archive Log)是非活动的重做日志备份.通过使用归档日志,可以保留所有重做历史记...

  • iOS 13归档解档

    归档解档的使用 自定义类对象要进行归档,那么这个对象的属性所属的类必须要遵守归档协议NSCoding必须在需要归档...

  • 利用运行时,归档解归档实现用户信息存储,无需对用户模型的每个属性

    利用运行时,归档解归档实现用户信息存储,无需对用户模型的每个属性单独归档与解归档:1、使用方法:保存:UserMo...

网友评论

    本文标题:如何使用归档

    本文链接:https://www.haomeiwen.com/subject/opbeottx.html