#mbltdev: core data: особенности использования и синхронизация...

Post on 26-Jun-2015

851 Views

Category:

Mobile

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

#MBLTdev: Конференция мобильных разработчиков Спикер: Руслан Шевчук iOS-разработчик, Aviasales http://mbltdev.ru/

TRANSCRIPT

Core Data: особенности использования и синхронизация в iCloud

Руслан ШевчукiOS-разработчик, Aviasales

Road Map• Задачи, которые решаются в приложении Aviasales с помощью

Core Data

• Дизайн модели и устройство стека в приложении Aviasales

• Особенности работы с большими объемами данных, многопоточность, производительность и совместное использование данных между контекстами

• Синхронизация Core Data с помощью iCloud: сопутствующие проблемы

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Другие полезные функции Core Data

• Отслеживание изменений и поддержка Undo/Redo операций

• Автоматическая валидация свойств объекта

• Сложные запросы на получение данных из хранилища

• Сортировка и фильтрация

Особенности Core Data

• Объектный граф

• Faulting

• Версионность моделей баз данных

• Поддержка KVO

• Синхронизация пользовательских данных c помощью iCloud

Стек

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

SQLite

FileSystem

Стек в приложении Aviasales

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

SQLite

FileSystem

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

In-Memory

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

iCloud

Данные внутри приложения

1. Временные данные

2. Данные, которые мы хотим хранить

3. Данные, которые мы хотим синхронизировать между устройствами

3 хранилища данных – одна модель

1 2 3NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

SQLite

FileSystem

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

In-Memory

NSManagedObjectContext

NSManagedObject

NSManagedObject

NSManagedObject

NSPersistantStore Coordinator

NSPesistantStore

iCloud

Потоковая безопасность

NSManagedObjectContext -initWithConcurrencyType:

Потоковая безопасность

NSManagedObjectContext -initWithConcurrencyType:

• NSConfinementConcurrencyType

• NSPrivateQueueConcurrencyType

• NSMainQueueConcurrencyType

Сonfinement Concurrency

NSManagedObjectContext -init

• Отдельные контексты в каждом используемом потоке

• Контекст (MOC) такого типа может использоваться только в рамках потока или создавшей его очереди

• Устаревший тип контекста, тип по умолчанию для обратной совместимости

Сonfinement Concurrency

NSManagedObjectContext -init

• Отдельные контексты в каждом используемом потоке

• Контекст (MOC) такого типа может использоваться только в рамках потока или создавшей его очереди

• Устаревший тип контекста, тип по умолчанию для обратной совместимости

Сonfinement Concurrency

NSManagedObjectContext -init

• Отдельные контексты в каждом используемом потоке

• Контекст (MOC) такого типа может использоваться только в рамках потока или создавшей его очереди

• Устаревший тип контекста, тип по умолчанию для обратной совместимости

Private QueueNSManagedObjectContext -initWithConcurrencyType:

• MOC обладает своей личной очередью

• Может использоваться только в рамках этой очереди

• При использовании контекста из других потоков предыдущее условие выполняется помещением задач в очередь блоками -performBlock: и -performBlockAndWait:

• Сore Data API может безопасно использоваться внутри блоков

Private QueueNSManagedObjectContext -initWithConcurrencyType:

• MOC обладает своей личной очередью

• Может использоваться только в рамках этой очереди

• При использовании контекста из других потоков предыдущее условие выполняется помещением задач в очередь блоками -performBlock: и -performBlockAndWait:

• Сore Data API может безопасно использоваться внутри блоков

Private QueueNSManagedObjectContext -initWithConcurrencyType:

• MOC обладает своей личной очередью

• Может использоваться только в рамках этой очереди

• При использовании контекста из других потоков предыдущее условие выполняется помещением задач в очередь блоками -performBlock: и -performBlockAndWait:

• Сore Data API может безопасно использоваться внутри блоков

Private QueueNSManagedObjectContext -initWithConcurrencyType:

• MOC обладает своей личной очередью

• Может использоваться только в рамках этой очереди

• При использовании контекста из других потоков предыдущее условие выполняется помещением задач в очередь блоками -performBlock: и -performBlockAndWait:

• Сore Data API может безопасно использоваться внутри блоков

Преимущества Private Queue над Confinement Concurrency

• MOC отвечает за доставку блока в правильную очередь

• Возможность производить операции из любого потока с помощью -performBlock: или -performBlockAndWait:

• Неиспользуемая очередь более эффективна, чем дополнительный поток

Преимущества Private Queue над Confinement Concurrency

• MOC отвечает за доставку блока в правильную очередь

• Возможность производить операции из любого потока с помощью -performBlock: или -performBlockAndWait:

• Неиспользуемая очередь более эффективна, чем дополнительный поток

Преимущества Private Queue над Confinement Concurrency

• MOC отвечает за доставку блока в правильную очередь

• Возможность производить операции из любого потока с помощью -performBlock: или -performBlockAndWait:

• Неиспользуемая очередь более эффективна, чем дополнительный поток

Main Queue

NSManagedObjectContext -initWithConcurrencyType:

• Особености аналогичны NSPrivateQueueConcurrencyType

• Очередь всегда находится в главном потоке

• Обращение из других потоков помощью блока -performBlock:

Main Queue

NSManagedObjectContext -initWithConcurrencyType:

• Особености аналогичны NSPrivateQueueConcurrencyType

• Очередь всегда находится в главном потоке

• Обращение из других потоков помощью блока -performBlock:

Main Queue

NSManagedObjectContext -initWithConcurrencyType:

• Особености аналогичны NSPrivateQueueConcurrencyType

• Очередь всегда находится в главном потоке

• Обращение из других потоков c помощью блока -performBlock:

Потоковая безопасность

NSManagedObjectContext -initWithConcurrencyType:

• NSConfinementConcurrencyType

• NSPrivateQueueConcurrencyType

• NSMainQueueConcurrencyType

Использование Core Data с несколькими потоками

NSManagedObjectID – универсальный потокобезопасный идентификатор

• Временный

• Постоянный

Использование Core Data с несколькими потоками

NSManagedObjectID – универсальный потокобезопасный идентификатор

• Временный

• Постоянный

Временный NSManagedObjectID

• Временным идентификатором обладает NSManagedObject ранее никогда не попадавший в NSPersistenStore

• Невозможно получить материализацию объекта в другом контексте, используя временный идентификатор

Временный NSManagedObjectID

• Временным идентификатором обладает NSManagedObject ранее никогда не попадавший в NSPersistenStore

• Невозможно получить материализацию объекта в другом контексте, используя временный идентификатор

Постоянный NSManagedObjectID

• Постоянным идентификатор становится сразу после первого сохранения объекта в хранилище

• Начиная с этого момента, вы можете рематериализовать объект в другом контексте с помощью метода контекста NSManagedObjectContext -objectWithID:

• Используйте NSManagedObjectID в случае необходимости передачи объекта из одного контекста в другой

Постоянный NSManagedObjectID

• Постоянным идентификатор становится сразу после первого сохранения объекта в хранилище

• Начиная с этого момента, вы можете рематериализовать объект в другом контексте с помощью метода контекста NSManagedObjectContext -objectWithID:

• Используйте NSManagedObjectID в случае необходимости передачи объекта из одного контекста в другой

Постоянный NSManagedObjectID

• Постоянным идентификатор становится сразу после первого сохранения объекта в хранилище

• Начиная с этого момента, вы можете рематериализовать объект в другом контексте с помощью метода контекста NSManagedObjectContext -objectWithID:

• Используйте NSManagedObjectID в случае необходимости передачи объекта из одного контекста в другой

Совместное использование несохраненных изменений между контекстами

Вложенные контексты

• Совместное использование несохраненных изменений между контекстами

MOC 1 Parent

NSPersistantStore

MOC 2 Child

Вложенные контексты

• Родительский контекст является для дочернего хранилищем данных

• Изменения, совершенные в дочернем контексте, при его сохранении передаются его родителю

• Возможность использовать временные NSManagedObjectID для передачи данных между вложенными контекстами

Вложенные контексты

• Родительский контекст является для дочернего хранилищем данных

• Изменения, совершенные в дочернем контексте, при его сохранении передаются его родителю

• Возможность использовать временные NSManagedObjectID для передачи данных между вложенными контекстами

Вложенные контексты

• Родительский контекст является для дочернего хранилищем данных

• Изменения, совершенные в дочернем контексте, при его сохранении передаются его родителю

• Возможность использовать временные NSManagedObjectID для передачи данных между вложенными контекстами

Особенности вложенных контекстов• Могут использоваться для передачи несохраненных данных между вложенными контекстами

• Контекст, сохраняя изменения, передает их на один уровень выше

• Метод NSManagedObjectContext -objectWithID: вернет объект в том состоянии в котором сможет его обнаружить на одном из самых ближайших уровней

• Родительский контекст должен иметь тип NSPrivateQueueConcurrencyType или NSMainQueueConcurrencyType

Особенности вложенных контекстов• Могут использоваться для передачи несохраненных данных между вложенными контекстами

• Контекст, сохраняя изменения, передает их на один уровень выше

• Метод NSManagedObjectContext -objectWithID: вернет объект в том состоянии в котором сможет его обнаружить на одном из самых ближайших уровней

• Родительский контекст должен иметь тип NSPrivateQueueConcurrencyType или NSMainQueueConcurrencyType

Особенности вложенных контекстов• Могут использоваться для передачи несохраненных данных между вложенными контекстами

• Контекст, сохраняя изменения, передает их на один уровень выше

• Метод NSManagedObjectContext -objectWithID: вернет объект в том состоянии в котором сможет его обнаружить на одном из самых ближайших уровней

• Родительский контекст должен иметь тип NSPrivateQueueConcurrencyType или NSMainQueueConcurrencyType

Особенности вложенных контекстов• Могут использоваться для передачи несохраненных данных между вложенными контекстами

• Контекст, сохраняя изменения, передает их на один уровень выше

• Метод NSManagedObjectContext -objectWithID: вернет объект в том состоянии в котором сможет его обнаружить на одном из самых ближайших уровней

• Родительский контекст должен иметь тип NSPrivateQueueConcurrencyType или NSMainQueueConcurrencyType

iCloud Core Data

• Позволяет решить задачу синхронизации пользовательских данных

• Накладывает определенные ограничения на то, как вы будете использовать Core Data.

iCloud Core Data

• Позволяет решить задачу синхронизации пользовательских данных

• Накладывает определенные ограничения на то, как вы будете использовать Core Data.

iCloud Core Data

• Позволяет решить задачу синхронизации пользовательских данных

• Накладывает определенные ограничения на то, как вы будете использовать Core Data

Задачи, которые решает iCloud в приложении Aviasales

• Синхронизация хранилища данных

• Авторизация пользователя и смена аккаунтов

• Снимает необходимость в хранении пользовательских данных на наших серверах и разработки API для транспортировки этих данных

• Быстрый отклик системы (multi-master replication)

Задачи, которые решает iCloud в приложении Aviasales

• Синхронизация хранилища данных

• Авторизация пользователя и смена аккаунтов

• Снимает необходимость в хранении пользовательских данных на наших серверах и разработки API для транспортировки этих данных

• Быстрый отклик системы (multi-master replication)

Задачи, которые решает iCloud в приложении Aviasales

• Синхронизация хранилища данных

• Авторизация пользователя и смена аккаунтов

• Снимает необходимость в хранении пользовательских данных на наших серверах и разработки API для транспортировки этих данных

• Быстрый отклик системы (multi-master replication)

Задачи, которые решает iCloud в приложении Aviasales

• Синхронизация хранилища данных

• Авторизация пользователя и смена аккаунтов

• Снимает необходимость в хранении пользовательских данных на наших серверах и разработки API для транспортировки этих данных

• Быстрый отклик системы (multi-master replication)

Multi-master replication

• Core Data разрешает конфликты, возникающие при параллельных изменениях данных

• Увеличение доступности всей системы в целом, то есть уменьшение времени отклика этой системы

Multi-master replication

• Core Data разрешает конфликты, возникающие при параллельных изменениях данных

• Увеличение доступности всей системы в целом, то есть уменьшение времени отклика этой системы

Создание хранилища данных в iCloud контейнере

• Запросить разрешения на использование iCloud в entitlements

• Передать название вашего хранилища в словаре options по ключу NSPersistentStoreUbiquitousContentNameKey

NSPersistentStoreCoordinator-addPersistentStoreWithType:configuration:URL:options:error:

События iCloud

• NSPersistentStoreCoordinatorStoresWillChangeNotification

• NSPersistentStoreCoordinatorStoresDidChangeNotification

• NSPersistentStoreDidImportUbiquitousContentChangesNotification

NSPersistentStoreDidImportUbiquitousContentChangesNotification

• Core Data посылает тогда, когда в ubiquity container происходят изменения извне

[[NSNotificationCenter defaultCenter] addObserverForName:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:persistentStoreCoordinator queue:queue usingBlock:^(NSNotification *note) {

[self.managedObjectContext performBlock:^{ [self.managedObjectContext mergeChangesFromContextDidSaveNotification:note]; }];

}];

Изменения аккаунтов

NSPersistentStoreCoordinatorStoresWillChangeNotification//Core Data очищает хранилище данных//Блокировка UI

NSPersistentStoreCoordinatorStoresDidChangeNotification//Новые данные, соотвествующие аккаунту, попадают в хранилище//Реакция UI на изменения

Изменения аккаунтов

NSPersistentStoreCoordinatorStoresWillChangeNotification//Core Data очищает хранилище данных//Блокировка UI

NSPersistentStoreCoordinatorStoresDidChangeNotification//Новые данные, соотвествующие аккаунту, попадают в хранилище//Реакция UI на изменения

Edge Case №1 – Нарушение консистентности связей объектов при использовании iCloud Core Data

Появление в хранилище объекта с полностью или частично отсутствующими связанными объектами

БилетПараметры поиска

Направление

Цена

Агентство

Edge Case №1 – Нарушение консистентности связей объектов при использовании iCloud Core Data

Атрибут проверки целостности объекта

БилетПараметры поиска

Направление

Цена

Агентство

Edge Case №2 – Модель• Миграция на новую версию модели возможна с использованием

Lightweight Migration (добавление, удаление или переименовывание атрибутов, записей или объектов)

• Возможность Lightweight Migration опереляется передаваемыми опциями при создании хранилища данных значениями @YES NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption

NSPersistentStoreCoordinator-addPersistentStoreWithType:configuration:URL:options:error:

• Сложные миграции iCloud Core Data не поддерживаются

• Упорядоченные связи to-many (NSOrderedSet) не поддерживаются

Edge Case №2 – Модель• Миграция на новую версию модели возможна с использованием

Lightweight Migration (добавление, удаление или переименовывание атрибутов, записей или объектов)

• Возможность Lightweight Migration опереляется передаваемыми опциями при создании хранилища данных значениями @YES NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption

NSPersistentStoreCoordinator-addPersistentStoreWithType:configuration:URL:options:error:

• Сложные миграции iCloud Core Data не поддерживаются

• Упорядоченные связи to-many (NSOrderedSet) не поддерживаются

Edge Case №2 – Модель• Миграция на новую версию модели возможна с использованием

Lightweight Migration (добавление, удаление или переименовывание атрибутов, записей или объектов)

• Возможность Lightweight Migration опереляется передаваемыми опциями при создании хранилища данных значениями @YES NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption

NSPersistentStoreCoordinator-addPersistentStoreWithType:configuration:URL:options:error:

• Сложные миграции iCloud Core Data не поддерживаются

• Упорядоченные связи to-many (NSOrderedSet) не поддерживаются

Edge Case №2 – Модель• Миграция на новую версию модели возможна с использованием

Lightweight Migration (добавление, удаление или переименовывание атрибутов, записей или объектов)

• Возможность Lightweight Migration опереляется передаваемыми опциями при создании хранилища данных значениями @YES NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption

NSPersistentStoreCoordinator-addPersistentStoreWithType:configuration:URL:options:error:

• Сложные миграции iCloud Core Data не поддерживаются

• Упорядоченные связи to-many (NSOrderedSet) не поддерживаются

Edge Case №3 – Дедупликация данных

• В приложении Aviasales для каждой функциональной единицы используется специально созданный менеджер, например, JRHistoryManager, JRFavouritesManager, JRPassengersManager и т.д.

• Менеджер возвращает коллекции объектов JRSearchInfo, JRTicket, JRPassenger и отвечает за процесс дедупликации

Edge Case №3 – Дедупликация данных

1. Выявление дублирующихся объектов в хранилище с помощью специально созданных хешей

2. Выбор критерия определения дубликата

3. Удаление дубликата

Источники

Руслан ШевчукiOS-разработчик, Aviasalesruslan@jetradar.com

Core Data Documentation Programming Guides, Examples, Tutorials http://developer.apple.com/

Apple Developer Forums http://devforums.apple.com

objc.io http://www.objc.io

NSHipster http://nshipster.com

MagicalRecordhttps://github.com/magicalpanda/MagicalRecord

top related