首页 > 解决方案 > 将数据存储在核心数据中的自定义类数组中

问题描述

我有一个实体,其中我有一些属性,我将自定义类传递给这些属性,该类将数据存储在该类的数组中 我的核心数据实体看起来像这样,

在此处输入图像描述

我的NSManangedObject班级看起来像这样,

extension SingleChat {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<SingleChat> {
        return NSFetchRequest<SingleChat>(entityName: "SingleChat")
    }

    @NSManaged public var name: String?
    @NSManaged public var roomSID: String?
    @NSManaged public var isGroup: Bool
    @NSManaged public var lastMessage: String?
    @NSManaged public var lastMsgTime: String?
    @NSManaged public var lastMsgTimeActual: String?
    @NSManaged public var profilePic: String?
    @NSManaged public var lastMsgRead: Bool
    @NSManaged public var unReadMsgsCount: Int16
    @NSManaged public var actualNameFor_1_2_1_chat: String?
    @NSManaged public var isNewGroup: Bool
    @NSManaged public var members : [TCHMember]
    @NSManaged public var messages : [TCHMessage]
    @NSManaged public var twChannelObj: TCHChannel?
    @NSManaged public var groupInfo : [String:JSON]?
}

这就是我将数据保存在核心数据中的方式,

 let appDelegate = UIApplication.shared.delegate as? AppDelegate
        let context = appDelegate?.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "SingleChat", in: context!)
        let user = NSManagedObject(entity: entity!, insertInto: context)

        for items in dateWiseSortedSingleRooms
        {
            user.setValue(items.name, forKey: "name")
            user.setValue(items.actualNameFor_1_2_1_chat, forKey: "actualNameFor_1_2_1_chat")
            user.setValue(items.isGroup, forKey: "isGroup")
            user.setValue(items.lastMsgRead, forKey: "lastMsgRead")
            user.setValue(items.lastMsgTimeActual, forKey: "lastMsgTimeActual")
            user.setValue(items.lastMessage, forKey: "lastMessage")
            user.setValue(items.lastMsgTime, forKey: "lastMsgTime")
            user.setValue(items.profilePic, forKey: "profilePic")
            user.setValue(items.roomSID, forKey: "roomSID")
            user.setValue(items.isNewGroup, forKey: "isNewGroup")
            user.setValue(items.unReadMsgsCount, forKey: "unReadMsgsCount")
            user.setValue(items.unReadMsgsCount, forKey: "unReadMsgsCount")
            user.setValue(items.members, forKey: "members")
            user.setValue(items.messages, forKey: "messages")
            user.setValue(items.twChannelObj, forKey: "twChannelObj")
        }

        do {
            try context?.save()
            print("Saved successfully.")
        } catch  {
            print("Fail to save")
        }

现在当我的代码执行应用程序在这一行崩溃时,

user.setValue(items.members, forKey: "members")
user.setValue(items.messages, forKey: "messages")

有了这个错误,

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[TCHMember encodeWithCoder:]:无法识别的选择器发送到实例 0x2807a1780

我该如何解决这个问题?并将我的自定义类数组数据存储在其中?

标签: swiftcore-data

解决方案


如果要在核心数据中存储非标准的对象,对应的属性是 type transformable,这样就可以NSData来回转换。如果对象采用NSCoding 协议
, 则可以做到这一点,这需要实现功能和(在此处描述)。这些函数定义了您的自定义对象的哪些属性必须被存储和恢复。 可以在此处找到如何使用这些功能的示例。encode(with:)init(coder:)

编辑:

还有另一种处理可转换属性的方法:NSCoding您可以实现自定义的,而不是采用协议NSValueTransformer。此类可以独立于您的 3rd 方类实现,请参见此处,并在您的核心数据模型中指定,请参见此处。一个例子可以在这里找到。

编辑2:

我自己没有使用第二种方法,但我的印象是:
为了将自定义对象存储在核心数据中,必须将其转换为NSData,并且在获取期间NSData必须将其转换回您的对象。

一种方法是使用NSCoding,但这需要在自定义类中实现它,可能作为扩展。如果这是不可能的,就像你的情况一样,你可以实现一个自定义NSValueTransformer对象。

对于编码,将您的自定义对象之一作为输入,并根据NSData相关属性创建适当的对象。对于解码,它接受一个NSData对象,并初始化您的自定义对象的新实例,并设置这些属性。

您只需NSValueTransformer在核心数据模型中指定 的名称,核心数据将使用此自定义NSValueTransformer. 你可以在这里找到一个例子


推荐阅读