Основные данные с преобразуемым атрибутом не удается сохранить

#ios #swift #core-data

Вопрос:

Я хочу использовать CoreData и сохранить атрибут пользовательского класса в одной из сущностей. Способ сделать это, по-видимому, заключается в использовании трансформируемого:

введите описание изображения здесь

А затем я пытаюсь добавить один элемент и сохранить его как:

 import UIKit;
import CoreData;

public class EntityData: NSObject, NSSecureCoding
{
    public static var supportsSecureCoding: Bool { true }

    public func encode(with coder: NSCoder) {
        coder.encode(self.name, forKey: "name");
    }

    public required init?(coder: NSCoder) {
        self.name = coder.decodeObject(forKey: "name") as? String;
    }

    var name: String?;

    init(name: String?) {
        self.name = name;
    }
}

class ViewController: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(_: animated);

        let context  = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext;
        
        let entity = Entity(context: context);
        
        entity.id = URL(string: "google.com");
        entity.data = EntityData(name: "Foo");
        
        do {
            try context.save();
        } catch {
            print("While saveing: (error)");
        }
    }
}

 

Это не удается с:

 2021-09-30 13:12:58.865312 0400 tmpCoreData[5815:170015] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034f6040> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034f6040> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
2021-09-30 13:12:58.865530 0400 tmpCoreData[5815:170015] [error] error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
CoreData: error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
2021-09-30 13:12:58.865983 0400 tmpCoreData[5815:170015] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034e4300> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034e4300> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
2021-09-30 13:12:58.866158 0400 tmpCoreData[5815:170015] [error] error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
CoreData: error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
2021-09-30 13:12:58.866558 0400 tmpCoreData[5815:170015] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034ec0c0> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034ec0c0> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
2021-09-30 13:12:58.900366 0400 tmpCoreData[5815:170015] [error] error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
CoreData: error: -executeRequest: encountered exception = <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo = (null)
2021-09-30 13:12:58.912131 0400 tmpCoreData[5815:170015] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034f83c0> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x6000034f83c0> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
While saveing: Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred."
 

Я не уверен, что делаю что-то не так. Это весь код, который у меня есть, больше я ничего не добавил.

Ответ №1:

Преобразуемый атрибут требует класса, соответствующего NS(Secure)Coding (не Codable !) и реализации архивирования объекта(ов). Обратите внимание на NSSecureUnarchiveFromData ошибки.

В мире Swift рассмотрите возможность объявления атрибута как String , кодирования объекта в JSON с Codable помощью и добавления вычисляемого свойства для плавного преобразования.

Комментарии:

1. Я пытался реализовать NSCoding и NSSecureCoding. Оба они приводят меня к одной и той же ошибке.

2. Добавьте свою реализацию NSCoding и код в (un)архив объекта. Опять же, решение JSON более эффективно.

3. Я добавил реализацию к своему вопросу. Не могли бы вы подробнее рассказать, почему решение JSON более эффективно? Мне фактически пришлось бы отслеживать, когда объект мутирует, чтобы редактировать его json и т. Д.

4. EntityData(name: "Foo") этого недостаточно. Вы должны заархивировать объект с NSKeyedArchiver помощью . NSCoding связано с Objective-C, решение JSON более легкое, потому что оно может обрабатывать даже структуры. И, как уже упоминалось, преобразование проще реализовать. Кстати, это быстро: никаких конечных точек с запятой.

5.PS: Я все равно не понимаю смысла сохранять его String в преобразуемом атрибуте.