如何持久存储 NSManagedObjectID?

Swe*_*per 4 persistence core-data ios swift

为了避免成为 XY 问题,这里有一些背景知识:

我的应用程序允许用户创建和保存许多设置,有点像 Xcode 的字体和颜色选择器:

在此输入图像描述

这是因为用户可以设置很多东西。只需点击保存的设置而不是再次设置所有这些内容会更容易。

我使用 Core Data 来存储用户保存的设置。用户创建的每个设置都是NSManagedObject子类的一个实例。现在我需要持久存储所选的设置,以便用户在应用程序重新打开时选择与以前相同的设置。

我的第一个想法是将子类实例存储NSManagedObjectNSUserDefaults. 但根据文档,我无法存储它,除非将其转换为NSData

默认对象必须是属性列表,即 NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary 的实例(或集合的实例组合)。

然后我尝试存储子objectIDNSManagedObject实例的。我看到有一个URIRepresentation()方法返回NSURL. 所以我认为这会起作用:

NSData(contentsOfURL: selectedOption!.objectID.URIRepresentation())
Run Code Online (Sandbox Code Playgroud)

但初始化程序不知何故失败了。

现在我意识到这是一个愚蠢的想法,因为即使我可以将其转换为NSData,我也无法转换NSDataNSManagedObjectID

根据这个问题,OP似乎能够存储对象ID:

我将选定的主题 objectID 存储在 NSUserDefaults 中,以便当应用程序重新启动时,选定的主题仍然完好无损。

我怎样才能做到这一点?

Mar*_*n R 6

NSUserDefaults有“便捷方法”

public func setURL(url: NSURL?, forKey defaultName: String)
public func URLForKey(defaultName: String) -> NSURL?
Run Code Online (Sandbox Code Playgroud)

它允许存储和检索NSURL像通过 获得的那样URIRepresentation()。来回转换NSData 是透明处理的。从文档中:

当使用 NSURL 存储时-[NSUserDefaults setURL:forKey:],会进行一些调整:

  1. 任何非文件 URL 都是通过+[NSKeyedArchiver archivedDataWithRootObject:]使用 NSURL 实例作为根对象进行调用来写入的。
  2. ...

当使用读取 NSURL 时-[NSUserDefaults URLForKey:],将使用以下逻辑:

  1. 如果键的值是 NSData,则 NSData 将用作 的参数+[NSKeyedUnarchiver unarchiveObjectWithData:]。如果 NSData 可以作为 NSURL 解档,则返回 NSURL,否则返回 nil。
  2. ...

因此,保存托管对象 ID 的操作很简单:

NSUserDefaults.standardUserDefaults().setURL(object.objectID.URIRepresentation(),
                                             forKey: "selected")
Run Code Online (Sandbox Code Playgroud)

并检索对象 ID 和对象,例如如下所示:

if let url = NSUserDefaults.standardUserDefaults().URLForKey("selected"),
    let oid = context.persistentStoreCoordinator!.managedObjectIDForURIRepresentation(url),
    let object = try? context.existingObjectWithID(oid) {

    print(object)
    // ...
}
Run Code Online (Sandbox Code Playgroud)

有关保存所选设置的替代方法,请参阅上面的评论