NSManagedObjectID em NSData
Pergunta
Eu encontrei esta maravilhosa NSManagedObjectID. Isso seria muito bom para fazer referência a uma entidade / NSManagedObject / NSEntityDescription, certo?
Vamos obter uma ID de uma entidade:
NSEntityDescription *entity = [self newEntity];
NSManagedObjectID *objID = [entity objectID];
Então ... alguma idéia de como obter este objID
em uma string? Ou melhor: NSData. Realmente algo para ser capaz de salvá-lo para as NSUserDefaults. ;-)
Btw: NSFetchRequest não quer trabalhar no meu caso. Eu uso uma versão modificada deste exemplo:. de uma velha questão
Solução
Para se ter uma URI arquivados correspondente a NSManagedObject
um objectID
:
NSManagedObject* myMO;
...
NSURL *uri = [[myMO objectID] URIRepresentation];
NSData *uriData = [NSKeyedArchiver archivedDataWithRootObject:uri];
Para voltar a uma instância do objeto gerenciado original, você precisa de uma pilha CoreData com o armazenamento persistente segurando essa instância já adicionado para o NSPersistentStoreCoordinator
. Então:
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];
Outras dicas
De documentação do NSManagedObjectID :
identificações de objeto pode ser transformado em um representação URI que pode ser arquivados e recriado depois de se referir de volta para um dado objecto (usando managedObjectIDForURIRepresentation: (NSPersistentStoreCoordinator) e objectWithID: (NSManagedObjectContext). Por exemplo, o último grupo selecionado em um aplicação pode ser armazenado no padrões de utilizador, através do grupo ID do objeto. Você também pode usar objeto representações ID URI a loja “fraco” relações em lojas persistentes (Onde se juntar sem disco é possível).
Apenas transformá-lo em uma URL, em seguida, transformar isso em uma cadeia ou uma dados.
Você olha para URIRepresentation ? É fácil converter um NSURL a um NSString, e que a um NSData.
Você não precisa converter o NSURL em um NSString antes de arquivar. Apenas arquivar o NSURL.
Editar: Eu aprendi recentemente que ID de um objeto pode mudar, como após uma migração. Parece, portanto, como não é uma boa idéia para salvar um ID para o disco esperando para ser capaz de referenciar o objeto mais tarde.
Aqui é a maneira mais limpa e mais curto que eu encontrei para fazer isso atualmente, usando o setURL e métodos getURL adicionado no 4.0 para evitar chamadas extras para NSKeyedUnarchiver e 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];
}
Como @preston disse: Não guardar um objectID no disco, em vez disso:
- Faça um novo atributo no seu entidade chamada "id"
- Faça um novo atributo no seu entidade pai entitys chamado "myEntitysMaxId"
- Substituir o seu entitys implementação pai "addNewMyEntityObject:"
- Não, aumento "myEntitysMaxId" e defina esse valor como os novos entitys "id"
- Faça o que você faz normalmente quando você buscar uma entidade com base em seus atributos!
Muito mais limpo e melhor!