我想为我的应用程序的(非常简单的)模型使用结构。
但是NSKeyedArchiver
只接受对象(扩展NSObjects
)。
有什么好方法可以将结构保存到文件中吗?
我有时使用的一种非常简单的方法。您需要编写的代码量在类/NSCoding 方案中并不多。
首先导入伟大的 SwiftyJSON 库。
让我们从一个简单的结构开始
struct Starship {
let name: String
let warpSpeed: Bool
let captain: String?
init(name: String, warpSpeed: Bool, captain: String? = nil) {
self.name = name
self.warpSpeed = warpSpeed
self.captain = captain
}
}
让我们使其可转换为 JSON 或从 JSON 转换
struct Starship {
let name: String
let warpSpeed: Bool
let captain: String?
init(name: String, warpSpeed: Bool, captain: String? = nil) {
self.name = name
self.warpSpeed = warpSpeed
self.captain = captain
}
init?(json: JSON) {
guard let
name = json["name"].string,
warpSpeed = json["warpSpeed"].bool
else { return nil }
self.name = name
self.warpSpeed = warpSpeed
self.captain = json["captain"].string
}
var asJSON: JSON {
var json: JSON = [:]
json["name"].string = name
json["warpSpeed"].bool = warpSpeed
json["captain"].string = captain
return json
}
}
就是这样。让我们使用它
let enterprise = Starship(name: "Enteriprise D", warpSpeed: true, captain: "JeanLuc Picard")
let json = enterprise.asJSON
let data = try! json.rawData()
// save data to file and reload it
let newJson = JSON(data: data)
let ship = Starship(json: newJson)
ship?.name // "Enterprise D"
Swift 5+ 的更新解决方案
- 无需导入任何内容
- 使结构可编码
struct Starship: Codable { // Add this
let name: String
let warpSpeed: Bool
let captain: String?
init(name: String, warpSpeed: Bool, captain: String? = nil) {
self.name = name
self.warpSpeed = warpSpeed
self.captain = captain
}
}
- 读取和写入文件的函数
var data: Starship
func readFromFile(filePathURL: URL) throws {
let readData = try Data(contentsOf: filePathURL)
self.data = try JSONDecoder().decode(Starship.self, from: readData)
}
func writeToFile(filePathURL: URL) throws {
let jsonData = try JSONEncoder().encode(self.data)
try jsonData.write(to: filePathURL)
}