1

我想知道如何将对象数组保存到 NSUserDefault。我已经阅读了有关编码数据数组的信息,但不确定该过程是如何工作的。

这是我的数组:

//EventData class with EventDataArray
class EventData {
    
    static var EventDataArray: [EventModel] = []
    
}

这是我的数据模型:

struct EventModel {
    var id = UUID()
    var eventName: String
    var fromTime: Date
    var toTime: Date
    var fromTimeString: String
    var toTimeString: String
    var color: UIColor
}

编辑:更新的数组类

class EventData: Codable {
    
    static var EventDataArray: [EventModel] = []
    
}

我将不胜感激有关该主题的任何建议!

4

2 回答 2

2

要将结构保存在 UserDefaults 中,您需要首先对其进行编码以便能够将其保存为数据。所以你需要让你的自定义结构符合 Codable:

struct Event: Codable {
    let id: UUID
    let name: String
    let start, end: Date
    let fromTime, toTime: String
    let color: Color
    init(id: UUID = .init(),
         name: String,
         start: Date,
         end: Date,
         fromTime: String,
         toTime: String,
         color: Color) {
        self.id = id
        self.name = name
        self.start = start
        self.end = end
        self.fromTime = fromTime
        self.toTime = toTime
        self.color = color
    }
}

请注意,您不能使 UIColor 符合 Codable 但您可以创建自定义 Color 结构:

struct Color: Codable {
    let (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat)
}

extension Color {
    init?(_ uiColor: UIColor) {
        var (r, g, b, a): (CGFloat,CGFloat,CGFloat,CGFloat) = (0, 0, 0, 0)
        guard uiColor.getRed(&r, green: &g, blue: &b, alpha: &a) else { return nil }
        self.init(r: r, g: g, b: b, a: a)
    }
    var color: UIColor { .init(red: r, green: g, blue: b, alpha: a) }
}

extension UIColor {
    convenience init(_ color: Color) {
        self.init(red: color.r, green: color.g, blue: color.b, alpha: color.a)
    }
    var color: Color? { Color(self) }
}

关于您的类,您还可以使其符合 Codable 或从 NSObject 继承并符合 NSCoding:

class Events: NSObject, NSCoding {
    private override init() { }
    static var shared = Events()
    var events: [Event] = []
    required init(coder decoder: NSCoder) {
        events = try! JSONDecoder().decode([Event].self, from: decoder.decodeData()!)
    }
    func encode(with coder: NSCoder) {
        try! coder.encode(JSONEncoder().encode(events))
    }
}

游乐场测试:

Events.shared.events = [.init(name: "a",
                              start: Date(),
                              end: Date(),
                              fromTime: "fromTime",
                              toTime: "toTime",
                              color: .init(r: 0, g: 0, b: 1, a: 1)),
                        .init(name: "b",
                              start: Date(),
                              end: Date(),
                              fromTime: "fromTimeB",
                              toTime: "toTimeB",
                              color: .init(r: 0, g: 1, b: 0, a: 1))]

print(Events.shared.events)
let data = try! NSKeyedArchiver.archivedData(withRootObject: Events.shared, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "events")
Events.shared.events = []
print(Events.shared.events)
let loadedData = UserDefaults.standard.data(forKey: "events")!
Events.shared = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(loadedData) as! Events
print(Events.shared.events)

这将打印

[事件(id:C7D9475B-773E-4272-84CC-56CAEAA73D0C,名称:“a”,开始:2021-01-26 05:17:30 +0000,结束:2021-01-26 05:17:30 +0000 , fromTime: "fromTime", toTime: "toTime", color: Color(r: 0.0, g: 0.0, b: 1.0, a: 1.0)), Event(id: 0BEA4225-2F63-4EEB-AF10-F3EF4C84D050, name :“b”,开始:2021-01-26 05:17:30 +0000,结束:2021-01-26 05:17:30 +0000,fromTime:“fromTimeB”,toTime:“toTimeB”,颜色:Color (r: 0.0, g: 1.0, b: 0.0, a: 1.0))]
[]
[事件(id:C7D9475B-773E-4272-84CC-56CAEAA73D0C,名称:“a”,开始:2021-01-26 05:17:30 +0000,结束:2021-01-26 05:17:30 +0000 , fromTime: "fromTime", toTime: "toTime", color: Color(r: 0.0, g: 0.0, b: 1.0, a: 1.0)), Event(id: 0BEA4225-2F63-4EEB-AF10-F3EF4C84D050, name :“b”,开始:2021-01-26 05:17:30 +0000,结束:2021-01-26 05:17:30 +0000,fromTime:“fromTimeB”,toTime:“toTimeB”,颜色:Color (r: 0.0, g: 1.0, b: 0.0, a: 1.0))]

于 2021-01-26T05:20:25.423 回答
0

只需使用:( UserDefaults().set(try? PropertyListEncoder().encode(EventDataArray), forKey: "eventDataPersisted")当然,您可以随意命名密钥)。

此外,根据经验,变量名通常遵循camelCase

于 2021-01-26T05:04:30.600 回答