核心数据中所有具有自定义类型的属性都必须是关系吗



这是以下评论中的后续问题如何映射嵌套的复杂JSON对象并将其保存到核心数据?。

想象一下,我的应用程序已经有了这个代码。

class Passenger{
var name: String
var number: String
var image : UIImage
// init method
}
class Trip {
let tripNumber : Int
let passenger : Passenger
init(tripNumber: Int, passenger: Passenger) {
self.tripNumber = tripNumber
self.passenger = passenger
}
}

现在我决定为我的应用程序添加持久性。我只是想有一张Trips表。我想显示行程中的乘客,但不需要直接查询乘客的表格。这只是旅行的一个自定义对象/属性。每次我接近乘客都是通过Trips。

那么,有没有一种方法可以让我创建一个名为"TripEntity"的NSManagedObject的新子类,并存储我的乘客——WITH 1。为"Passenger"2创建另一个NSManagedObject子类。在乘客和行程之间建立一种反向关系?简单地说,我只是想让它成为一种属性。从概念上讲,对我来说,这也只是一种属性。这不是真正的关系。。。

还是说,一旦您使用了Core数据,那么每个自定义类型都需要明确地成为NSManagedObject的子类?否则它就不会持久化。我猜这也是对象的意思。你的图表需要完整。忽略图形之外的任何内容。。。

我之所以这么问,是因为我实际想要存储的JSON对象非常庞大,而且我正在努力减少需要做的工作。

您可以将乘客添加到一个Trip实体中,但由于属性类型受到限制,您必须使用transformable类型,这对于归档和取消归档对象来说可能非常昂贵。

如果源数据是JSON,最有效的方法是为PassengerTrip创建核心数据实体并添加反向关系。然后使所有的NSManagedObject类都采用Codable,并在每个类中添加init(from decoderencode(to encoder:方法。

例如,让我们假设Trip类与Passenger有一种多对多的关系,它可能看起来像

@NSManaged public var tripNumber: Int32
@NSManaged public var passengers: Set<Passenger>

并且在CCD_ 10类中存在属性CCD_

@NSManaged public var trip: Trip?

这是CCD_ 13中所需的CCD_。解码器既可以对数组进行解码,也可以对集合进行解码。

private enum CodingKeys: String, CodingKey { case tripNumber, passengers }
public required convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("Context Error") }
let entity = NSEntityDescription.entity(forEntityName: "Trip", in: context)!
self.init(entity: entity, insertInto: context)
let values = try decoder.container(keyedBy: CodingKeys.self)
tripNumber = try values.decode(Int32.self, forKey: .tripNumber)
passengers = try values.decode(Set<Passenger>.self, forKey: .passengers)
passengers.forEach{ $0.trip = self }
}

通过forEach线设置反向关系
您必须添加JSONDecoder的扩展,才能在userInfo对象中传递当前的NSManagedObjectContext

相应的编码器非常简单——

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(tripNumber, forKey: .tripNumber)
try container.encode(passengers, forKey: .passengers)
}

采用CodableNSManagedObject类非常适合从JSON数据预填充数据库或进行JSON备份。

任何自定义属性都需要表示为核心数据属性类型之一。这包括字符串和数值等显而易见的东西。它还包括"二进制",它是任何可以转换为NSData(Swift中的Data)的东西。

根据你的描述,最好的方法可能是

  1. 您的Passenger类采用NSCoding
  2. passenger属性设置为核心数据"可转换"类型。(顺便说一句,这应该是一系列乘客吗?你有一个相关的乘客,但你的问题将其描述为不止一个)
  3. 完成#2之后,将乘客属性的"自定义类"字段设置为类的名称——Passenger

如果执行这两项操作,Core Data将自动调用NSCoding方法,在Passenger类和可以保存在Core Data中的二进制blob之间进行转换。

相关内容

  • 没有找到相关文章

最新更新