Сохранить CoreData-сущности в NSUserDefaults - PullRequest
18 голосов
/ 01 февраля 2009

Представьте сущность CoreData (например, с именем searchEngine).
NSManagedObjectContext управляет некоторыми "экземплярами" этой сущности.
Конечный пользователь сможет выбрать "standard searchEngine" с помощью NSPopupButton.
selected object NSPopupButton должен быть привязан к NSUserDefaults.
Проблема:

1) @try {save}

a) Если вы попытаетесь сохранить выбранный «экземпляр» непосредственно в NSUserDefaults, произойдет нечто вроде этого:

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60  ; data: {
    url = "<a href="http://google.de/" rel="noreferrer">http://google.de/</a>";
    someAttribute = 1;
    name = "google";
})' of class 'searchEngine'.

b) Если вы попытаетесь преобразовать «экземпляр» в NSData, то получите:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0

Так есть идеи, как получить эти объекты в plist-совместимых данных?

2) @try {registerDefaults}

Обычно метод registerDefaults: реализован в + (void)initialize. Проблема здесь заключается в том, что этот метод вызывается до того, как CoreData загрузит сохраненные объекты из своей базы данных. Так что я не могу установить значение по умолчанию для несуществующего объекта, верно?

Я знаю, длинные вопросы ... но: попробуй {[я предоставлю: подробности]}; D

Ответы [ 3 ]

35 голосов
/ 07 июля 2009

Если вам нужно сохранить ссылку на определенный управляемый объект, используйте представление URI его идентификатора управляемого объекта:

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];

Затем можно сохранить URL-адрес по умолчанию для пользователя.

Для извлечения управляемого объекта вы используете:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];

Единственное предостережение: вы должны убедиться, что исходный идентификатор управляемого объекта является постоянным - это не проблема, если вы уже сохранили объект, или вы можете использовать obtainPermanentIDsForObjects:error:.

7 голосов
/ 29 декабря 2013

Вот самый чистый и кратчайший способ сделать это в настоящее время, используя методы setURL и getURL, добавленные в 4.0, чтобы избежать дополнительных вызовов NSKeyedUnarchiver и NSKeyedArchiver:

сеттер:

 + (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];
 }
6 голосов
/ 01 февраля 2009

Вы не захотите пытаться заархивировать объект основных данных и сохранить его. Вместо этого вы должны сохранить ключ или какой-либо другой известный атрибут и использовать его для извлечения сущности при запуске приложения.

Пример кода (слегка измененный по сравнению с примером, опубликованным в Руководство по программированию базовых данных ):

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...
}

Таким образом, вы сохраняете имя пользователя по умолчанию и извлекаете сущность при необходимости.

...