Aktivera offlinesynkronisering med iOS-mobilappar
Översikt
Den här självstudien beskriver offlinesynkronisering med mobile apps-funktionen i Azure App Service för iOS. Med offlinesynkronisering kan slutanvändarna interagera med en mobilapp för att visa, lägga till eller ändra data, även om de inte har någon nätverksanslutning. Ändringar lagras i en lokal databas. När enheten är online igen synkroniseras ändringarna med fjärrserverdelen.
Om det här är din första upplevelse med Mobile Apps bör du först slutföra självstudien Skapa en iOS-app. Om du inte använder det nedladdade snabbstartsserverprojektet måste du lägga till paketen för dataåtkomsttillägg i projektet. Mer information om servertilläggspaket finns i Arbeta med .NET-serverdels-SDK för Azure Mobile Apps.
Mer information om funktionen för offlinesynkronisering finns i Synkronisering av offlinedata i Mobilappar.
Granska klientsynkroniseringskoden
Klientprojektet som du laddade ned för självstudien Skapa en iOS-app innehåller redan kod som stöder offlinesynkronisering med hjälp av en lokal Core Data-baserad databas. Det här avsnittet sammanfattar vad som redan ingår i självstudiekoden. En konceptuell översikt över funktionen finns i Offline datasynkronisering i Mobilappar.
Med hjälp av funktionen för datasynkronisering offline i Mobile Apps kan slutanvändarna interagera med en lokal databas även om nätverket inte är tillgängligt. Om du vill använda dessa funktioner i din app initierar du synkroniseringskontexten MSClient
för och refererar till ett lokalt arkiv. Sedan refererar du till tabellen via MSSyncTable-gränssnittet .
Observera att typen av medlemssynkroniseringstabell är MSSyncTable i QSTodoService.m (Objective-C) eller ToDoTableViewController.swift (Swift). Offlinesynkronisering använder det här synkroniseringstabellgränssnittet i stället för MSTable. När en synkroniseringstabell används går alla åtgärder till det lokala arkivet och synkroniseras endast med fjärrserverdelen med explicita push- och pull-åtgärder.
Om du vill hämta en referens till en synkroniseringstabell använder du metoden syncTableWithName på MSClient
. Om du vill ta bort funktionen för offlinesynkronisering använder du tableWithName i stället.
Innan några tabellåtgärder kan utföras måste det lokala arkivet initieras. Här är relevant kod:
Objective-C. I metoden QSTodoService.init :
MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context]; self.client.syncContext = [[MSSyncContext alloc] initWithDelegate:nil dataSource:store callback:nil];
Swift. I metoden 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)
Den här metoden skapar ett lokalt arkiv med hjälp
MSCoreDataStore
av gränssnittet, som tillhandahålls av Mobile Apps SDK. Du kan också ange ett annat lokalt arkiv genom att implementera protokolletMSSyncContextDataSource
. Dessutom används den första parametern för MSSyncContext för att ange en konflikthanterare. Eftersom vi har passeratnil
får vi standardkonflikthanteraren, som misslyckas vid eventuella konflikter.
Nu ska vi utföra den faktiska synkroniseringsåtgärden och hämta data från fjärrserverdelen:
Objective-C.
syncData
skickar först nya ändringar och anropar sedan pullData för att hämta data från fjärrserverdelen. Metoden pullData hämtar i sin tur nya data som matchar en fråga:-(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() } }
I Objective-C-versionen i syncData
anropar vi först pushWithCompletion i synkroniseringskontexten. Den här metoden är medlem i MSSyncContext
(och inte själva synkroniseringstabellen) eftersom den skickar ändringar över alla tabeller. Endast poster som har ändrats lokalt (via CUD-åtgärder) skickas till servern. Sedan anropas hjälpverktyget pullData , som anropar MSSyncTable.pullWithQuery för att hämta fjärrdata och lagra dem i den lokala databasen.
Eftersom push-åtgärden inte var absolut nödvändig i Swift-versionen finns det inget anrop till pushWithCompletion. Om det finns ändringar som väntar i synkroniseringskontexten för tabellen som utför en push-åtgärd utfärdar pull alltid en push-överföring först. Men om du har fler än en synkroniseringstabell är det bäst att uttryckligen anropa push för att säkerställa att allt är konsekvent mellan relaterade tabeller.
I både Objective-C- och Swift-versionerna kan du använda metoden pullWithQuery för att ange en fråga för att filtrera de poster som du vill hämta. I det här exemplet hämtar frågan alla poster i fjärrtabellen TodoItem
.
Den andra parametern för pullWithQuery är ett fråge-ID som används för inkrementell synkronisering. Inkrementell synkronisering hämtar endast poster som har ändrats sedan den senaste synkroniseringen med postens tidsstämpel (anropas UpdatedAt
updatedAt
i det lokala arkivet.) Fråge-ID:t ska vara en beskrivande sträng som är unik för varje logisk fråga i din app. Om du vill välja bort inkrementell synkronisering skickar nil
du som fråge-ID. Den här metoden kan vara potentiellt ineffektiv eftersom den hämtar alla poster för varje pull-åtgärd.
Objective-C-appen synkroniseras när du ändrar eller lägger till data, när en användare utför uppdateringsgesten och vid start.
Swift-appen synkroniseras när användaren utför uppdateringsgesten och vid start.
Eftersom appen synkroniseras när data ändras (Objective-C) eller när appen startar (Objective-C och Swift) förutsätter appen att användaren är online. I ett senare avsnitt uppdaterar du appen så att användarna kan redigera även när de är offline.
Granska Core Data-modellen
När du använder Core Data Offline Store måste du definiera specifika tabeller och fält i datamodellen. Exempelappen innehåller redan en datamodell med rätt format. I det här avsnittet går vi igenom de här tabellerna för att visa hur de används.
Öppna QSDataModel.xcdatamodeld. Fyra tabeller definieras – tre som används av SDK:t och en som används för att göra-objekten själva:
- MS_TableOperations: Spårar de objekt som måste synkroniseras med servern.
- MS_TableOperationErrors: Spårar eventuella fel som inträffar under offlinesynkronisering.
- MS_TableConfig: Spårar den senast uppdaterade tiden för den senaste synkroniseringsåtgärden för alla pull-åtgärder.
- TodoItem: Lagrar att göra-objekten. Systemkolumnerna createdAt, updatedAt och version är valfria systemegenskaper.
Anteckning
Mobile Apps SDK reserverar kolumnnamn som börjar med "``". Använd inte det här prefixet med något annat än systemkolumner. Annars ändras kolumnnamnen när du använder fjärrbacksdelen.
När du använder funktionen för offlinesynkronisering definierar du de tre systemtabellerna och datatabellen.
Systemtabeller
MS_TableOperations
Attribut | Typ |
---|---|
id | Heltal 64 |
Itemid | Sträng |
properties | Binära data |
tabell | Sträng |
tableKind | Heltal 16 |
MS_TableOperationErrors
Attribut | Typ |
---|---|
id | Sträng |
operationId | Heltal 64 |
properties | Binära data |
tableKind | Heltal 16 |
MS_TableConfig
Attribut | Typ |
---|---|
id | Sträng |
key | Sträng |
Keytype | Heltal 64 |
tabell | Sträng |
värde | Sträng |
Datatabell
TodoItem
Attribut | Typ | Anteckning |
---|---|---|
id | Sträng, markerad som obligatorisk | Primärnyckel i fjärrarkiv |
slutföra | Boolesk | Att göra-objektfält |
text | Sträng | Att göra-objektfält |
createdAt | Date | (valfritt) Kartor till createdAt system-egenskapen |
updatedAt | Date | (valfritt) Kartor till updatedAt systemegenskap |
version | Sträng | (valfritt) Används för att identifiera konflikter, mappar till version |
Ändra synkroniseringsbeteendet för appen
I det här avsnittet ändrar du appen så att den inte synkroniseras vid appstart eller när du infogar och uppdaterar objekt. Den synkroniseras bara när knappen uppdatera gest utförs.
Objective-C:
I QSTodoListViewController.m ändrar du metoden viewDidLoad för att ta bort anropet till
[self refresh]
i slutet av metoden. Nu synkroniseras inte data med servern vid start av appen. I stället synkroniseras den med innehållet i det lokala arkivet.I QSTodoService.m ändrar du definitionen för
addItem
så att den inte synkroniseras när objektet har infogats.self syncData
Ta bort blocket och ersätt det med följande:if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); }
Ändra definitionen av
completeItem
som nämnts tidigare. Ta bort blocket förself syncData
och ersätt det med följande:if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); }
Swift:
I viewDidLoad
, i ToDoTableViewController.swift, kommenterar du ut de två raderna som visas här för att stoppa synkroniseringen vid appstart. När detta skrivs uppdaterar inte Swift Todo-appen tjänsten när någon lägger till eller slutför ett objekt. Tjänsten uppdateras endast vid start av appen.
self.refreshControl?.beginRefreshing()
self.onRefresh(self.refreshControl)
Testa appen
I det här avsnittet ansluter du till en ogiltig URL för att simulera ett offlinescenario. När du lägger till dataobjekt lagras de i det lokala Core Data Store, men de synkroniseras inte med mobilappens serverdel.
Ändra mobilappens URL i QSTodoService.m till en ogiltig URL och kör appen igen:
Objective-C. I QSTodoService.m:
self.client = [MSClient clientWithApplicationURLString:@"https://sitename.azurewebsites.net.fail"];
Swift. I ToDoTableViewController.swift:
let client = MSClient(applicationURLString: "https://sitename.azurewebsites.net.fail")
Lägg till några att göra-objekt. Avsluta simulatorn (eller stäng appen med två två skäl) och starta sedan om den. Kontrollera att ändringarna bevaras.
Visa innehållet i den fjärranslutna TodoItem-tabellen :
- För en Node.js serverdel går du till Azure Portal och i mobilappens serverdel klickar du på Enkla tabeller>TodoItem.
- För en .NET-serverdel använder du antingen ett SQL-verktyg, till exempel SQL Server Management Studio eller en REST-klient, till exempel Fiddler eller Postman.
Kontrollera att de nya objekten inte har synkroniserats med servern.
Ändra url:en tillbaka till rätt i QSTodoService.m och kör appen igen.
Utför uppdateringsgesten genom att hämta listan med objekt.
En förloppssnurrare visas.Visa TodoItem-data igen. De nya och ändrade att göra-objekten ska nu visas.
Sammanfattning
För att stödja offlinesynkroniseringsfunktionen MSSyncTable
använde vi gränssnittet och initierades MSClient.syncContext
med ett lokalt arkiv. I det här fallet var det lokala arkivet en Core Data-baserad databas.
När du använder ett lokalt Core Data-arkiv måste du definiera flera tabeller med rätt systemegenskaper.
Crud-åtgärderna (normal create, read, update och delete) för mobilappar fungerar som om appen fortfarande är ansluten, men alla åtgärder utförs mot det lokala arkivet.
När vi synkroniserade det lokala arkivet med servern använde vi metoden MSSyncTable.pullWithQuery .
Ytterligare resurser
- Datasynkronisering offline i Mobile Apps
- Molntäcke: Offlinesynkronisering i Azure Mobile Services (videon handlar om Mobile Services, men Mobile Apps offlinesynkronisering fungerar på liknande sätt.)