iPhone CoreData миграция только данных - PullRequest
1 голос
/ 10 февраля 2011

У меня есть приложение для iPhone, которое использует CoreData для хранения.

Постоянное хранилище (база данных sqlite3) поставляется с несколькими объектами, заполненными данными. Эти данные используются для создания различных меню и опций в приложении. Назовем эти данные «данными приложения».

Несколько других объектов используются приложением для хранения пользовательских данных.

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

У меня есть скрипт MacRuby, который получает новые данные из набора CSV-файлов и обновляет базу данных sqlite3 на моей машине для разработки, но я не уверен, каков наилучший способ обновить существующие развернутые приложения новыми данными приложения ( помните, без изменения схемы) без влияния на пользовательские данные.

Есть идеи?

_ Обновление _

Подумав немного, я ориентируюсь на настройку приложения для загрузки нового файла sqlite3 с веб-сервера, который содержит новые данные. После получения мое приложение скопирует данные из обновленного файла sqlite3 в рабочий файл базы данных приложения, полностью заменив данные приложения, но не затрагивая данные пользователя.

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

1 Ответ

0 голосов
/ 10 февраля 2011

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

NSString *applicationDataPath = [[NSBundle mainBundle] pathForResource:@"ApplicationData" ofType:@"plist"];
NSString *previousVersion = [[NSUserDefaults standardUserDefaults] stringForKey:@"VERSION"];

NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

/* Don't bother processing updates if the version last run  is the same as the current version. */
if (! [previousVersion isEqualToString:currentVersion])
{
   NSArray *versionList = [applicationData objectForKey:@"Versions"];

   BOOL process = (nil == previousVersion);
   for (NSDictionary *versionData in versionList)
   {
     NSString *version = [versionData objectForKey:@"version"];
     if (process)
     {
       // Send dictionary for this version update to some method to process it..
       [self processUpdate:versionData];
     }

     if (!process && [version isEqualToString:previousVersion])
       process = YES;
   }
}    

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

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

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

[{ Версии = ( { данные = { 1 = { лицо = меню; }; }; версия = "1.1"; }, { данные = { 1 = { лицо = меню; }; }; версия = "1.2"; }, { данные = { 1 = { лицо = меню; }; }; версия = "1.3"; }, { данные = { 1 = { лицо = меню; }; }; версия = "2.0"; }, { данные = { 1 = { лицо = меню; }; }; версия = "2.5"; } ); }]

...