Мое приложение требует данных из базы данных sqlite. Он будет поставляться с версией этой базы данных, но мне нужно обновлять ее на регулярной основе (чаще всего раз в месяц). Как правило, я отправлял обновления для других частей своего приложения в виде XML через кучу веб-сервисов, которые я создал, но эта конкретная база данных, над которой я работаю сейчас, довольно большой (около 20-30 МБ) m получать ошибки таймаута, когда я пытаюсь отправить его таким образом.Обновление базы данных sqlite без XML
Я попытался поместить базу данных на сервер своих компаний, а затем загрузить ее в объект NSData
. Затем я сохранил этот объект данных в каталоге Документов приложения. Когда я перезапускаю приложение, я получаю сообщение об ошибке «Файл по пути не является базой данных SQLite». Код для этого ниже.
// Download data
NSURL *url = [NSURL URLWithString:@"http://www.mysite.net/download/myDatabase.sqlite"];
NSData *fileData = [[NSData alloc] initWithContentsOfURL:url];
NSLog(@"%@",fileData); // Writes a bunch of 8 character (hex?) strings
// Delete old database
NSError *error;
NSURL *destination = [app applicationDocumentsDirectory];
destination = [destination URLByAppendingPathComponent:@"myDatabase"];
destination = [destination URLByAppendingPathExtension:@"sqlite"];
NSLog(@"destination = %@",destination);
[[NSFileManager defaultManager] removeItemAtPath:[destination path] error:&error];
// Save into correct location
[fileData writeToURL:destination atomically:YES];
//[NSFileManager defaultManager] createFileAtPath:[destination path] contents:fileData attributes:nil]; // I also tried this, it doesn't work either.
Существует ли стандартная процедура обновления большой базы данных, которую приложение будет использовать? У меня возникает ощущение, что то, что я пытаюсь сделать, неверно и что есть совершенно другой способ сделать это, но я не могу понять, что.
UPDATE: Я попробовал несколько вещей, чтобы попытаться найти проблему, но ничего не получает мне ближе. Я помещаю базу данных, которую я пытаюсь загрузить с моего сервера на USB-накопитель, а затем на Mac, который я разрабатываю, и в папку «Документы» для моего приложения в Simulator. Когда я запускаю свое приложение, передавая базу данных таким образом, он работает без каких-либо проблем, и я могу видеть все свои данные.
И наоборот, я полностью удалил свое приложение с симулятора и перезапустил его, чтобы он создавал мою базу данных с нуля. Я передал эту недавно созданную базу данных с моего mac на мой сервер с USB-накопителем. После того, как файл был на моем сервере, я попытался запустить мое «обновление загрузки» в приведенном выше блоке кода, но он по-прежнему сбой при следующем запуске моего приложения с ошибкой «Файл по пути не является ошибкой базы данных SQLite» сообщение.
Из этих тестов я уверен, что проблема не в базе данных, которую я пытаюсь загрузить. Что-то в моем «загружаемом обновлении» кода искажает базу данных, но я до сих пор не смог понять, почему, и я не нашел приемлемого альтернативного метода для получения моих обновлений для моих пользователей после запуска моего приложения.
UPDATE 2: Я делал несколько больше поиска, и я узнал, что пользователю нужно будет ввести в имя пользователя и пароль, чтобы получить доступ к любому файлу на моем сервере. Теперь я верю, что NSData
Я возвращаюсь из своего кода выше - это вызов аутентификации или что-то, связанное с этим, и поэтому, когда я сохраняю его с помощью NSFileManager
, он не распознается как SQL-база данных.
Простейшее решение, которое я нашел для проверки подлинности, - here. Когда я пытаюсь сделать NSData *fileData = [NSData dataWithContentsOfURL:url options:NSDataReadingMapped error:&error];
(после изменения моего url
, как предложено в ссылке, конечно), я получаю сообщение об ошибке NSCocoaErrorDomain Code=256
, что является просто неизвестной ошибкой. Мой fileData
- nil
после этого. Я заметил, что эта почта довольно старая, поэтому я не знаю, поддерживается ли она.
Я также нашел другое решение проблемы аутентификации here с использованием NSURLConnection
вместо dataWithContentsOfURL
. Это гораздо более свежий, но в этом примере используется еще более синтаксис, который я раньше не видел. Я смог в значительной степени скопировать-вставить из примера, и мой проект будет строиться без ошибок, но я не знаю правильного синтаксиса для использования процедуры fetchURL:withCompletion:failure:
из моего UIViewController
.Я пробовал
NSError *error;
NSData *fileData;
ExampleDelegate *download = [[ExampleDelegate alloc] init];
[download fetchURL:url withCompletion:fileData failure:&error];
, но это дает ошибку сборки для отправки несовместимого указателя. Я думаю, что я не могу пройти прямо NSData
и NSError
как ExampleDelegateSuccess
и ExampleDelegateFailure
объектов, соответственно, хотя это то, что они typedef
из. Я, вероятно, должен что-то сделать для fileData
и error
, чтобы преобразовать их, но это typedef
ing является одним из «синтаксиса расширенного поиска». Я имел в виду выше, и я действительно не знаю, что делать.
Это не включено в его пример, но я нашел еще один метод NSURLConnectionDelegate
под названием connection:didReceiveAuthenticationChallenge:
here, который, я думаю, могу просто добавить в код из примера, и это должно решить мою проблему аутентификации. Я чувствую, что если бы я просто знал, как позвонить fetchURL
, я бы установил. Кто-нибудь имеет какие-либо советы о том, что мне нужно сделать, чтобы получить fileData
и error
в этот звонок?
Спасибо за предложение. Я много видел о JSON здесь, но еще не использовал его сам - я посмотрю на него (и вы упомянули AFHTTPClient). Я рассматривал возможность разбить мою базу данных на несколько файлов, но она почти гарантированно продолжает расти, поэтому просто, сколько штук я должен нарезать, немного сложно понять. Я надеялся найти другой маршрут, но это может быть единственный путь. – GeneralMike
Надеюсь, это сработает. – HalR
+1: хорошее предложение - разбить его на куски, может помочь ... –