Встреча №8. nsincrementalstore, или как заставить core data варить...
TRANSCRIPT
NSIncrementalStoreили как заставить CoreData варить ваш
собственный кофе
Андрей Гусев Ведущий разработчик iOS
NeoSphere LLC
Врем
я
Загрузка Обработка и сохранение
10
8
Получение данных с использованием CoreData
CoreData + NSIncrementalStore =
Как пользоваться
Инициализация
Модель базы данных
Переопределение обязательных методов
+ (void)initialize { [NSPersistentStoreCoordinator registerStoreClass:self forStoreType:[self persistentStoreType]]; }
+ (NSString *)persistentStoreType { return NSStringFromClass(self); }
Инициализация
[_pStoreCoordinator addPersistentStoreWithType:[MyIncrementalStore persistentStoreType] configuration:@"IncrementalStore" URL:incrementalStoreUrl options:nil error:&error]
Методы для переопределения
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
- (NSIncrementalStoreNode *)newValuesForObjectWithID:(NSManagedObjectID *)objectID withContext:(NSManagedObjectContext *)context error:(NSError **)error;
- (id)newValueForRelationship:(NSRelationshipDescription *)relationship forObjectWithID:(NSManagedObjectID *)objectID withContext:(NSManagedObjectContext *)context error:(NSError **)error;
- (BOOL)loadMetadata:(NSError **)error
- (NSArray *)obtainPermanentIDsForObjects:(NSArray *)array error:(NSError **)error;
- (BOOL)loadMetadata:(NSError **)error { NSMutableDictionary *mutableMetadata = [NSMutableDictionary dictionary];
[mutableMetadata setValue:[[NSProcessInfo processInfo] globallyUniqueString] forKey:NSStoreUUIDKey]; [mutableMetadata setValue:[[self class] persistentStoreType] forKey:NSStoreTypeKey];
[self setMetadata:mutableMetadata]; return YES; }
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
if (request.requestType == NSFetchRequestType) { NSFetchRequest *fRequest = (NSFetchRequest *)request; switch (fRequest.resultType) { case NSManagedObjectResultType: case NSManagedObjectIDResultType: {
/* Выборка идентификаторов объектов */
if (fRequest.resultType == NSManagedObjectResultType) {
//результат - массив NSManagedObject-ов (Faults)
} else {
//результат - массив NSManagedObjectID
} } break;
***
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
//Получение CoreData ObjectID для объекта NSManagedObjectID *oid = [self newObjectIDForEntity:entity referenceObject:item];
//Получение fault-а объекта по его CoreData ObjectID [context objectWithID:oid];//Получение исходного referenceObject по CoreData objectID id item = [self referenceObjectForObjectID:oid];
item -> NSString или NSNumber
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
NSManagedObjectID
NSManagedObject
ReferenceObject (item)
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
if (request.requestType == NSFetchRequestType) { NSFetchRequest *fRequest = (NSFetchRequest *)request; switch (fRequest.resultType) {
***
case NSDictionaryResultType: { /* Выборка значений конкретных полей */
//Результат - массив NSDictionary. //Ключи - название полей данных, значения - сами данные
} break; case NSCountResultType: { /* Подсчёт количества объектов */ //Результат - массив, состоящий из одного NSNumber-а
} break;
- (id)executeRequest:(NSPersistentStoreRequest *)request withContext:(NSManagedObjectContext *)context error:(NSError **)error
***
else if (request.requestType == NSSaveRequestType) { /*
Обработка NSSaveChangesRequest: - (NSSet *)deletedObjects
- (NSSet *)insertedObjects
- (NSSet *)updatedObjects
- (NSSet *) lockedObjects */
//результат - пустой массив. }
- (NSIncrementalStoreNode *)newValuesForObjectWithID:(NSManagedObjectID *)objectID withContext:(NSManagedObjectContext *)context error:(NSError **)error;
/* Выбрать все данные для объекта с заданным ObjectID */
/* Заполнить NSDictionary полученными значениями:
Ключ - название поля объекта в DataModel Значение - конкретное значение для объекта
*/
return [[NSIncrementalStoreNode alloc] initWithObjectID:objectID withValues:objectDataDict version:version];
- (id)newValueForRelationship:(NSRelationshipDescription *)relationship forObjectWithID:(NSManagedObjectID *)objectID withContext:(NSManagedObjectContext *)context error:(NSError **)error;
if (relationship.isToMany) {
return [NSManagedObject, NSManagedObject, ...] или [] } else {
return NSManagedObject или [NSNull null] }
- (NSArray *)obtainPermanentIDsForObjects:(NSArray *)array error:(NSError **)error;
Вопросы?!
Полезные ссылки
Демонстрационное приложение: https://github.com/GusevAndrey/NSIncrementalStoreInUse
Programming Guide: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/IncrementalStorePG/Introduction/Introduction.html
Class reference: https://developer.apple.com/library/ios/documentation/CoreData/Reference/NSIncrementalStore_Class/Reference/NSIncrementalStore.html
Пара статей по NSIncrementalStore: http://nshipster.com/nsincrementalstore/ http://sealedabstract.com/code/nsincrementalstore-the-future-of-web-services-in-ios-mac-os-x/
Статья о реализации загрузки данных с сервера в CoreData: http://chris.eidhof.nl/post/17826914256/accessing-an-api-using-coredatas-nsincrementalstore
Живой проект AFNetworking + NSIncrementalStore: https://github.com/AFNetworking/AFIncrementalStore
Приложение Looky: https://itunes.apple.com/ru/app/id579331601