Swift 和自定义 Class 作为可转换对象的 CoreData
Swift And CoreData With Custom Class As Transformable Object
我正在尝试使用带有 swift 的自定义 class 和 CoreData 作为可转换对象。我一直在浪费时间试图弄清楚但不能。我不断收到两个错误:属性 无法标记为@NSManaged,因为它的类型无法在 Objective-C 中表示,并且 属性 无法声明 public,因为它的类型使用内部类型。
非常感谢帮助。谢谢。
我有一个名为 User 的 CoreData 对象。我还有一个名为 Site 的对象。
我不希望 Site 对象成为 CoreData 对象,因为在我创建 Site 对象的大多数情况下,我不希望将它添加到 CoreData 上下文中。
下面您将看到 "Site" 类型的 "primarySite" 和 "Site" 类型的数组 "sites"。这两行给出了我上面列出的相同的两个错误。
数据模型
用户+CoreDataClass
import Foundation
import CoreData
public class User: NSManagedObject {
}
用户+CoreDataProperties
import Foundation
import CoreData
extension User {
@nonobjc public class func fetchRequest() -> NSFetchRequest<User> {
return NSFetchRequest<User>(entityName: "User");
}
@NSManaged public var firstName: String?
@NSManaged public var lastName: String?
@NSManaged public var role: String?
@NSManaged public var primarySite: Site
@NSManaged public var sites: [Site]
}
站点
import UIKit
class Site: NSCoding {
let identifier: Int32
let name: String
let note: String
init(with values: Dictionary<String,Any>) {
identifier = Int32(values["identifier"] as! String)!
name = values["name"] as! String
note = values["note"] as! String
}
required convenience init(coder decoder: NSCoder) {
var siteValues = [String:Any]()
siteValues["identifier"] = decoder.decodeObject(forKey: "identifier") as! String
siteValues["name"] = decoder.decodeObject(forKey: "name") as! String
siteValues["note"] = decoder.decodeObject(forKey: "note") as!
self.init(with: siteValues)
}
func encode(with coder: NSCoder) {
coder.encode(String(self.identifier), forKey: "identifier")
coder.encode(self.name, forKey: "name")
coder.encode(self.note, forKey: "note")
}
}
由于 Site 是自定义的 class,您不能将其用作 NSManagedObject 中的数据类型。
就我而言,我在您的 数据模型 中创建了它们的类型 "Binary Data"。
因此,使其类型 NSData 成为 objective c.
中的数据类型
之后,您可以取消存档数据。
例如:
if let sitesArray = NSKeyedUnarchiver.unarchiveObject(with: sites) as? [[String : Any]] {
//enter your processing code here to convert them to site objects
}
Property cannot be marked @NSManaged because its type cannot be represented in Objective-C
发生这种情况是因为 Site
没有继承自 NSObject
。 Swift 类 不必继承自 NSObject
,但 Core Data 可转换对象会继承。如果您添加 NSObject
,则不会发生该错误。
还有一些其他问题——例如,你的 init(coder decoder: NSCoder)
没有分配任何 属性 值——但这些应该很容易弄清楚。
我想出了解决这两个错误的方法。
1) "Property cannot be marked @NSManaged because its type cannot be represented in Objective-C"
感谢@Tom 的回答,我通过使 Site 成为 NSObject.
的子 class 来解决此错误
class Site: NSObject, NSCoding {
2) "Property cannot be declared public because its type uses an internal type"
我通过在 class 之前添加 "public" 以及编码器和解码器函数来解决此错误。
public class Site: NSObject, NSCoding {
...
public func encode(with coder: NSCoder) {...}
public required convenience init(coder decoder: NSCoder) {...}
我正在尝试使用带有 swift 的自定义 class 和 CoreData 作为可转换对象。我一直在浪费时间试图弄清楚但不能。我不断收到两个错误:属性 无法标记为@NSManaged,因为它的类型无法在 Objective-C 中表示,并且 属性 无法声明 public,因为它的类型使用内部类型。
非常感谢帮助。谢谢。
我有一个名为 User 的 CoreData 对象。我还有一个名为 Site 的对象。
我不希望 Site 对象成为 CoreData 对象,因为在我创建 Site 对象的大多数情况下,我不希望将它添加到 CoreData 上下文中。
下面您将看到 "Site" 类型的 "primarySite" 和 "Site" 类型的数组 "sites"。这两行给出了我上面列出的相同的两个错误。
数据模型
用户+CoreDataClass
import Foundation
import CoreData
public class User: NSManagedObject {
}
用户+CoreDataProperties
import Foundation
import CoreData
extension User {
@nonobjc public class func fetchRequest() -> NSFetchRequest<User> {
return NSFetchRequest<User>(entityName: "User");
}
@NSManaged public var firstName: String?
@NSManaged public var lastName: String?
@NSManaged public var role: String?
@NSManaged public var primarySite: Site
@NSManaged public var sites: [Site]
}
站点
import UIKit
class Site: NSCoding {
let identifier: Int32
let name: String
let note: String
init(with values: Dictionary<String,Any>) {
identifier = Int32(values["identifier"] as! String)!
name = values["name"] as! String
note = values["note"] as! String
}
required convenience init(coder decoder: NSCoder) {
var siteValues = [String:Any]()
siteValues["identifier"] = decoder.decodeObject(forKey: "identifier") as! String
siteValues["name"] = decoder.decodeObject(forKey: "name") as! String
siteValues["note"] = decoder.decodeObject(forKey: "note") as!
self.init(with: siteValues)
}
func encode(with coder: NSCoder) {
coder.encode(String(self.identifier), forKey: "identifier")
coder.encode(self.name, forKey: "name")
coder.encode(self.note, forKey: "note")
}
}
由于 Site 是自定义的 class,您不能将其用作 NSManagedObject 中的数据类型。
就我而言,我在您的 数据模型 中创建了它们的类型 "Binary Data"。 因此,使其类型 NSData 成为 objective c.
中的数据类型之后,您可以取消存档数据。
例如:
if let sitesArray = NSKeyedUnarchiver.unarchiveObject(with: sites) as? [[String : Any]] {
//enter your processing code here to convert them to site objects
}
Property cannot be marked @NSManaged because its type cannot be represented in Objective-C
发生这种情况是因为 Site
没有继承自 NSObject
。 Swift 类 不必继承自 NSObject
,但 Core Data 可转换对象会继承。如果您添加 NSObject
,则不会发生该错误。
还有一些其他问题——例如,你的 init(coder decoder: NSCoder)
没有分配任何 属性 值——但这些应该很容易弄清楚。
我想出了解决这两个错误的方法。
1) "Property cannot be marked @NSManaged because its type cannot be represented in Objective-C"
感谢@Tom 的回答,我通过使 Site 成为 NSObject.
class Site: NSObject, NSCoding {
2) "Property cannot be declared public because its type uses an internal type"
我通过在 class 之前添加 "public" 以及编码器和解码器函数来解决此错误。
public class Site: NSObject, NSCoding {
...
public func encode(with coder: NSCoder) {...}
public required convenience init(coder decoder: NSCoder) {...}