如何使CoreData模型符合协议?

时间:2019-06-29 01:07:03

标签: swift core-data protocols swift-protocols

我正在尝试制作一个与持久性框架无关的代码库。即我想要面向协议的程序设计,但是在CoreData上无法正常工作。

说我有一个协议:

public protocol BookItem {
  var title: String { get }
  var filename: String { get }
  var createdAt: Date { get }
  var content: BookItemContent? { get }
}

和另一个协议

public protocol BookItemContent {
  var bookItem: BookItem { get }
  var data: Data { get }
}

当我在CoreData中创建具体类型时,我可能会:

class CDBookItem: NSManagedObject, BookItem {

  @NSManaged public var title: String?
  @NSManaged public var filename: String?
  @NSManaged public var createdAt: NSDate?
  @NSManaged public var content: CDBookItemContent?
}

class CDBookItemContent: NSManagedObject, BookItemContent {

  @NSManaged public var data: NSData?
  @NSManaged public var bookItem: CDBookItem?
}

我在这里有3个问题:

1)现在,我有多个具有不同返回类型的属性。 (例如.content属性)

如何最好地解决此问题?最糟糕和肮脏的方法是重命名所有Core-Data属性,然后包装它们以使其一致。

我可以看到的另一种方法是手动生成NSManagedObject子类,然后更改CoreData代码生成的风格,以消除可选项。尽管如此,我仍然剩下content: BookItemContentcontent: CDBookItemContent,所以我不知道是否有一种优雅的方式来做我希望在这里做的事情。我希望我可以声明NSManagedObject子类符合其预期的协议类型,并且编译器可以解决这个问题。

2)核心数据代码生成器使用“ NSObject”类型,而不是现代等效物。 (即NSData而不是Data,NSDate而不是Date)。我可以只修改codegen文件以删除“ NS”并获得免费桥接吗?

3)是否知道CoreData总是在代码生成器中创建可选的对象属性,即使您不希望这样做也是如此?解决方案实际上是覆盖手动生成的文件吗?

1 个答案:

答案 0 :(得分:0)

最后,我发现面向协议的编程并不完全符合承诺。我希望几乎可以用这种方式完成整个代码库。最后,解决方案是使NSManagedObject子类符合协议,方法是必须为协议的属性显式编写访问器,该访问器将一些属性包装在核心数据模型上。即return myManagedObject.contentObject as! BookItemContent