iPhone и Базовые Данные: как сохранить вводимые пользователями данные между обновлениями?

Рассмотрите приложение для iPhone, которое является каталогом животных. Приложение должно позволить пользователю добавлять пользовательскую информацию для каждого животного - скажем, оценка (в масштабе 1 - 5), а также некоторые примечания, которые они могут ввести приблизительно в животное. Однако пользователь не сможет изменить сами данные животных. Предположите, что, когда приложение обновляется, для (статической) части каталога должно быть легко измениться, но мы хотели бы, чтобы (динамическая) пользовательская часть информации о пользователе была сохранена между обновлениями, таким образом, пользователь не теряет ни одной их пользовательской информации.

Мы, вероятно, хотели бы использовать Базовые Данные для создания этого приложения. Давайте также скажем, что у нас уже есть предыдущий процесс на месте для чтения в данных животных, чтобы предварительно заполнить поддержку (SQLite) хранилище те Базовые Данные использование. Мы можем встроить этот файл базы данных в сам комплект приложений, так как это не становится измененным. Когда пользователь загрузит обновление приложения, новая версия будет включать последнюю (статическую) базу данных каталога животных, таким образом, мы никогда не должны волноваться об этом являющийся устаревшим.

Но, теперь хитрая часть: как мы храним (динамического) пользователя пользовательские данные звуковым способом?

Моя первая мысль - то, что (динамическая) база данных должна быть сохранена в каталоге Documents для приложения, таким образом, обновления приложения не ударяют существующие данные. Я корректен?

Мое долгое размышление - то, что, так как (динамический) пользователь пользовательская база данных данных не находится в том же хранилище как (статический) каталог животных, мы не можем наивно сделать отношения между Оценкой и объектами Примечаний (в одной базе данных) и объектом Животных (в другой базе данных). В этом случае я предположил бы, что одно решение будет состоять в том, чтобы иметь "animalName" свойство строки в объекте Оценки/Примечаний и подойти его во времени выполнения. Действительно ли это - лучший способ сделать это или является там способом "синхронизировать" две различных базы данных в Базовых Данных?

5
задан Shaggy Frog 11 March 2010 в 02:44
поделиться

3 ответа

Вот в основном то, как я решил эту проблему.

Хотя ответы Амории и М. Харрисона были верными, у них было одно предположение: после создания не только таблицы, но и каждая строка в каждой таблице всегда будет одинаковой.

Проблема в том, что мой процесс предварительного заполнения базы данных «Животные» с использованием существующих данных (которые периодически обновляются) каждый раз создает новый файл базы данных. Другими словами, я не могу полагаться на создание связи между (статической) сущностью Animal и (динамической) сущностью Rating в Core Data, поскольку эта сущность может не существовать в следующий раз, когда я регенерирую приложение. Почему нет? Потому что я не могу контролировать, как Core Data хранит эти отношения за кулисами. Поскольку это резервное хранилище SQLite, вполне вероятно, что оно использует таблицу с отношениями внешнего ключа. Но когда вы регенерируете базу данных, вы ничего не можете предположить о том, какие значения каждая строка получает для ключа. Первичный ключ для Льва может быть другим во второй раз, если я добавил Лемура в список.

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

Итак, какое решение? Что ж, поскольку я не могу полагаться на отношения внешних ключей, которые создает Core Data, я должен придумать свои собственные. Я делаю промежуточный шаг в процессе создания моей базы данных: вместо того, чтобы брать мои необработанные данные (которые являются текстом UTF-8, но на самом деле являются файлами MS Word) и напрямую создавать базу данных SQLite с Core Data, я представляю посредника Шаг: я конвертирую .txt в .xml. Почему XML? Ну, не потому, что это серебряная пуля, а просто потому, что это формат данных, который я могу очень легко проанализировать. Так чем же отличается этот XML-файл? Хэш-значение, которое я генерирую для каждого Animal с использованием MD5, которое, как я полагаю, является уникальным. Для чего нужен хеш-код? Что ж, теперь я могу создать две базы данных: одну для «статических» данных о животных (для которой у меня уже есть процесс) и одну для «динамической» базы данных рейтингов, которую создает приложение для iPhone и которая находится в каталоге документов приложения. . Для каждого рейтинга я создаю псевдосвязь с Animal, сохраняя хеш-значение объекта Animal. Поэтому каждый раз, когда пользователь вызывает на iPhone подробное представление о животных, я запрашиваю «динамическую» базу данных, чтобы определить, существует ли объект Rating, соответствующий значению Animal.md5Hash.

Поскольку я сохраняю этот промежуточный файл данных XML, в следующий раз, когда будет обновление, я могу сравнить его с последним файлом XML, который я использовал, чтобы увидеть, что изменилось. Теперь, если имя животного было изменено - допустим, была исправлена ​​опечатка - я возвращаю хеш-значение для этого животного на месте.Это означает, что даже если имя животного будет изменено, я все равно смогу найти соответствующий рейтинг, если он существует, в «динамической» базе данных.

У этого решения есть еще один приятный побочный эффект: мне не нужно заниматься какими-либо проблемами миграции. «Статическая» база данных Animal, поставляемая с приложением, может оставаться встроенной как ресурс приложения. Он может изменить все, что хочет. «Динамическая» база данных рейтингов может нуждаться в миграции в какой-то момент, если я изменю ее модель данных, чтобы добавить больше сущностей, но в действительности две модели данных останутся полностью независимыми.

2
ответ дан 15 December 2019 в 00:58
поделиться

Я делаю это следующим образом: отправляю базу данных статического материала как часть вашего пакета приложений. При запуске приложения проверьте, есть ли в Документах файл базы данных. Если нет, скопируйте его из пакета приложений в Документы. Затем откройте базу данных из Документов: это единственная, из которой вы читаете и редактируете.

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

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

1
ответ дан 15 December 2019 в 00:58
поделиться

Хранить базу данных SQLite в каталоге Documents (NSDocumentDirectory), конечно, лучше всего. В целом, следует по возможности избегать изменений в приложении, которые изменяют или удаляют таблицы SQL (добавление - это нормально). Однако, когда вам абсолютно необходимо внести изменения в обновление, подойдет что-то вроде того, что сказала Amorya - откройте старую БД, импортируйте все, что вам нужно, в новую БД и удалите старую.

Поскольку похоже, что вам нужна статическая база данных с таблицей "Animal", которую нельзя изменять, то простая замена этой таблицы обновлениями не должна быть проблемой - до тех пор, пока ID записей не изменится. Способ хранения пользовательских данных о животных заключается в создании отношения с внешним ключом к ID животного для каждой записи, созданной пользователем. Это то, что вам нужно будет перенести, когда обновление изменит его.

1
ответ дан 15 December 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: