将数据存储在核心数据的自定义类数组中

时间:2019-02-18 12:05:30

标签: swift core-data

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

enter image description here

我的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

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

1 个答案:

答案 0 :(得分:0)

如果要将非标准对象存储在核心数据中,则对应的属性为transformable类型,以便可以将其转换为NSData并返回。
如果对象采用NSCoding protocol,而这需要实现功能encode(with:)init(coder:)(在此进行描述),则可以完成此操作。这些函数定义必须存储和还原自定义对象的哪些属性。
here是如何使用这些功能的示例。

编辑:

还有另一种处理可变形属性的方法:您可以实施自定义NSCoding,而不是采用NSValueTransformer协议。该类可以独立于您的第三方类see here来实现,并在您的核心数据模型see here中指定。可以找到一个示例here

编辑2:

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

一种实现方法是使用NSCoding,但这需要在自定义类中实现它,可能是作为扩展。如果您无法做到这一点,则可以实现自定义NSValueTransformer对象。

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

您只需在核心数据模型中指定NSValueTransformer的名称,核心数据将使用此自定义NSValueTransformer。您可以找到一个example here