在iOS中存储复杂对象?

时间:2017-08-06 19:02:34

标签: json swift plist

我有一个复杂的类对象如下:

class Ride {
    var distance:String?
    var price:Double?
    var Legs:[Leg]?
    var Routes:[Route]?
}

class Leg {
    var id:int?
    var value:string?
}

class Route {
    var id:int?
    var value:string?
}

我想要的是将它们存储为JSON或其他任何值,并在需要时对其进行读写。我的方法是在创建Ride对象之后将数据序列化为JSON并写入ridesjson.json文件然后当我想从该JSON读取时我想序列化为Ride对象。我可以这样做,还是有任何好办法吗?

1 个答案:

答案 0 :(得分:1)

在Swift 3中,将对象序列化为文件的标准方法是使其采用NSCoding(它必须是NSObject才能工作)并实现encode(with:)init(coder:)。然后,您可以存档到数据并保存(并反转过程以读取它)。

class Person: NSObject, NSCoding {
    var firstName : String
    var lastName : String
    override var description : String {
        return self.firstName + " " + self.lastName
    }
    init(firstName:String, lastName:String) {
        self.firstName = firstName
        self.lastName = lastName
        super.init()
    }
    func encode(with coder: NSCoder) {
        coder.encode(self.lastName, forKey: "last")
        coder.encode(self.firstName, forKey: "first")
    }
    required init(coder: NSCoder) {
        self.lastName = coder.decodeObject(forKey:"last") as! String
        self.firstName = coder.decodeObject(forKey:"first") as! String
        super.init()
    }

}

以下是存档的示例:

let fm = FileManager.default
let docsurl = try fm.url(for:.documentDirectory, 
    in: .userDomainMask, appropriateFor: nil, create: false)
let moi = Person(firstName: "Matt", lastName: "Neuburg")
let moidata = NSKeyedArchiver.archivedData(withRootObject: moi)
let moifile = docsurl.appendingPathComponent("moi.txt")
try moidata.write(to: moifile, options: .atomic)

我们在这里解开它:

let fm = FileManager.default
let docsurl = try fm.url(for:.documentDirectory, 
    in: .userDomainMask, appropriateFor: nil, create: false)
let moifile = docsurl.appendingPathComponent("moi.txt")
let persondata = try Data(contentsOf: moifile)
let person = NSKeyedUnarchiver.unarchiveObject(with: persondata) as! Person
print(person) // "Matt Neuburg"

但是,在Swift 4中,使用Codable协议可能更容易,从而使您的对象可以自动序列化为属性列表或JSON。 Codable适用于任何类型,包括结构。这就是所需要的:

struct Person : Codable {
    let firstName : String
    let lastName : String
}

以下是如何归档人员:

let p = Person(firstName: "Matt", lastName: "Neuburg")
let penc = PropertyListEncoder()
let d = try! penc.encode(p)

这是一个Data对象,您可以write直接将其转换为磁盘,如上例所示。 Unarchiving就是这么简单。假设d是您从磁盘读取的数据:

let p = try! PropertyListDecoder().decode(Person.self, from: d)