Salvar CoreData-entidades em NSUserDefaults
-
20-08-2019 - |
Pergunta
Imagine que uma entidade CoreData (por exemplo chamado searchEngine
).
NSManagedObjectContext
administra alguns "casos" desta entidade.
O usuário final vai ser capaz de selecionar sua "standard searchEngine"
com um NSPopupButton
.
O selected object
de NSPopupButton deve ser binded aos NSUserDefaults.
O problema:
1)
@try {Salvar}
a)
Se você tentar salvar a "instância" selecionada diretamente para NSUserDefaults lá vem algo como isto:-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60 ; data: { url = "http://google.de/"; someAttribute = 1; name = "google"; })' of class 'searchEngine'.
b)
Se você tentar converter o "exemplo" para NSData vem esta:-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0
Assim, qualquer idéia de como obter este entidades em um dados plist compatível?
2)
@try {registerDefaults}Normalmente, o método
registerDefaults:
é implementado em+ (void)initialize
. O problema aqui é que este método é chamado antes CoreData carrega as entidades salvas de seu banco de dados. Então eu não posso definir um padrão para um objeto não-existente, certo?
Eu sei, perguntas longas ... mas: try {[me fornecer: detalhes]}; D
Solução
Você não gostaria de tentar arquivar uma entidade de dados núcleo e armazená-lo. Em vez disso, você iria armazenar a chave ou algum outro atributo conhecido e usá-lo para buscar a entidade quando o aplicativo é iniciado.
Alguns códigos de exemplo (ligeiramente modificado a partir do exemplo postado no núcleo de dados Guia de Programação ):
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:@"SearchEngine" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"engineName LIKE[c] '%@'", selectedEngineName];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
// Deal with error...
}
Desta forma, você salvar o nome nos padrões do usuário e buscar a entidade quando necessário.
Outras dicas
Se você precisa armazenar uma referência a um objeto específico gerenciado, use a representação URI de seu ID objeto gerenciado:
NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];
Você pode salvar a URL para os padrões do usuário.
Para recuperar o objeto gerenciado, você usa:
NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];
A única ressalva é que você deve garantir que o original ID objeto gerenciado é permanente -. Isso não é um problema se você já salvou o objeto, alternativamente, você pode usar obtainPermanentIDsForObjects:error:
Aqui é a maneira mais limpa e mais curto para atualmente fazer isso 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];
}