#ios #core-data #icloud
#iOS #core-data #icloud
Вопрос:
У меня есть приложение, которое использует собственный метод синхронизации данных из приложения на сервер и обратно в любое другое приложение, которое использует пользователь (iOS и Android).
Я не использую синхронизацию iCloud и не хочу использовать синхронизацию основных данных iCloud, поэтому я просто хочу дать понять, что я НЕ пытаюсь этого делать.
Когда приложение загружает новую запись, которая должна быть создана на сервере, оно отправляет ту URIRepresentation
, о NSManagedObect.objectID
которой говорится в документации A compact, universal identifier for a managed object
, чтобы сервер мог определить, видел ли он эту запись раньше (возможно, приложение уже пыталось загрузить эти данные, но что-то не удалось позже в процессе,таким образом, это помогает нам избежать создания дубликатов записей на сервере).
Вот пример идентификатора объекта: x-coredata://80978028-AEB5-45F0-AAD5-F328C4B294AF/MedicineShot/p1481
Согласно документации, этот идентификатор объекта должен быть уникальным для моего приложения… но я не могу точно сказать, какова область уникальности, например, если у одного человека есть мое приложение на iPhone и iPad, будет ли оно генерировать один и тот же идентификатор объекта в этих двух разных хранилищах на двух разных устройствах?
Мы используем это приложение / сервер уже 6 лет, и у нас никогда не было конфликта идентификаторов, о котором мы знаем, но, похоже, мы столкнулись с одним.
Пользователь создал запись на своем iPhone с указанным в приведенном выше примере идентификатором coredata. Тот же пользователь 5 дней спустя создал новую запись на своем iPad, и у нее точно такой же идентификатор coredata. Поскольку наш сервер синхронизации использует этот идентификатор, чтобы определить, получает ли он запрос на создание записи, которую он уже создал, сервер обработал эти две разные записи как одинаковые.
Мы никогда не видели этого раньше, и в документации, похоже, говорится, что этого не должно быть, потому что эти идентификаторы должны быть уникальными. Идентификатор управляемого объекта должен быть универсальным идентификатором для управляемого объекта, но это два разных устройства, создающие две разные записи в два разных дня (с интервалом в 5 дней)… с тем же идентификатором.
Это был один и тот же пользователь, который, вероятно, использует одну и ту же учетную запись Apple на обоих устройствах.
Может ли iCloud тайно копировать файлы постоянного хранилища с одного устройства на другое?
Если да, есть ли способ запретить iCloud копировать эти файлы постоянного хранилища данных, чтобы мы могли гарантировать получение уникальных идентификаторов с устройства на устройство?
РЕДАКТИРОВАТЬ: uri идентификатора объекта имеет то, что похоже на UUID 80978028-AEB5-45F0-AAD5-F328C4B294AF
, а UUID должны быть универсально уникальными, как указано в названии. Является ли эта часть идентификатора объекта идентификатором UUID? Если да, то как постоянное хранилище Core Data на двух разных устройствах может выдавать один и тот же uri идентификатора объекта?
Комментарии:
1. Я не верю, что область уникальности задокументирована, но лично я бы не стал считать уникальность ion за пределами данного постоянного хранилища, поскольку это область, в которой используются идентификаторы управляемых объектов. Если iOS тайно копировала данные между устройствами (чего не происходит), это, вероятно, позволило бы избежать проблемы, поскольку у вас была бы одна и та же запись на двух устройствах с одинаковым идентификатором, а не разные записи. Пользователь мог восстановить резервную копию. Если вам нужна уникальность, вам, вероятно, следует создать свой собственный уникальный идентификатор, а не полагаться на идентификаторы управляемых объектов.
2. @Paulw11 Если файл постоянного хранилища был скопирован с одного устройства на другое, когда был вставлен MedicineShot p1480 … а затем iphone вставил другой, а ipad вставил другой… оба они будут p1481, но это будут разные записи. Я не описываю постоянное копирование, а как одноразовую копию для восстановления или что-то в этом роде. Я не уверен.
3. Я полагаю, что первая часть идентификатора объекта является идентификатором постоянного хранилища ( developer.apple.com/documentation/coredata/nspersistentstore /… ) таким образом, теория резервного копирования / восстановления, по-видимому, имеет смысл.
Ответ №1:
Несмотря на то, что предлагается в документации, идентификаторы управляемых объектов уникальны только в пределах определенного файла постоянного хранилища. Не гарантируется, что они везде уникальны. Я знаю, я тоже читал документы, и я знаю, что они говорят «универсальный», но я думаю, что также важно отметить, что они говорят
Идентификаторы содержат информацию, необходимую для точного описания объекта в постоянном хранилище…
Но они ничего не говорят о нескольких постоянных хранилищах. Core Data изначально создавалась для использования в приложении, и документы не всегда соответствовали идее синхронизации с серверами или другими устройствами.
Форма URI- x-coredata://80978028-AEB5-45F0-AAD5-F328C4B294AF/MedicineShot/p1481
— недокументирована, но части:
- UUID: идентификатор определенного постоянного хранилища. Это также сохраняется в метаданных постоянного хранилища, чтобы можно было сопоставлять экземпляры и хранилища.
MedicineShot
: Объект, используемый для этого экземпляраp1481
:p
подразумевает «постоянный» (временные идентификаторы имеют at
и другой формат) и1481
, по сути, является увеличивающимся первичным ключом в постоянном хранилище. Он начинается с 0 и подсчитывается каждый раз, когда вы вставляете новый экземпляр объекта.
Использование идентификатора управляемого объекта из одного хранилища в другом хранилище вряд ли будет работать хорошо. Помимо UUID, уникальные идентификаторы не будут совпадать, если вы не будете очень осторожны, чтобы всегда вставлять новые экземпляры в том же порядке.
Комментарии:
1. Оказывается, проблема здесь в том, что они восстановили приложение из резервной копии iCloud на новый телефон, который они получили. Таким образом, постоянное хранилище на двух разных устройствах использовало один и тот же uuid. Таким образом, два разных устройства затем вставили следующую запись, которая оказалась одного и того же типа объекта, и, таким образом, managedobjectid был точно таким же для двух разных записей. Когда эти устройства пытались синхронизировать эти записи с нашим сервером, наш сервер ошибочно определил вторую попытку как «дублирующую» попытку создать ранее созданную запись.