NSManagedObjectID into NSData

前端 未结 6 2129
一生所求
一生所求 2020-12-30 06:27

I found this wonderful NSManagedObjectID. This would be very good for referencing an Entity/NSManagedObject/NSEntityDescription, right?
Let\'s get an ID from an entity:<

相关标签:
6条回答
  • 2020-12-30 06:52

    Did you look at URIRepresentation? It's easy to convert an NSURL to an NSString, and that to an NSData.

    0 讨论(0)
  • 2020-12-30 06:55

    To get an archived URI corresponding to a NSManagedObject's objectID:

    NSManagedObject* myMO;
    ...
    NSURL *uri = [[myMO objectID] URIRepresentation];
    NSData *uriData = [NSKeyedArchiver archivedDataWithRootObject:uri];
    

    In order to get back to an instance of the original managed object, you need a CoreData stack with the persistent store holding that instance already added to the NSPersistentStoreCoordinator. Then:

    NSData *uriData;
    NSPersistentStoreCoordinator *psc;
    NSManagedObjectContext *moc; //with moc.persistentStoreCoordinator = psc.
    ...
    NSURL *uri = [NSKeyedUnarchiver unarchiveObjectWithData:uriData];
    NSManagedObjectID *moID = [psc managedObjectIDForURIRepresentation:uri];
    NSManagedObject *myMO = [moc objectWithID:moID];
    
    0 讨论(0)
  • 2020-12-30 06:56

    From the NSManagedObjectID documentation:

    Object IDs can be transformed into a URI representation which can be archived and recreated later to refer back to a given object (using managedObjectIDForURIRepresentation: (NSPersistentStoreCoordinator) and objectWithID: (NSManagedObjectContext). For example, the last selected group in an application could be stored in the user defaults through the group object’s ID. You can also use object ID URI representations to store “weak” relationships across persistent stores (where no hard join is possible).

    Just turn it into a URL then turn that into a string or a data.

    0 讨论(0)
  • 2020-12-30 07:02

    You don't need to convert the NSURL into an NSString before archiving. Just archive the NSURL.

    Edit: I've recently learned that an object's ID can change, such as after a migration. It therefore seems like not a good idea to save an ID to disk expecting to be able to reference the object later.

    0 讨论(0)
  • 2020-12-30 07:07

    Here's the cleanest and shortest way I've found to do this currently, using the setURL and getURL methods added in 4.0 to avoid extra calls to NSKeyedUnarchiver and NSKeyedArchiver:

    Setter:

     + (void)storeSomeObjectId:(NSManagedObjectID *)objectId
     {
         [[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation] 
                                                forKey:@"someObjectIdKey"];
         [[NSUserDefaults standardUserDefaults] synchronize];
     }
    

    Getter:

     + (SomeManagedObject *)getObjectByStoredId
     {
         NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"];
         NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri];
         SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId];
     }
    
    0 讨论(0)
  • 2020-12-30 07:13

    As @preston said, don't save an objectID to disk, instead:

    1. Make a new attribute on your entity called "id"
    2. Make a new attribute on your entitys parent entity called "myEntitysMaxId"
    3. Override your entitys parent implementation "addNewMyEntityObject:"
    4. There, increase "myEntitysMaxId" and set that value as the new entitys "id"
    5. Do as you normally do when you fetch an entity based on its attributes!

    Much cleaner and better!

    0 讨论(0)
提交回复
热议问题