Лучшие практики для временных объектов в RestKit с Core Data - PullRequest
6 голосов
/ 27 марта 2012

Фон: у меня есть управляемый объект, машина.У меня есть API поиска RESTful на localhost / cars / search.Возвращенные результаты являются объектами Car со стороны сервера, но я хочу сохранить только тот, который выбирает пользователь.Остальные машины, которые я хочу отбросить, когда они возвращаются из поиска.

Сначала я был похож на:

@interface Car : NSManagedObject  //<--- managed object

    @property (nonatomic, strong) NSNumber* year;
    @property (nonatomic, strong) NSString* make;
    @property (nonatomic, strong) NSString* model;

@end

@interface TransientCar : NSObject //<--- regular NSObject!

    @property (nonatomic, strong) NSNumber* year;
    @property (nonatomic, strong) NSString* make;
    @property (nonatomic, strong) NSString* model;

@end

Я отображал результаты поиска REST API JSON в TransientCarобъекты для целей отображения результатов поиска, но не для сохранения их в контексте.По умолчанию, если вы сопоставляете управляемый объект, RestKit вызовет фабрику удобства + объекта, чтобы создать объект и вставить его в текущий контекст (жестко запрограммированный в контекст хранилища объектов sharedManager, кстати!)

Это казалосьнеустойчивый.Так что теперь я просто использую NSMutableDictionary для хранения данных результатов поиска, пока пользователь не коснется подробного представления и не сделает что-то стоящее для сохранения реального управляемого объекта для:

RKObjectMapping* tempCarMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[tempCarMapping mapKeyPathsToAttributes:
 @"year", @"year",
 @"make", @"make",
 @"model", @"model",
 nil];

Это хорошая практика?Используя NSMutableDictionary как временное представление, пока пользователь не сделает что-то, что оправдывает вставку нового объекта в контекст?Я был фанатом использования исходного подкласса управляемых объектов для представления данных, но каким-то образом смог пометить его как «не хранить» или что-то в этом роде, но каждый раз, когда я делаю это, я чувствую, что борюсь с фреймворком(и условия гонки).Я также попытался использовать контекст с нулями / выбрасыванием, создав новый RKObjectManager и просто очистив весь его контекст после этого, но метод + managedObjectContext в категории ActiveRecord в RestKit жестко задан для возврата:

[[[RKObjectManager sharedManager] objectStore] managedObjectContext];

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

Ответы [ 3 ]

5 голосов
/ 01 ноября 2012

К сожалению, у меня пока нет достаточной репутации StackOverflow, чтобы поместить этот ответ на место (как комментарии к другим ответам), но я хотел добавить несколько моментов.

Я считаю, что ответ Эвана Корделла ошибочен. Текущая версия restkit (0.10.x) не позволяет создавать контексты для использования RKManagedObjectLoaders, а RKObjectManagers может хранить хранилище, но оно должно иметь тип RKManagedObjectStore, который явно привязан к sqllite. Dev-версия restkit (0.20) явно ослабляет это, поэтому вы можете сохранить данные в базе данных в памяти. Я попытался переопределить методы RKManagedObjectStore, чтобы использовать предоставленный мною контекст, но он не сработал ... во всяком случае, исправление кажется нетривиальным.

Другая приведенная ссылка, Лучший подход для создания временного объекта для базовых данных с помощью Restkit , похоже, связана с публикацией объекта и получением того же объекта в ответе. Это другая проблема, чем была поставлена ​​в этом вопросе.

До тех пор, пока не будет выпущен v.0.20.x, который, как мы надеемся, скоро будет, кажется, что параллельная иерархия классов является единственным выбором. Если я ошибаюсь, я приветствую исправление в этом пункте!

3 голосов
/ 02 апреля 2012

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

Что касается других ваших попыток, я не думаю, что библиотека заставляет вашу руку так сильно, как вы думаете.Посмотрите на API для RKManagedObjectStore и NSManagedObject+ActiveRecord.В частности, RKManagedObjectStore имеет свойство managedObjectContext, метод - (NSManagedObjectContext*)newManagedObjectContext и несколько методов для объединения изменений.

Вы правы, что [NSManagedObject managedObjectContext] всегда возвращает контекст sharedManager - но это имеет смысл, это метод класса.Иначе как класс узнает, какой контекст вернуть?Но это спорный вопрос, поскольку существует множество других способов создания новых контекстов и доступа к ним.Или, полностью обходя это, вы можете просто сохранить ссылку на ваш временный контекст и использовать его напрямую.

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

Параметр NSMutableDictionary не так гибок, как другие методы, но я бы не сказал, что это «плохая практика».

2 голосов
/ 28 июня 2012

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

Это позволит избежать проблемы переходного объекта, упомянутой в ответе Эвана Корделла, который являетсяосновной вкладчик в RestKit.

...