Aktualizacja bazy danych sqlite bez XML

Moja aplikacja wymaga danych z bazy danych sqlite. Zostanie ona wysłana z wersją tej bazy danych, ale muszę ją regularnie aktualizować (najprawdopodobniej raz w miesiącu). Zazwyczaj wysyłam aktualizacje dla innych części mojej aplikacji jako XML za pośrednictwem kilku ustawionych przeze mnie usług sieciowych, ale ta konkretna baza danych, nad którą teraz pracuję, jest dość duża (około 20-30 MB), a ja ' m otrzymuję błędy limitu czasu, gdy próbuję wysłać to w ten sposób.

Próbowałem umieścić bazę danych na serwerze mojej firmy, a następnie pobrać ją doNSData obiekt. Następnie zapisałem ten obiekt danych w katalogu Dokumenty mojej aplikacji. Po ponownym uruchomieniu aplikacji pojawia się komunikat o błędzie „Plik na ścieżce nie wydaje się być bazą danych SQLite”. Kod do tego znajduje się poniżej.

// 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.

Czy istnieje standardowa procedura aktualizacji dużej bazy danych, z której będzie korzystać aplikacja? Mam wrażenie, że to, co staram się zrobić, jest nieprawidłowe i że jest zupełnie inny sposób na to, ale nie mogę zrozumieć, co.

AKTUALIZACJA: Próbowałem kilka rzeczy, aby znaleźć problem, ale nic mnie nie przybliża. Umieszczam bazę danych, którą próbuję pobrać z mojego serwera na dysku USB, a następnie na mac, nad którym pracuję, i do folderu Dokumenty mojej aplikacji w symulatorze. Kiedy uruchamiam aplikację, przesyłając bazę danych w ten sposób, działa bez problemu i widzę wszystkie moje dane.

I odwrotnie, całkowicie usunąłem swoją aplikację z symulatora i uruchomiłem ją ponownie, aby tworzyła moją bazę danych od podstaw. Przeniosłem tę nowo utworzoną bazę danych z mojego komputera Mac na serwer za pomocą dysku USB. Gdy plik znajdował się na moim serwerze, próbowałem uruchomić „aktualizację pobierania” w powyższym bloku kodu, ale nadal zawiesza się przy następnym uruchomieniu aplikacji z błędem „Plik na ścieżce nie wydaje się być bazą danych SQLite” wiadomość.

Na podstawie tych testów jestem pewien, że problem nie dotyczy bazy danych, którą próbuję pobrać. Coś w moim kodzie „pobierania aktualizacji” uszkadza bazę danych, ale wciąż nie byłem w stanie zrozumieć, dlaczego, ani nie znalazłem akceptowalnej alternatywnej metody, aby przekazać moje aktualizacje użytkownikom po uruchomieniu aplikacji.

UPDATE 2: Robiłem więcej poszukiwań i dowiedziałem się, że użytkownik będzie musiał wprowadzić nazwę użytkownika i hasło, aby uzyskać dostęp do dowolnego pliku na moim serwerze. Teraz wierzę, żeNSData Wracam z powyższego kodu, który jest w rzeczywistości wyzwaniem uwierzytelnienia lub czymś z tym związanym, i dlatego, kiedy go zapisuję za pomocąNSFileManager nie jest rozpoznawany jako DB sqlite.

Najprostszym rozwiązaniem, które znalazłem, aby uzyskać uwierzytelnienie, jesttutaj. Kiedy próbuję to zrobićNSData *fileData = [NSData dataWithContentsOfURL:url options:NSDataReadingMapped error:&error]; (po zmianie mojegourl jak sugerowano w linku, oczywiście), pojawia się błądNSCocoaErrorDomain Code=256, który jest po prostu nieznanym błędem. MójfileData jestnil po tym. Zauważyłem, że ten post jest dość stary, więc nie wiem, czy nadal jest obsługiwany.

Znalazłem też inne rozwiązanie problemu uwierzytelnianiatutaj za pomocąNSURLConnection zamiastdataWithContentsOfURL. Jest to znacznie nowsza wersja, ale w tym przykładzie użyto bardziej zaawansowanej składni, której nie widziałem wcześniej. Udało mi się skopiować i wkleić z przykładu, a mój projekt będzie budowany bez błędów, ale nie znam poprawnej składni do używaniafetchURL:withCompletion:failure: rutyna z mojegoUIViewController. próbowałem

NSError *error;
NSData *fileData;
ExampleDelegate *download = [[ExampleDelegate alloc] init];
[download fetchURL:url withCompletion:fileData failure:&error];

ale to daje błąd kompilacji dla wysyłania niezgodnego wskaźnika. Myślę, że nie mogę przejść prostoNSData iNSError tak jakExampleDelegateSuccess iExampleDelegateFailure obiekty, nawet jeśli to, czym one sątypedefwyd. Prawdopodobnie muszę coś zrobićfileData ierror nawracać je, ale totypedefing jest jedną z „zaawansowanej składni”, o której wspomniałem powyżej i tak naprawdę nie wiem, co robić.

Nie ma go w swoim przykładzie, ale znalazłem innyNSURLConnectionDelegate metoda zwanaconnection:didReceiveAuthenticationChallenge: tutaj Myślę, że mogę po prostu dodać do kodu z przykładu i to powinno rozwiązać mój problem z uwierzytelnianiem. Czuję, że gdybym wiedział, jak zadzwonićfetchURL Byłbym ustawiony. Czy ktoś ma jakieś rady na temat tego, co muszę zrobić, aby uzyskaćfileData ierror w to wezwanie?

questionAnswers(4)

yourAnswerToTheQuestion