【问题标题】:CoreData with transformable attribute fails on save具有可转换属性的 CoreData 在保存时失败
【发布时间】:2021-11-22 00:26:10
【问题描述】:

我想使用 CoreData 并将自定义类属性保存在其中一个实体中。这样做的方法似乎是使用 Transformable:

然后我尝试添加单个元素并将其保存为:

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."

我不确定我做错了什么。这是我所有的代码,我没有添加任何其他内容。

【问题讨论】:

    标签: ios swift core-data


    【解决方案1】:

    可转换属性需要符合NS(Secure)Coding(不是Codable!)的类以及归档对象的实现。注意NSSecureUnarchiveFromData 错误。

    在 Swift 世界中,考虑将属性声明为 String,使用 Codable 将对象编码为 JSON,并添加计算属性以进行无缝转换。

    【讨论】:

    • 我试过实现 NSCoding 和 NSSecureCoding。他们都给了我同样的错误。
    • 添加 NSCoding 的实现和代码以(取消)归档对象。同样,JSON 解决方案更高效。
    • 我将实现添加到我的问题中。您能否详细说明为什么 JSON 解决方案更高效?我必须有效地跟踪对象何时变异以编辑其 json 等。
    • EntityData(name: "Foo") 是不够的。您必须使用NSKeyedArchiver 归档对象。 NSCoding 与 Objective-C 相关,JSON 解决方案更轻量级,因为它甚至可以处理结构。如前所述,转换更容易实现。顺便说一句,这是 Swift:没有尾随分号。
    • PS:我不明白将 one String 保存在可转换属性中的意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2016-08-14
    相关资源
    最近更新 更多