swift - 使用 NSCoding 保存结构

标签 swift struct nscoder

我想保存以下数据:

class Book: NSObject, NSCoding {

var title: String
var chapter: [Chapter]

struct Chapter {
    var chapTitle: String
    var texte: [Texte]
}

struct Texte {
    var description: String
    var texte: [String]
    var position: [Int]
    var hidden: [Int?]
}

我目前正在使用 NSCoder 来保存 Book 类:

static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("learn")


struct PropertyKey {
    static let title = "title"
    static let chapter = "Chapter"
}

//MARK: - Initialization
init?(title: String, chapter: [Book.Chapter]) {        
    self.title = title
    self.chapter = chapter
}

//MARK: - NSCoding
func encode(with aCoder: NSCoder) {
    aCoder.encode(title, forKey: PropertyKey.title)
    aCoder.encode(chapter, forKey: PropertyKey.chapter)
}

required convenience init?(coder aDecoder: NSCoder) { 
    let title = aDecoder.decodeObject(forKey: PropertyKey.title) as! String
    let chapter = aDecoder.decodeObject(forKey: PropertyKey.chapter) as! [Book.Chapter]

    self.init(title: title, chapter: chapter)
}

这样我就可以保存书的标题和一个空的章节数组。

但是,当我尝试将 chapTitletexte 添加到 Book 对象时,出现以下错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x60000066dec0'

这是否意味着该结构无法保存?我应该改变什么?

最佳答案

如果你可以将 book 设为 struct ,那么你最好使用 codable 。

struct Book: Codable {

var title: String
var chapter: [Chapter]

struct Chapter:Codable {
    var chapTitle: String
    var texte: [Texte]
}

struct Texte:Codable {
    var description: String
    var texte: [String]
    var position: [Int]
    var hidden: [Int?]
}

保存

static func saveData (books: [Book]) throws
{
     let encoded = try JSONEncoder().encode(books)
     try encoded.write(to: ArchiveURL)
     print("Books saved")
}

检索

//retrive data from it's saved place
static func loadData() throws -> [Book]
{
     let data = try Data(contentsOf: ArchiveURL)
     return try JSONDecoder().decode([Book].self, from: data)
}

同时编辑顶部的变量

let directory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/learn/"

let ArchiveURL = URL(fileURLWithPath: directory)

关于swift - 使用 NSCoding 保存结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50887940/

相关文章:

c - 结构对字体大小的贡献

swift - 使用 NSKeyedArchiver 和 NSKeyedUnarchiver 进行往返编码和解码

swift - realm 移动平台,离线时如何连接?

swift - 像以前一样刷新 ViewController

ios - base64 字符串到 iOS 中的音频 mp3?

c - 为什么这段代码会导致段错误错误?

ios - iMessage 中的导航栏高度 (iOS 10)

c++ - 如何在使用 g++ 编译器时使用 c 样式初始化结构?

objective-c - initWithCoder :?中NSCoder有什么用(Cocoa和Cocoa Touch)

ios - 在 Swift 3 中使用 NSCoder 编码/解码日期?