Coredata Transformable 属性在 macOS 15 升级后不再起作用

问题描述 投票:0回答:1

fault: Could not materialize Objective-C class for declared attribute value class name "ContactContainer" of attribute named contactContainer CoreData: fault: Could not materialize Objective-C class for declared attribute value class name "ContactContainer" of attribute named contactContainer CoreData: Could not materialize Objective-C class for declared attribute value class name "ContactContainer" of attribute named contactContainer

一切都运行良好,直到更改为新的操作系统版本,不确定是否更改了设置或什么。我已经重新安装了整个机器,重新启动,清除了缓存等应用程序不再工作。无法登录或打开任何窗口。

变压器类 ` 进口粉底

@objc(ContactValueTransformer) 公共最终类 ContactValueTransformer: ValueTransformer {

static let name = NSValueTransformerName(rawValue: String(describing: ContactValueTransformer.self))

override public class func transformedValueClass() -> AnyClass {
    ContactContainer.self
}

override public class func allowsReverseTransformation() -> Bool {
    true
}

override public func transformedValue(_ value: Any?) -> Any? {
    guard let contact = value as? ContactContainer else { return nil }
    
    do {
        let data = try JSONEncoder().encode(contact)
        return data
    } catch {
        assertionFailure("Failed to transform `ContactContainer` to `Data`")
        return nil
    }
}

override public func reverseTransformedValue(_ value: Any?) -> Any? {
    if value == nil { return nil }
    guard let data = value as? Data else { return nil }
    
    do {
        return try JSONDecoder().decode(ContactContainer.self, from: data)
    } catch {
        assertionFailure("Failed to transform `Data` to `ContactContainer`")
        return nil
    }
}

    /// Registers the value transformer with `ValueTransformer`.
public static func register() {
    let transformer = ContactValueTransformer()
    ValueTransformer.setValueTransformer(transformer, forName: name)
}

}

添加了 ContactContainer 的代码


import Foundation
import SwiftUI


public class ContactContainer: NSObject, Codable, ObservableObject {
    
    public var phones: [Phone] = [] {
        didSet {
            lastModified = .now
            objectWillChange.send()
        }
    }
    
    public var emails: [Email] = [] {
        didSet {
            lastModified = .now
            objectWillChange.send()
        }
    }
    
    public var addresses: [Address] = [] {
        didSet {
            lastModified = .now
            objectWillChange.send()
        }
    }
        
    private enum CodingKeys: CodingKey {
        case phones
        case emails
        case addresses
        case lastModified
        case dateCreated
    }
    
    public private(set) var lastModified: Date
    public private(set) var dateCreated: Date

    public override init() {
        
        self.phones = []
        self.emails = []
        self.addresses = []
        self.lastModified = .now
        self.dateCreated = .now
        
        super.init()
    }
    
    public init(phone: Phone? = nil, email: Email? = nil, address: Address? = nil) {
        if let phone {
            self.phones = [phone]
        }
        if let email {
            self.emails = [email]
        }
        if let address {
            self.addresses = [address]
        }
        
        self.lastModified = .now
        self.dateCreated = .now
    }

    public init(phones: [Phone] = [], emails: [Email] = [], addresses: [Address] = []) {
        self.phones = phones
        self.emails = emails
        self.addresses = addresses
        self.lastModified = .now
        self.dateCreated = .now
    }
    
    public required init(from decoder: any Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.phones = try container.decode([Phone].self, forKey: .phones)
        self.emails = try container.decode([Email].self, forKey: .emails)
        self.addresses = try container.decode([Address].self, forKey: .addresses)
        self.lastModified = try container.decode(Date.self, forKey: .lastModified)
        self.dateCreated = try container.decode(Date.self, forKey: .dateCreated)
    }
    
    public func encode(to encoder: any Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.phones, forKey: .phones)
        try container.encode(self.emails, forKey: .emails)
        try container.encode(self.addresses, forKey: .addresses)
        try container.encode(self.lastModified, forKey: .lastModified)
        try container.encode(self.dateCreated, forKey: .dateCreated)
    }
    
    public func hasMatch(for searchText: String) -> Bool {
        addresses.hasMatch(for: searchText)
        || phones.hasMatch(for: searchText)
        || emails.hasMatch(for: searchText)
    }
    
    public func copy() throws -> ContactContainer {
        try JSONDecoder().decode(Self.self, from: try JSONEncoder().encode(self))
    }
}

`注意电话地址和电子邮件基本上是相同的 Coddle 协议和实现。 Copy就是获取NSManagedObject来更新数据。

核心数据模型

enter image description here

老实说,我不知道该尝试什么,我已经删除了我的火柴盒专业版并从头开始重新安装,尝试了时间机器备份设置重新启动删除容器。我不知道我期待什么,但没想到两个月的代码付诸东流。

swift xcode macos updates apple-m1
1个回答
0
投票

我不确定发生了什么变化,但解决方案是声明每个类 @objc 并确保它们都继承自 NSObject。我不知道为什么会这样,但它解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.