things you might have missed from coredata

30
Advanced CoreData CocoaHeads Moscow

Upload: sergey-pronin

Post on 16-Jul-2015

703 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Things you might have missed from CoreData

Advanced CoreDataCocoaHeads Moscow

Page 2: Things you might have missed from CoreData

Сергей Пронин

Full-stack developer CTO, Senior Dev, Co-Founder App in the Air

Senior DeveloperEmpatika

ПреподавательНИУ-ВШЭДепартамент Программной Инженерии

Page 3: Things you might have missed from CoreData

App in the Air

Page 4: Things you might have missed from CoreData

http://appintheair.mobi/

Page 5: Things you might have missed from CoreData
Page 6: Things you might have missed from CoreData

Advanced CoreData

• CoreData stack set-ups

• High-performance Concurrency

• Migration

• Runtime models

Page 7: Things you might have missed from CoreData

CoreData stack set-ups

Page 8: Things you might have missed from CoreData

Default• Предлагается Xcode при создании проекта

• Самый простой в понимании

• Вся работа проходит через Main (UI) thread

• Подходит для маленьких проектов с примитивным хранением Store

Coordinator

Context Main

Page 9: Things you might have missed from CoreData

Nested Simple• I/O операции делаются асинхронно через PrivateConcurrency context

• Mid-level проекты, где данные нужны в момент доступа

• Стандартный MagicalRecord работает таким образом

• Main thread страдает при больших объемах данных

Context Private

Store

Coordinator

Context Main

Page 10: Things you might have missed from CoreData

Nested Workers• I/O операции делаются асинхронно через PrivateConcurrency context

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

• Ведет себя лучше, чем Nested Simple на больших объемах

• Изменения из workers все равно проходят через Main

workers

Context Private

Store

Coordinator

Context Main

Context Private

Context Private

Page 11: Things you might have missed from CoreData

High-Performance Concurrent Classic

• I/O операции делаются асинхронно через PrivateConcurrency context

• Ведет себя почти идеально на больших объемах

• Изменения из worker не касаются Main

• Нужно “затягивать” изменения

• Записи из Main синхронны — нужно сохранять большие объемы отдельно

worker

Store

Coordinator

Context Private

Context Main

Page 12: Things you might have missed from CoreData

High-Performance Concurrent Modified

• I/O операции делаются асинхронно через PrivateConcurrency context

• Ведет себя почти идеально на больших объемах

• Изменения из worker не касаются Main

• Нужно “затягивать” изменения через NSManagedObjectContextDidSaveNotification

• Записи Main асинхронны — удобство использования

worker

Context Private

Store

Coordinator

Context Private

Context Main

Page 13: Things you might have missed from CoreData

PerformanceAll Off-main Main

Default 4.2s 0.0s 4.2s

Nestedsimple 18.647s 15.637s 3.010s

Nestedworkers 18.927s 15.85s 3.077s

HP Classic 21.05s 20.9s 0.158s

Page 14: Things you might have missed from CoreData

Материалы

1. The concurrent Core Data Stack

2. Backstage with Nested Managed Object Contexts

3. Concurrent Core Data Stacks – Performance Shootout

4. Не нужно бояться CoreData

Page 15: Things you might have missed from CoreData

Migration

Page 16: Things you might have missed from CoreData

Light-weight migration

NSMigratePersistentStoresAutomaticallyOption: trueNSInferMappingModelAutomaticallyOption: true

• Удаление entity, отношения или атрибута • Переименование с renamingIdentifier • Добавление атрибута • Изменение иерархии

Page 17: Things you might have missed from CoreData

Heavy-weight migration• Все, что не подходит под light-weight миграцию

• Изменение типа атрибута

NSMigrationManager — отвечает за миграцию, принимает две модели (“из” и “в”)

NSMappingModel — хранит набор NSEntityMapping

NSEntityMapping — соотношение двух NSEntityDescription между которыми будет маппинг

NSEntityMigrationPolicy — “политика” миграции, обрабатывает преобразование каждого объекта

Page 18: Things you might have missed from CoreData

NSEntityMappinglet eMapping = NSEntityMapping() eMapping.mappingType = .TransformEntityMappingType eMapping.entityMigrationPolicyClassName = “MyEntityMigrationPolicy" eMapping.sourceEntityName = fromEntity.name eMapping.sourceEntityVersionHash = fromEntity eMapping.sourceExpression = NSExpression(format: MANTRA) eMapping.destinationEntityVersionHash = toEntity.versionHash eMapping.destinationEntityName = toEntity.name

let idMapping = NSPropertyMapping() idMapping.name = "_id" idMapping.valueExpression = NSExpression(format: “FUNCTION($source, \"valueForKey:\", \”_id\")") eMapping.attributeMappings = [idMapping]

mappings.append(entityMapping)

MANTRA ”FETCH(FUNCTION($manager, \"fetchRequestForSourceEntityNamed:predicateString:\", \"\(fromEntity.name)\", \"TRUEPREDICATE\"),FUNCTION($manager, \"sourceContext\"), NO)"

Page 19: Things you might have missed from CoreData

NSMappingModel

let mappingModel = NSMappingModel()

//...

mappingModel.entityMapping = mappings

Page 20: Things you might have missed from CoreData

NSMigrationManagerlet migrationManager = NSMigrationManager( sourceModel: sourceModel, destinationModel: destinationModel)

//...

migrationManager.migrateStoreFromURL(store1URL, type: NSSQLiteStoreType, options: nil, withMappingModel: mappingModel, toDestinationURL: store2URL, destinationType: NSSQLiteStoreType, destinationOptions: nil, error: &error)

Page 21: Things you might have missed from CoreData

NSEntityMigrationPolicysubclass

func createDestinationInstancesForSourceInstance( _ sInstance: NSManagedObject, entityMapping mapping: NSEntityMapping, manager: NSMigrationManager, error: NSErrorPointer) -> Bool {

let dInstance = NSEntityDescription .insertNewObjectForEntityForName(mapping.destinationEntityName, inManagedObjectContext: manager.destinationContext)

for (key, value) in dInstance.entity.propertiesByName { let oldValue = sInstance.valueForKey(key as! String) let convertedValue = convert(oldValue) dInstance.setValue(convertedValue, forKey: key as! String) }

manager.associateSourceInstance(sInstance, withDestinationInstance: dInstance, forEntityMapping: mapping) return true }

Page 22: Things you might have missed from CoreData

Launch Arguments

-com.apple.CoreData.MigrationDebug 1Описывает процесс миграции + ошибки

-com.apple.CoreData.SQLDebug 1 (3)Логгирует настоящие SQL запросы на каждый store

Page 24: Things you might have missed from CoreData

Runtime Models

Page 25: Things you might have missed from CoreData

Runtime models

Advanced caching — write once, use anytime — грамотно написанное runtime построение модели позволяет полностью настраивать store с бекэнда

Page 26: Things you might have missed from CoreData

let entity = NSEntityDescription() entity.name = “Person” //если есть entity.managedObjectClassName = “Person”

var properties = [NSAttributeDescription]() let attribute = NSAttributeDescription() attribute.name = “_id” attribute.optional = false attribute.indexed = true attribute.type = .StringAttributeType properties.append(attribute) //... entity.properties = properties

let model = NSManagedObjectModel() model.entities = [entity] let coordinator = NSPersistentStoreCoordinator( managedObjectModel: model)

Page 27: Things you might have missed from CoreData

Материалы

1. Simple Core Data model in Runtime

2. Generating Registered Runtime Classes

3. Mike Ash Blog: Runtime Ambassador

Page 28: Things you might have missed from CoreData

Key Points

• Экспериментировать со сборками CoreData стеков, чтобы найти удачный вариант

• Сложная миграция — это просто

• Вся CoreData без труда строится в runtime, позволяя делать “гибкие” модели с бекенда

Page 29: Things you might have missed from CoreData

Курс НИУ ВШЭ — Swift

Идёт прямо сейчас. Все материалы на русском языке. https://itunes.apple.com/ru/course/razrabotka-ios-prilozenij/id941293188?l=en

iTunes U

Page 30: Things you might have missed from CoreData

Спасибо!

@spronin [email protected]