Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
- Android
- Cordova
- iOS
- Windows
- Xamarin.Android
- Xamarin.Forms
- Xamarin.iOS
Przegląd
W tym samouczku opisano synchronizowanie w trybie offline z funkcją Mobile Apps usługi Azure App Service dla systemu iOS. Dzięki synchronizacji w trybie offline użytkownicy końcowi mogą wchodzić w interakcje z aplikacją mobilną w celu wyświetlania, dodawania lub modyfikowania danych, nawet jeśli nie mają połączenia sieciowego. Zmiany są przechowywane w lokalnej bazie danych. Po powrocie urządzenia do trybu online zmiany są synchronizowane z zdalnym zapleczem.
Jeśli to jest Twoje pierwsze doświadczenie z aplikacjami mobilnymi, powinieneś najpierw ukończyć samouczek Stwórz aplikację na iOS. Jeśli nie używasz pobranego projektu serwera Szybkiego startu, musisz dodać pakiety rozszerzeń dostępu do danych do projektu. Aby uzyskać więcej informacji na temat pakietów rozszerzeń serwera, zobacz Work with the .NET backend server SDK for Azure Mobile Apps.
Aby dowiedzieć się więcej na temat funkcji synchronizacji w trybie offline, zobacz Offline Data Sync in Mobile Apps.
Przeglądanie kodu synchronizacji klienta
Projekt klienta pobrany dla Tworzenie aplikacji iOS zawiera już kod obsługujący synchronizację w trybie offline przy użyciu lokalnej bazy danych opartej na Core Data. W tej sekcji podsumowano, co zostało już uwzględnione w kodzie samouczka. Aby zapoznać się z koncepcyjnym omówieniem tej funkcji, zobacz Offline Data Sync in Mobile Apps.
Korzystając z funkcji synchronizacji danych w trybie offline usługi Mobile Apps, użytkownicy końcowi mogą korzystać z lokalnej bazy danych nawet wtedy, gdy sieć jest niedostępna. Aby użyć tych funkcji w aplikacji, należy zainicjować kontekst synchronizacji MSClient
i odwołać się do magazynu lokalnego. Następnie odwołujesz się do swojej tabeli za pomocą interfejsu MSSyncTable.
W QSTodoService.m (Objective-C) lub ToDoTableViewController.swift (Swift), zwróć uwagę, że typ członka syncTable jest MSSyncTable. Synchronizacja w trybie offline używa tego interfejsu tabeli synchronizacji zamiast MSTable. Gdy jest używana tabela synchronizacji, wszystkie operacje przechodzą do magazynu lokalnego i są synchronizowane tylko z zdalnym zapleczem z jawnymi operacjami wypychania i ściągania.
Aby uzyskać odwołanie do tabeli synchronizacji, użyj metody syncTableWithName w MSClient
. Aby usunąć funkcje synchronizacji offline, zamiast tego użyj tableWithName.
Przed wykonaniem jakichkolwiek operacji na tabeli należy zainicjować sklep lokalny. Oto odpowiedni kod:
Objective-C. W metodzie QSTodoService.init:
MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context]; self.client.syncContext = [[MSSyncContext alloc] initWithDelegate:nil dataSource:store callback:nil];
Swift. W metodzie ToDoTableViewController.viewDidLoad:
let client = MSClient(applicationURLString: "http:// ...") // URI of the Mobile App let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext! self.store = MSCoreDataStore(managedObjectContext: managedObjectContext) client.syncContext = MSSyncContext(delegate: nil, dataSource: self.store, callback: nil)
Ta metoda tworzy magazyn lokalny przy użyciu interfejsu
MSCoreDataStore
, który udostępnia SDK dla aplikacji mobilnych. Alternatywnie możesz udostępnić inny magazyn lokalny, implementując protokółMSSyncContextDataSource
. Ponadto pierwszy parametr msSyncContext służy do określania procedury obsługi konfliktów. Ponieważ przeszliśmy przeznil
, otrzymujemy domyślną procedurę obsługi konfliktów, która zawodzi przy jakimkolwiek konflikcie.
Teraz przeprowadźmy rzeczywistą operację synchronizacji i pobierzemy dane z zdalnego zaplecza:
Objective-C.
syncData
najpierw wprowadza nowe zmiany, a następnie wywołuje pullData, aby pobrać dane z zdalnego backendu. Z kolei metoda pullData pobiera nowe dane zgodne z zapytaniem:-(void)syncData:(QSCompletionBlock)completion { // Push all changes in the sync context, and then pull new data. [self.client.syncContext pushWithCompletion:^(NSError *error) { [self logErrorIfNotNil:error]; [self pullData:completion]; }]; } -(void)pullData:(QSCompletionBlock)completion { MSQuery *query = [self.syncTable query]; // Pulls data from the remote server into the local table. // We're pulling all items and filtering in the view. // Query ID is used for incremental sync. [self.syncTable pullWithQuery:query queryId:@"allTodoItems" completion:^(NSError *error) { [self logErrorIfNotNil:error]; // Lets the caller know that we have finished. if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); } }]; }
Swift:
func onRefresh(sender: UIRefreshControl!) { UIApplication.sharedApplication().networkActivityIndicatorVisible = true self.table!.pullWithQuery(self.table?.query(), queryId: "AllRecords") { (error) -> Void in UIApplication.sharedApplication().networkActivityIndicatorVisible = false if error != nil { // A real application would handle various errors like network conditions, // server conflicts, etc. via the MSSyncContextDelegate print("Error: \(error!.description)") // We will discard our changes and keep the server's copy for simplicity if let opErrors = error!.userInfo[MSErrorPushResultKey] as? Array<MSTableOperationError> { for opError in opErrors { print("Attempted operation to item \(opError.itemId)") if (opError.operation == .Insert || opError.operation == .Delete) { print("Insert/Delete, failed discarding changes") opError.cancelOperationAndDiscardItemWithCompletion(nil) } else { print("Update failed, reverting to server's copy") opError.cancelOperationAndUpdateItem(opError.serverItem!, completion: nil) } } } } self.refreshControl?.endRefreshing() } }
W wersji Objective-C w syncData
najpierw wywołujemy pushWithCompletion w kontekście synchronizacji. Ta metoda jest elementem MSSyncContext
(a nie samej tabeli synchronizacji), ponieważ przenosi zmiany we wszystkich tabelach. Do serwera są wysyłane tylko rekordy, które zostały zmodyfikowane lokalnie (za pośrednictwem operacji CUD). Następnie wywoływana jest funkcja pomocnicza pullData, która następnie uruchamia MSSyncTable.pullWithQuery, aby pobrać zdalne dane i zapisać je w lokalnej bazie danych.
W wersji Swift, operacja wypychania nie była ściśle konieczna, więc nie ma wywołania pushWithCompletion. Jeśli w kontekście synchronizacji tabeli, która wykonuje operację wypychania, występują jakiekolwiek zmiany, ściąganie zawsze najpierw inicjuje wypchnięcie. Jeśli jednak masz więcej niż jedną tabelę synchronizacji, najlepiej jest jawnie wywołać operację push, aby w powiązanych tabelach zapewnić spójność danych.
W obu wersjach Objective-C i Swift można użyć metody pullWithQuery, aby określić zapytanie do filtrowania rekordów, które chcesz pobrać. W tym przykładzie zapytanie pobiera wszystkie rekordy w zdalnej tabeli TodoItem
.
Drugi parametr pullWithQuery to identyfikator zapytania używany do synchronizacji przyrostowej . Synchronizacja przyrostowa pobiera tylko rekordy, które zostały zmodyfikowane od ostatniej synchronizacji, wykorzystując znacznik czasu UpdatedAt
rekordu (znany jako updatedAt
w magazynie lokalnym). Identyfikator zapytania powinien być opisowym, unikatowym ciągiem dla każdego logicznego zapytania w aplikacji. Aby zrezygnować z synchronizacji przyrostowej, przekaż nil
jako identyfikator zapytania. Takie podejście może być potencjalnie nieefektywne, ponieważ pobiera wszystkie rekordy dla każdej operacji ściągania.
Aplikacja Objective-C jest synchronizowana podczas modyfikowania lub dodawania danych, gdy użytkownik wykonuje gest odświeżania i podczas uruchamiania.
Aplikacja Swift synchronizuje się, gdy użytkownik wykonuje gest odświeżania i podczas uruchamiania.
Ponieważ aplikacja synchronizuje się za każdym razem, gdy dane są modyfikowane (Objective-C) lub za każdym razem, gdy aplikacja jest uruchamiana (Objective-C i Swift), aplikacja zakłada, że użytkownik jest w trybie online. W późniejszej sekcji zaktualizujesz aplikację, aby użytkownicy mogli edytować nawet wtedy, gdy są w trybie offline.
Przeglądanie podstawowego modelu danych
W przypadku korzystania z magazynu danych podstawowych w trybie offline należy zdefiniować określone tabele i pola w modelu danych. Przykładowa aplikacja zawiera już model danych z odpowiednim formatem. W tej sekcji omówimy te tabele, aby pokazać, jak są używane.
Otwórz QSDataModel.xcdatamodeld. Cztery tabele są zdefiniowane — trzy, które są używane przez zestaw SDK i jeden, który jest używany dla samych elementów to-do:
- MS_TableOperations: śledzi elementy, które należy zsynchronizować z serwerem.
- MS_TableOperationErrors: śledzi wszelkie błędy występujące podczas synchronizacji w trybie offline.
- MS_TableConfig: Rejestruje czas ostatniej aktualizacji dla ostatniej operacji synchronizacji we wszystkich operacjach ściągania.
- TodoItem: przechowuje elementy to-do. Kolumny systemowe createdAt, updatedAtoraz wersja są opcjonalnymi właściwościami systemu.
Uwaga
Zestaw SDK usługi Mobile Apps rezerwuje nazwy kolumn rozpoczynające się od "``". Nie używaj tego prefiksu z innymi kolumnami systemowymi. W przeciwnym razie nazwy kolumn są modyfikowane podczas korzystania z zdalnego zaplecza systemu.
W przypadku korzystania z funkcji synchronizacji offline zdefiniuj trzy tabele systemowe i tabelę danych.
Tabele systemowe
MS_TableOperations
atrybuty tabeli
Atrybut | Typ |
---|---|
id | Liczba całkowita 64 |
identyfikator przedmiotu | Sznurek |
właściwości | Dane binarne |
stół | Sznurek |
tableKind | Int16 |
MS_TableOperationErrors
atrybuty tabeli
Atrybut | Typ |
---|---|
id | Sznurek |
operationId | Liczba całkowita 64 |
właściwości | Dane binarne |
tableKind | Liczba całkowita 16 |
MS_TableConfig
Atrybut | Typ |
---|---|
id | Sznurek |
klucz | Sznurek |
typ klucza | Liczba całkowita 64 |
stół | Sznurek |
wartość | Sznurek |
Tabela danych
todoItem
Atrybut | Typ | Uwaga |
---|---|---|
id | Ciąg, oznaczony jako wymagany | Klucz podstawowy w magazynie zdalnym |
ukończyć | Boolean | Pole zadania do wykonania |
Tekst | Sznurek | Pole zadania do wykonania |
createdAt | Data | (opcjonalnie) Odnosi się do właściwości systemowej createdAt |
data aktualizacji | Data | (opcjonalnie) Mapuje zaktualizowanąW właściwość systemowa |
wersja | Sznurek | (opcjonalnie) Służy do wykrywania konfliktów, odpowiada wersji |
Zmienianie zachowania synchronizacji aplikacji
W tej sekcji zmodyfikujesz aplikację tak, aby nie była synchronizowana podczas uruchamiania aplikacji ani podczas wstawiania i aktualizowania elementów. Synchronizuje się tylko po wykonaniu przycisku gestu odświeżania.
Objective-C:
W QSTodoListViewController.mzmień metodę viewDidLoad, aby usunąć wywołanie metody
[self refresh]
na końcu. Teraz dane nie są synchronizowane z serwerem podczas uruchamiania aplikacji. Zamiast tego, synchronizowana jest z zawartością lokalnego magazynu.W QSTodoService.mzmodyfikuj definicję
addItem
, aby nie była synchronizowana po wstawieniu elementu. Usuń blokself syncData
i zastąp go następującymi elementami:if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); }
Zmodyfikuj definicję
completeItem
, jak wspomniano wcześniej. Usuń blok dlaself syncData
i zastąp go następującymi elementami:if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); }
Swift:
W viewDidLoad
w ToDoTableViewController.swiftzakomentuj dwie linie przedstawione tutaj, aby zatrzymać synchronizację przy uruchomieniu aplikacji. W momencie pisania tego tekstu aplikacja Swift Todo nie aktualizuje usługi, gdy ktoś dodaje lub kończy element. Aktualizuje usługę tylko podczas uruchamiania aplikacji.
self.refreshControl?.beginRefreshing()
self.onRefresh(self.refreshControl)
Testowanie aplikacji
W tej sekcji łączysz się z nieprawidłowym adresem URL, aby zsymulować scenariusz offline. Po dodaniu elementów danych są one przechowywane w lokalnym magazynie danych Core Data Store, ale nie są one synchronizowane z zapleczem aplikacji mobilnej.
Zmień adres URL aplikacji mobilnej w QSTodoService.m na nieprawidłowy adres URL i uruchom aplikację ponownie:
Objective-C. W pliku QSTodoService.m:
self.client = [MSClient clientWithApplicationURLString:@"https://sitename.azurewebsites.net.fail"];
Swift. W pliku ToDoTableViewController.swift:
let client = MSClient(applicationURLString: "https://sitename.azurewebsites.net.fail")
Dodaj niektóre elementy to-do. Zamknij symulator (lub wymuś zamknięcie aplikacji), a następnie uruchom go ponownie. Sprawdź, czy zmiany są utrwalane.
Wyświetl zawartość zdalnej tabeli TodoItem:
- Aby uzyskać zaplecze Node.js, przejdź do witryny Azure Portal, a następnie w zapleczu aplikacji mobilnej kliknij pozycję Łatwe tabele>TodoItem.
- W przypadku zaplecza platformy .NET użyj narzędzia SQL, takiego jak SQL Server Management Studio, lub klienta REST, takiego jak Fiddler lub Postman.
Sprawdź, czy nowe elementy nie zostały zsynchronizowane z serwerem, a nie.
Zmień adres URL z powrotem na poprawny w QSTodoService.mi uruchom ponownie aplikację.
Wykonaj gest odświeżania, ściągając listę elementów.
Jest wyświetlany wskaźnik postępu.Ponownie wyświetl dane TodoItem. Nowe i zmienione elementy to-do powinny być teraz wyświetlane.
Podsumowanie
Aby obsługiwać funkcję synchronizacji w trybie offline, użyliśmy interfejsu MSSyncTable
i zainicjowaliśmy MSClient.syncContext
z magazynem lokalnym. W tym przypadku magazyn lokalny był bazą danych opartą na danych podstawowych.
W przypadku korzystania z lokalnego magazynu Core Data musisz zdefiniować kilka tabel z poprawnymi właściwościami systemu.
Normalne operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD) dla aplikacji mobilnych działają tak, jakby aplikacja jest nadal połączona, ale wszystkie operacje występują w sklepie lokalnym.
Podczas synchronizowania magazynu lokalnego z serwerem użyliśmy metody MSSyncTable.pullWithQuery.
Dodatkowe zasoby
- synchronizacji danych w trybie offline w usłudze Mobile Apps
- Cloud Cover: synchronizacja w trybie offline w usłudze Azure Mobile Services (film wideo dotyczy usług Mobile Services, ale synchronizacja w trybie offline usługi Mobile Apps działa w podobny sposób).