2017-08-06 70 views
1

我有一个复杂的类对象,如下所示:在iOS中存储复杂对象?

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或任何具有价值和读取和写入到它时,我需要的。我的方法是在数据序列化为JSON并创建Ride对象后写入ridesjson.json文件,然后当我想从该JSON读取时,我想序列化为Ride对象。我可以这样做还是有什么好方法可以做到这一点?

回答

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" 

在夫特4,但是,它可以是更容易使用的可编码的协议,以便使您的对象可以作为属性列表或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) 

这是一个数据对象,您可以直接write到磁盘与前面的例子所示。取消存档也很简单。假设d是您从磁盘读取的数据:

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