gpt4 book ai didi

ios - 使用 NSKeyedArchiver 和 Userdefault 保存结构数组,其中对象符合 NSCoding

转载 作者:搜寻专家 更新时间:2023-11-01 06:04:42 31 4
gpt4 key购买 nike

作为面向协议(protocol)的编程概念,我使用Struct 创建了我的模型。

我想将“Struct”的Array 保存到Userdefault 中。但是我在对这个模型的数组进行编码/解码时遇到了问题。

这是我的模型结构

struct Room {
let name : String
let id : String
let booked : Bool
}

我在这里创建了一个像这样的扩展

extension Room {


func decode() -> Room? {
let userClassObject = NSKeyedUnarchiver.unarchiveObject(withFile: RoomClass.path()) as? RoomClass
return userClassObject?.room
}

func encode() {
let personClassObject = RoomClass(room: self)
NSKeyedArchiver.archiveRootObject(personClassObject, toFile: RoomClass.path())
}

class RoomClass: NSObject, NSCoding {

var room : Room?

init(room: Room) {
self.room = room
super.init()
}

class func path() -> String {
let documentsPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
let path = documentsPath?.appending(("/Room"))
return path!
}

func encode(with aCoder: NSCoder) {
aCoder.encode(room!.name, forKey: "name")
aCoder.encode(room!.id, forKey: "Id")
aCoder.encode(room!.booked, forKey: "booked")
}

required init?(coder aDecoder: NSCoder) {
let _name = aDecoder.decodeObject(forKey: "name") as? String
let _id = aDecoder.decodeObject(forKey: "Id") as? String
let _booked = aDecoder.decodeBool(forKey: "booked")

room = Room(name: _name!, id: _id!, booked: _booked)

super.init()
}
}
}

当我试图像这样保存arrRoomList(房间对象数组)时

        self.saveRooms(arrayRooms: arrRoomList)

我遇到了这个错误

[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance

我也试过先对每个对象进行编码,然后尝试将它们保存为默认值,然后它也会报错。

谁能指导我如何以正确的方式编码/解码 Userdefaults 中的结构数组而不将其转换为字典?

最佳答案

您可以像这样设置结构以直接使用 NSKeyedArchiver:

struct Room {
let name : String
let id : String
let booked : Bool
}

extension Room {
func encode() -> Data {
let data = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWith: data)
archiver.encode(name, forKey: "name")
archiver.encode(id, forKey: "id")
archiver.encode(booked, forKey: "booked")
archiver.finishEncoding()
return data as Data
}

init?(data: Data) {
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
defer {
unarchiver.finishDecoding()
}
guard let name = unarchiver.decodeObject(forKey: "name") as? String else { return nil }
guard let id = unarchiver.decodeObject(forKey: "id") as? String else { return nil }
booked = unarchiver.decodeBool(forKey: "booked")
self.name = name
self.id = id
}
}

要与 UserDefaults 一起使用,请这样调用:

// to encode to data and save to user defaults
let room = Room(name: "asdf", id: "123", booked: true)
UserDefaults.standard.set(room.encode(), forKey: "room")

// to retrieve from user defaults
if let data = UserDefaults.standard.object(forKey: "room") as? Data {
let room = Room(data: data)
}

可以像这样保存/检索房间数组:

func saveRooms(arrayRooms: [Room]) {
let roomsData = arrayRooms.map { $0.encode() }
UserDefaults.standard.set(roomsData, forKey: "rooms")
}

func getRooms() -> [Room]? {
guard let roomsData = UserDefaults.standard.object(forKey: "rooms") as? [Data] else { return nil }
return roomsData.flatMap { return Room(data: $0) }
}


// save 2 rooms to user defaults
let roomA = Room(name: "A", id: "123", booked: true)
let roomB = Room(name: "B", id: "asdf", booked: false)
saveRooms(arrayRooms: [roomA, roomB])

// get the rooms
print(getRooms())

关于ios - 使用 NSKeyedArchiver 和 Userdefault 保存结构数组,其中对象符合 NSCoding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40779910/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com