Swift - 将字典 [String:Any] 编码和解码为 plist
Swift - Encode and Decode a dictionary [String:Any] into plist
我试图将字典存储在我的 class 标记中,但它抛出一个错误,指出它不可编码或不可解码。我可以看到错误是由 [String: Any] 引起的,但我该如何解决它?
var buttonActions : [String: [String: [String:Any]]] = [:]
保存并加载
func saveData() {
let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")
let encoder = PropertyListEncoder()
do {
let data = try encoder.encode(markerArray)
try data.write(to: dataFilePath!)
print("Saved")
} catch {
print("Error Encoding \(error)")
}
}
func loadData() {
let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")
if let data = try? Data(contentsOf: dataFilePath!){
let decoder = PropertyListDecoder()
do {
markerArray = try decoder.decode([Marker].self, from: data)
} catch {
print("Decode Error \(error)")
}
}
Class
class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonActions : [String: [String: [String:Any]]] = [:]
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}
遗憾的是,您不能对包含 Any
的泛型类型使用 encode
或 decode
(例如 [String: Any]
或 [Any]
)。 Any
不符合协议 Encodable
也不符合 Decodable
并且 Swift 不知道如何 encode/decode 它。您必须为字典使用具体的泛型类型(例如 [String: String]
)。
如果您仍然需要使用像 Any
这样的通用类型,您必须实现 encode(to:)
和 init(from:)
方法。另一种选择是使用 struct
而不是符合 Codable
(Encodable & Decodable
) 的 [String: [String: [String:Any]]]
。你仍然需要在该结构中实现 encode(to:)
和 init(from:)
方法,但好的一面是你不必像你必须的那样为所有属性编写 encoder.encode()
故事如果您在 Marker
class 中实现它们。
所以终于在安德拉达的帮助下解决了。
我添加了第二个结构来保存动作并通过必须使用 [string:any]
class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonAction : [String: [ButtonAction]] = [:] //Dictionary I edited using the new struct
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}
下面是我添加的结构体
struct ButtonAction: Codable {
var action: String
var array_linked_of_buttons: [[String:String]]
init(action: String, array_linked_of_buttons: [[String:String]]) {
self.action = action
self.array_linked_of_buttons = array_linked_of_buttons
}
}
确保初始化你的结构,否则它不会工作。
我试图将字典存储在我的 class 标记中,但它抛出一个错误,指出它不可编码或不可解码。我可以看到错误是由 [String: Any] 引起的,但我该如何解决它?
var buttonActions : [String: [String: [String:Any]]] = [:]
保存并加载
func saveData() {
let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")
let encoder = PropertyListEncoder()
do {
let data = try encoder.encode(markerArray)
try data.write(to: dataFilePath!)
print("Saved")
} catch {
print("Error Encoding \(error)")
}
}
func loadData() {
let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")
if let data = try? Data(contentsOf: dataFilePath!){
let decoder = PropertyListDecoder()
do {
markerArray = try decoder.decode([Marker].self, from: data)
} catch {
print("Decode Error \(error)")
}
}
Class
class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonActions : [String: [String: [String:Any]]] = [:]
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}
遗憾的是,您不能对包含 Any
的泛型类型使用 encode
或 decode
(例如 [String: Any]
或 [Any]
)。 Any
不符合协议 Encodable
也不符合 Decodable
并且 Swift 不知道如何 encode/decode 它。您必须为字典使用具体的泛型类型(例如 [String: String]
)。
如果您仍然需要使用像 Any
这样的通用类型,您必须实现 encode(to:)
和 init(from:)
方法。另一种选择是使用 struct
而不是符合 Codable
(Encodable & Decodable
) 的 [String: [String: [String:Any]]]
。你仍然需要在该结构中实现 encode(to:)
和 init(from:)
方法,但好的一面是你不必像你必须的那样为所有属性编写 encoder.encode()
故事如果您在 Marker
class 中实现它们。
所以终于在安德拉达的帮助下解决了。
我添加了第二个结构来保存动作并通过必须使用 [string:any]
class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonAction : [String: [ButtonAction]] = [:] //Dictionary I edited using the new struct
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}
下面是我添加的结构体
struct ButtonAction: Codable {
var action: String
var array_linked_of_buttons: [[String:String]]
init(action: String, array_linked_of_buttons: [[String:String]]) {
self.action = action
self.array_linked_of_buttons = array_linked_of_buttons
}
}
确保初始化你的结构,否则它不会工作。