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来更新数据。
核心数据模型
老实说,我不知道该尝试什么,我已经删除了我的火柴盒专业版并从头开始重新安装,尝试了时间机器备份设置重新启动删除容器。我不知道我期待什么,但没想到两个月的代码付诸东流。
我不确定发生了什么变化,但解决方案是声明每个类 @objc 并确保它们都继承自 NSObject。我不知道为什么会这样,但它解决了问题。