#mbltdev: core data: особенности использования и синхронизация...
Post on 26-Jun-2015
851 Views
Preview:
DESCRIPTION
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