Хранить данные в массиве пользовательских классов в основных данных - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть объект, в котором у меня есть некоторые атрибуты, которым я передаю пользовательский класс, который хранит данные в массиве этого класса. Мой основной объект данных выглядит так:

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 голосов
/ 18 февраля 2019

Если вы хотите сохранить нестандартные объекты в основных данных, соответствующий атрибут имеет тип transformable, поэтому его можно преобразовать в NSData и обратно.
Это можно сделать, если объект принимает протокол NSCoding , который требует реализации функций encode(with:) и init(coder:) (описанных там).Эти функции определяют, какие свойства вашего пользовательского объекта должны быть сохранены и восстановлены.
Пример использования этих функций можно найти здесь .

РЕДАКТИРОВАТЬ:

Существует еще один способ обработки трансформируемых атрибутов: вместо принятия протокола NSCoding вы можете реализовать свой собственный NSValueTransformer.Этот класс может быть реализован независимо от ваших сторонних классов, см. Здесь , и указан в вашей базовой модели данных, см. Здесь .Пример можно найти здесь .

РЕДАКТИРОВАТЬ 2:

Я не использовал 2-й метод самостоятельно, но у меня сложилось впечатление:
В целях хранения пользовательского объекта в основных данных,оно должно быть преобразовано в NSData, а во время выборки NSData должно быть преобразовано обратно в ваш объект.

Один из способов сделать это - использовать NSCoding, но для этого необходимо реализовать его в пользовательском классе, возможно, в качестве расширения.Если это невозможно, как в вашем случае, вы можете реализовать пользовательский объект NSValueTransformer.

Для кодирования ему дается один из ваших пользовательских объектов в качестве входных данных, и при необходимости создается NSData объект из соответствующих свойств.Для декодирования он принимает объект NSData, инициализирует новый экземпляр вашего пользовательского объекта и устанавливает эти свойства.

Вам просто нужно указать имя NSValueTransformer в вашей базовой модели данных, и основные данные будут использовать этот пользовательский NSValueTransformer.Вы можете найти пример здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...