2014-01-08 5 views
4

Я работаю над новым приложением, которое использует Core Data и iCloud. Я следую демонстрации iCloudCoreDataStack и iCloud Design Guide. Пока синхронизация между устройствами работает хорошо, но я не понял, как засеять небольшой объем данных при первом использовании приложения на первом устройстве пользователя и пропустить посев, если приложение используется на второй (поскольку он должен загружаться из iCloud).Как занести исходные данные в Core Data + iCloud?

Это должно быть легко, просто спросите контейнер iCloud, если у него есть какие-либо данные. Загрузите данные, если они существуют, или создайте новые данные, если это не так. Но я не мог найти способ сделать это :-(

я могу думать о трех путях решения этого:

  1. Использование migratePersistentStore: toURL: опции: withType: ошибка: У меня есть очень небольшое количество данных, так что в этом случае это выглядит как излишний

  2. магазин значение на NSUbiquitousKeyValueStore, чтобы отметить, если начальная синхронизация была сделана я попытался с помощью NSUbiquitousKeyValueStore, но иногда это заняло бы слишком много времени, чтобы получить значение от UbiquitousKeyValueStore, поэтому исходные данные будут созданы даже тогда, когда они не нужны, что приведет к дублированию.

  3. Используйте файл дозорный, чтобы иметь тот же эффект # 2 (я не знаю, как это реализовать)

Приложение является IOS 7 только и новые, так что нет никакой необходимости мигрировать старые пользовательские данные.

Каждого соответствующие учебник и книга, которую я нашел, казались, используя предварительно iOS7 супер сложный способ делать вещи (например, с использованием резервного хранилища), который не стоит на прошивке 7.

Либо я пропускаю что-то (часто бывает), или это сложнее, чем должно быть. Я ценю любые предложения и указатели.

ответ

7

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

Это, возможно, хотя и неразумно для семян, основанных на завершении первоначального импорта Core Data.

Вы должны ждать NSPersistentStoreCoordinatorStoresDidChangeNotification с NSPersistentStoreUbiquitousTransitionTypeKey набор для NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted.

Если в магазине нет данных, вы можете засеять исходные данные в этой точке.

Однако важно понимать, что несколько устройств могут получать начальное уведомление об импорте без импорта семенных данных и, следовательно, заново его заново. Невозможно избежать этого.


На отправке второго постоянного хранилища с вашим приложением, чтобы служить в качестве данных о семени.

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

NSDictionary *options = @{ NSReadOnlyPersistentStoreOption: @YES }; 
[_psc addPersistentStoreWithType:NSSQLiteStoreType 
        configuration:nil 
          URL:seedStoreURL 
         options:options 
          error:&localError]; 

NSDictionary *iCloudOptions = @{ NSPersistentStoreUbiquitousContentNameKey: @"storeName" }; 
[_psc addPersistentStoreWithType:NSSQLiteStoreType 
        configuration:nil 
          URL:iCloudStoreURL 
         options:iCloudOptions 
          error:&localError]; 

_moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
[appMOC setPersistentStoreCoordinator:_psc]; 

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

Единственный трюк заключается в том, что если вы хотите, чтобы ваш пользователь мог изменять данные из хранилища семян, вам необходимо переместить эти объекты в хранилище iCloud.

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

+0

Но как избежать использования второго постоянного хранилища, когда приложение используется на втором устройстве? (то есть данные должны быть загружены из iCloud). – kroger

+2

Как он сказал, не засевайте данные, не берете данные о семенах и не добавляйте их в качестве второго постоянного хранилища только для чтения в свой 'NSPersistentStoreCoordinator'. Это избавит вас от боли позже, когда вам нужно «обновить» данные семян. –

+0

Я расширю свой ответ, чтобы освежить этот момент. – ImHuntingWabbits

2

Попробуйте этот подход:

Перед созданием местной проверки магазина, если один уже был создан в ICloud смотря на наличие каталога с именем «NSPersistentStoreUbiquitousNameKey» в каталоге ICloud/CoreData.

Если существует, то это означает, что какое-то другое устройство уже создало хранилище и поделилось им в iCloud, поэтому при создании локального хранилища на устройстве не добавляйте данные семени, поскольку это уже будет существовать в iCloud.

Если этого не существует, другое устройство не будет совместно использовать хранилище в iCloud, поэтому вы, вероятно, можете создать свои данные семян и синхронизировать их с iCloud.

Обратите внимание, что следующие сценарии не удовлетворяются:

  • Пользователь работает приложение на устройстве, которое не имеет ICloud включена - если пользователь выбирает в настоящее время синхронизации с ICloud от этого вам придется решать проблемы, возникающие в результате попыток объединить данные с этого устройства с данными, уже находящимися в iCloud. Еще раз вы можете проверить наличие данных в iCloud, а затем спросить пользователя , хотят ли они попытаться объединить данные с устройства или же они хотят заменить данные данными из iCloud.

  • Пользователь работает приложение на устройстве, которое не связано с сети - и не имел каких-либо данных, синхронизированные с ICloud еще так думает нет файла уже в ICloud. Затем приложение создаст данные семпл , и когда он получит сетевое подключение, Core Data объединит данные - вам, возможно, придется иметь дело с возникающими проблемами.

Для этого сценария вам может потребоваться обучение пользователей.

+0

Можно ли проверить наличие данных iCloud следующим образом? 'NSURL * ubiquitousURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier: nil];' 'NSLog (@" iCloud URL:% @ ", ubiquitousURL);' –

+0

Это просто даст вам URL-адрес контейнера iCloud, если он nil, тогда iCloud не включен. Это не скажет вам, есть ли какие-либо данные в контейнере. –

Смежные вопросы