如何持久存储NSManagedObjectID?

时间:2016-08-15 10:40:56

标签: ios swift core-data persistence

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

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

enter image description here

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

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

我的第一个想法是将NSManagedObject子类实例存储在NSUserDefaults中。但根据文档,除非我将其转换为NSData,否则我无法存储它:

  

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

然后我尝试存储objectID子类实例的NSManagedObject。我看到有URIRepresentation()方法返回NSURL。所以我认为这会奏效:

NSData(contentsOfURL: selectedOption!.objectID.URIRepresentation())

但初始化程序以某种方式失败了。

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

根据this question,OP似乎能够存储对象id:

  

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

我该怎么做?

1 个答案:

答案 0 :(得分:3)

NSUserDefaults有"便利方法"

public func setURL(url: NSURL?, forKey defaultName: String)
public func URLForKey(defaultName: String) -> NSURL?

允许存储和检索与获得的NSURL类似的URIRepresentation()NSData。转换为-[NSUserDefaults setURL:forKey:]的转换 处理透明。来自documentation

  

使用+[NSKeyedArchiver archivedDataWithRootObject:]存储NSURL时,会进行一些调整:

     
      
  1. 通过使用NSURL实例作为根调用-[NSUserDefaults URLForKey:]来编写任何非文件URL   宾语。
  2.   
  3. ...
  4.         

    使用+[NSKeyedUnarchiver unarchiveObjectWithData:]读取NSURL时,使用以下逻辑:

         
        
    1. 如果键的值是NSData,则NSData用作NSUserDefaults.standardUserDefaults().setURL(object.objectID.URIRepresentation(), forKey: "selected") 的参数。如果NSData可以作为NSURL解压缩,则返回NSURL,否则返回nil。
    2.   
    3. ...
    4.   

因此,保存托管对象ID只需完成

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

    print(object)
    // ...
}

并检索对象ID和对象,例如:

{{1}}

有关保存所选设置的其他方法,请参阅the above comment