Ответ 1
ОК, ребята, я думаю, что я начал работать.
UPDATE. Первоначально это сработало для меня, но у меня были некоторые очень странные эффекты и тот факт, что, если вы выходите из iCloud, контейнер ubiquity удаляется, заставив меня подумать об альтернативном решении. Теперь я использую библиотеку Ensembles, и я в основном очень доволен ею. END UPDATE
Я просто прикусил свое собственное тестовое приложение, которое написал 2 года назад, у которого не было CoreData или iCloud, и, похоже, он работает хорошо. Он синхронизирует базу данных с моим iPhone и iPhone Simulator. Одна маленькая вещь, которая сводит меня с ума, состоит в том, что я все еще ничего не вижу на https://developer.icloud.com.
Теперь я собираюсь сделать то же самое для своего распределенного приложения. Вот что я сделал:
- Самое приятное в том, что вам почти ничего не нужно делать на портале разработчиков (например, создать профиль создания и загрузки, даже создавать идентификатор приложения не требуется). XCode 6.3.2 делает все это для вы; если вы знаете порядок, конечно. Итак, сначала перейдите в свою целевую настройку → Возможности и включите iCloud. Xcode выполняет задачу добавления файла прав, создания идентификатора приложения на портале разработчиков и создания контейнера iCloud. Снимите флажок "Хранилище с ключом" и отметьте "Документы iCloud".
- Я предполагаю, что вы используете MagicalRecord, и вы устанавливаете свой стек Core Data следующим образом:
[MagicalRecord setupAutoMigratingCoreDataStack];
В этом случае MagicalRecord создает локальный магазин, имя которого вы можете получить, вызвав [MagicalRecord defaultStoreName]
. Вам нужно будет указать это в установочном вызове iCloud. Таким образом, код, который у меня есть сейчас, в AppDelegate.m:
NSString *defaultStoreName = [MagicalRecord defaultStoreName];
[MagicalRecord setupCoreDataStackWithiCloudContainer:@"Container ID from Developer Portal (as on image)"
contentNameKey:@"DataStorage" // It seems like you can write whatever you want here
localStoreNamed:defaultStoreName // Unless not specifically named earlier
cloudStorePathComponent:@"stuff"]; // Seems like you can write whatever stuff you want.
Этот метод работал у меня. Другой, более короткий метод вызова iCloud (без ContentNameKey) не выдавал исключений, но не работал должным образом. Думаю, вам просто нужно указать ContentNameKey.
Здесь вы получите идентификатор контейнера на портале разработчиков. Я знаю, это очень подробные инструкции, но мне жаль, что мне так ясно, что строка "iCloudContainer" в приведенной выше функции фактически является iCloudContainerID и должна быть получена из портала разработчиков.
- Перейдите в Настройки устройства → iCloud → iCloud Drive и включите его. Войдите в iCloud с вашей учетной записью. Это важно для всей работы.
-
Теперь попробуйте запустить приложение на симуляторе как минимум. Если в журналах нет сообщения "iCloud не включено", вы находитесь на полпути.
-
Зарегистрируйте объект, который отвечает за все действия с основными данными для прослушивания
NotificationCenter
в следующих событиях:NSPersistentStoreCoordinatorStoresWillChangeNotification
NSPersistentStoreCoordinatorStoresDidChangeNotification
NSPersistentStoreDidImportUbiquitousContentChangesNotification
вот так:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(storesWillChange:)
name:NSPersistentStoreCoordinatorStoresWillChangeNotification
object:nil];
и правильно обрабатывать изменения.
Жесткая работа еще предстоит сделать, и теперь это зависит от вашего проекта, и я не могу дать вам никаких советов индивидуально.
Для меня были проблемы:
- как реагировать на изменения в удаленном хранилище
- как объединить разные данные и избежать дубликатов
- как избежать полной потери данных, если контейнер iCloud пуст.
Но я надеюсь найти ответы на мои вопросы в официальном руководстве Apple iCloud.
Я рад, что вы избежали пары дней головной боли для вас! Пожалуйста, напишите комментарий, если это решение сработало для вашего проекта!