Megosztás a következőn keresztül:


Offline szinkronizálás engedélyezése iOS-mobilalkalmazásokkal

Áttekintés

Ez az oktatóanyag az iOS Azure App Service Mobile Apps szolgáltatásával való offline szinkronizálást ismerteti. Az offline szinkronizálással a végfelhasználók akkor is megtekinthetik, hozzáadhatják vagy módosíthatják az adatokat a mobilalkalmazásokkal, ha nincs hálózati kapcsolatuk. A módosítások egy helyi adatbázisban vannak tárolva. Miután az eszköz újra online állapotba került, a rendszer szinkronizálja a módosításokat a távoli háttérrendszerrel.

Ha ez az első tapasztalata a Mobile Apps szolgáltatással kapcsolatban, először végezze el az iOS-alkalmazás létrehozása című oktatóanyagot. Ha nem használja a letöltött gyors üzembe helyezési kiszolgálóprojektet, hozzá kell adnia az adatelérési bővítménycsomagokat a projekthez. A kiszolgálóbővítmény-csomagokkal kapcsolatos további információkért lásd : Az Azure Mobile Appshez készült .NET-háttérkiszolgáló SDK használata.

Az offline szinkronizálási funkcióval kapcsolatos további információkért lásd: Offline adatszinkronizálás a Mobile Appsben.

Az ügyfél szinkronizálási kódjának áttekintése

Az iOS-alkalmazás létrehozása oktatóanyaghoz letöltött ügyfélprojekt már tartalmaz olyan kódot, amely támogatja az offline szinkronizálást egy helyi Core Data-alapú adatbázis használatával. Ez a szakasz összefoglalja, hogy mi szerepel az oktatóanyag kódjában. A funkció fogalmi áttekintését az Offline adatszinkronizálás a Mobile Appsben című témakörben tekintheti meg.

A Mobile Apps offline adatszinkronizálási funkciójával a végfelhasználók akkor is használhatják a helyi adatbázisokat, ha a hálózat elérhetetlen. Ha ezeket a funkciókat szeretné használni az alkalmazásban, inicializálja a szinkronizálási MSClient környezetet, és hivatkozik egy helyi áruházra. Ezután az MSSyncTable felületen keresztül hivatkozhat a táblára.

A QSTodoService.m (Objective-C) vagy a ToDoTableViewController.swift (Swift) alkalmazásban figyelje meg, hogy a tagszinkronizálási tábla típusa MSSyncTable. Az offline szinkronizálás ezt a szinkronizálási táblafelületet használja az MSTable helyett. Szinkronizálási tábla használata esetén az összes művelet a helyi tárolóba kerül, és csak a távoli háttérrendszerrel szinkronizálódik explicit leküldéses és lekéréses műveletekkel.

Egy szinkronizálási táblára mutató hivatkozás lekéréséhez használja a syncTableWithName metódust a következőn MSClient: . Az offline szinkronizálási funkciók eltávolításához használja helyette a tableWithName parancsot .

A táblaműveletek végrehajtása előtt a helyi tárolót inicializálni kell. Íme a megfelelő kód:

  • Objective-C. A QSTodoService.init metódusban :

    MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context];
    self.client.syncContext = [[MSSyncContext alloc] initWithDelegate:nil dataSource:store callback:nil];
    
  • Swift. A ToDoTableViewController.viewDidLoad metódusban:

    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)
    

    Ez a metódus létrehoz egy helyi tárolót a MSCoreDataStore Mobile Apps SDK által biztosított felület használatával. Másik lehetőségként másik helyi tárolót is megadhat a MSSyncContextDataSource protokoll implementálásával. Emellett az MSSyncContext első paramétere egy ütközéskezelő megadására szolgál. Mivel a művelet sikeres nilvolt, az alapértelmezett ütközéskezelőt kapjuk, amely bármilyen ütközés esetén meghiúsul.

Most végezzük el a tényleges szinkronizálási műveletet, és lekérjük az adatokat a távoli háttérrendszerből:

  • Objective-C. syncData először leküldi az új módosításokat, majd meghívja a pullData-t , hogy adatokat szerezzen be a távoli háttérrendszerből. A pullData metódus viszont egy lekérdezésnek megfelelő új adatokat kap:

    -(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()
        }
    }
    

Az Objective-C verzióban syncDataelőször a pushWithCompletion parancsot hívjuk meg a szinkronizálási környezetben. Ez a metódus (és nem maga a szinkronizálási tábla) tagja MSSyncContext , mert minden táblában leküldi a módosításokat. A rendszer csak a helyileg (CUD-műveleteken keresztül) valamilyen módon módosított rekordokat küldi el a kiszolgálónak. Ezután meghívja a pullData segítőt, amely meghívja az MSSyncTable.pullWithQueryt a távoli adatok lekéréséhez és a helyi adatbázisban való tárolásához.

A Swift verzióban, mivel a leküldéses művelet nem volt feltétlenül szükséges, nincs hívás a pushWithCompletion parancsra. Ha a leküldéses műveletet végző tábla szinkronizálási környezetében vannak függőben lévő módosítások, a lekérés mindig leküldéses műveletet ad vissza. Ha azonban egynél több szinkronizálási táblával rendelkezik, a legjobb, ha kifejezetten leküldést hív meg, hogy minden konzisztens legyen a kapcsolódó táblák között.

Az Objective-C és a Swift verziókban a pullWithQuery metódussal is megadhat egy lekérdezést a lekérni kívánt rekordok szűréséhez. Ebben a példában a lekérdezés lekéri a távoli TodoItem tábla összes rekordjait.

A pullWithQuery második paramétere a növekményes szinkronizáláshoz használt lekérdezésazonosító. A növekményes szinkronizálás csak azokat a rekordokat kéri le, amelyek az utolsó szinkronizálás óta módosultak a rekord időbélyegével UpdatedAt (a helyi tárolóban). updatedAt A lekérdezésazonosítónak egy leíró sztringnek kell lennie, amely egyedi az alkalmazás minden logikai lekérdezéséhez. A növekményes szinkronizálás letiltásához adja meg nil a lekérdezés azonosítóját. Ez a megközelítés valószínűleg nem hatékony, mert minden egyes lekérési művelethez lekéri az összes rekordot.

Az Objective-C alkalmazás az adatok módosításakor vagy hozzáadásakor, a frissítési kézmozdulat végrehajtásakor és az indításkor szinkronizálódik.

A Swift alkalmazás akkor szinkronizálódik, amikor a felhasználó végrehajtja a frissítési kézmozdulatot, és elindul.

Mivel az alkalmazás az adatok módosításakor (Objective-C) vagy az alkalmazás indításakor (Objective-C és Swift) szinkronizálódik, az alkalmazás feltételezi, hogy a felhasználó online állapotban van. Egy későbbi szakaszban frissíteni fogja az alkalmazást, hogy a felhasználók akkor is szerkeszthessenek, ha offline állapotban vannak.

A Core Data-modell áttekintése

Az alapadatok offline tárolójának használatakor meg kell határoznia az adatmodell adott tábláit és mezőit. A mintaalkalmazás már tartalmaz egy megfelelő formátumú adatmodellt. Ebben a szakaszban végigvezetjük ezeket a táblázatokat, hogy bemutassuk a használatuk módját.

Nyissa meg a QSDataModel.xcdatamodeld fájlt. Négy tábla van definiálva – három olyan, amelyet az SDK használ, és egy, amelyet maguk a teendőkhöz használnak:

  • MS_TableOperations: Nyomon követi a kiszolgálóval szinkronizálandó elemeket.
  • MS_TableOperationErrors: Nyomon követi az offline szinkronizálás során előforduló hibákat.
  • MS_TableConfig: Nyomon követi az összes lekéréses művelet legutóbbi szinkronizálási műveletének utolsó frissítési időpontját.
  • Teendők: A teendők tárolására. A createdAt, updatedAt és version rendszeroszlopok választható rendszertulajdonságok.

Megjegyzés

A Mobile Apps SDK fenntartja a "``" betűvel kezdődő oszlopneveket. Ne használja ezt az előtagot a rendszeroszlopok kivételével. Ellenkező esetben az oszlopnevek a távoli háttérrendszer használatakor módosulnak.

Az offline szinkronizálási funkció használatakor adja meg a három rendszertáblát és az adattáblát.

Rendszertáblák

MS_TableOperations

MS_TableOperations táblaattribútumok

Attribútum Típus
id Egész szám 64
Itemid Sztring
properties Bináris adatok
tábla Sztring
tableKind Egész szám 16

MS_TableOperationErrors

MS_TableOperationErrors táblaattribútumok

Attribútum Típus
id Sztring
operationId Egész szám 64
properties Bináris adatok
tableKind Egész szám 16

MS_TableConfig

Attribútum Típus
id Sztring
kulcs Sztring
keyType Egész szám 64
tábla Sztring
érték Sztring

Adattábla

TodoItem

Attribútum Típus Megjegyzés
id Kötelezőként megjelölt sztring Elsődleges kulcs a távoli tárolóban
Teljes Logikai Teendő mező
szöveg Sztring Teendő mező
createdAt Dátum (nem kötelező) A createdAt rendszertulajdonság leképezése
updatedAt Dátum (nem kötelező) A frissített Rendszer tulajdonság leképezése
version Sztring (nem kötelező) Ütközések észlelésére szolgál, verzióra van leképezve

Az alkalmazás szinkronizálási viselkedésének módosítása

Ebben a szakaszban úgy módosítja az alkalmazást, hogy az ne szinkronizáljon az alkalmazás indításakor, illetve elemek beszúrásakor és frissítésekor. Csak a frissítési kézmozdulat végrehajtásakor szinkronizálódik.

Objective-C:

  1. A QSTodoListViewController.m fájlban módosítsa a viewDidLoad metódust a metódus végén található hívás eltávolításához [self refresh] . Most az adatok nincsenek szinkronizálva a kiszolgálóval az alkalmazás indításakor. Ehelyett szinkronizálva van a helyi tároló tartalmával.

  2. A QSTodoService.m-ben módosítsa annak definícióját addItem , hogy az ne szinkronizáljon az elem beszúrása után. Távolítsa el a self syncData blokkot, és cserélje le a következőre:

    if (completion != nil) {
        dispatch_async(dispatch_get_main_queue(), completion);
    }
    
  3. Módosítsa a korábban említett definíciót completeItem . Távolítsa el a blokkot, self syncData és cserélje le a következőre:

    if (completion != nil) {
        dispatch_async(dispatch_get_main_queue(), completion);
    }
    

Swift:

A viewDidLoadToDoTableViewController.swift fájlban tegye megjegyzésbe az itt látható két sort, hogy leállítsuk a szinkronizálást az alkalmazás indításakor. Az írás időpontjában a Swift Todo alkalmazás nem frissíti a szolgáltatást, amikor valaki hozzáad vagy befejez egy elemet. Csak az alkalmazás indításakor frissíti a szolgáltatást.

self.refreshControl?.beginRefreshing()
self.onRefresh(self.refreshControl)

Az alkalmazás tesztelése

Ebben a szakaszban egy érvénytelen URL-címhez csatlakozik egy offline forgatókönyv szimulálásához. Az adatelemek hozzáadásakor azok a helyi Core Data Store-ban vannak tárolva, de nincsenek szinkronizálva a mobilalkalmazás háttérrendszerével.

  1. Módosítsa a QSTodoService.m mobilalkalmazás URL-címét érvénytelen URL-címre, majd futtassa újra az alkalmazást:

    Objective-C. A QSTodoService.m-ben:

    self.client = [MSClient clientWithApplicationURLString:@"https://sitename.azurewebsites.net.fail"];
    

    Swift. A ToDoTableViewController.swift fájlban:

    let client = MSClient(applicationURLString: "https://sitename.azurewebsites.net.fail")
    
  2. Vegyen fel néhány teendőt. Lépjen ki a szimulátorból (vagy kényszerítetten zárja be az alkalmazást), majd indítsa újra. Ellenőrizze, hogy a módosítások megmaradnak-e.

  3. A távoli TodoItem-tábla tartalmának megtekintése:

    • Ha Node.js háttérrendszert szeretne, lépjen a Azure Portal, és a mobilalkalmazás háttérrendszerében kattintson az Easy TablesTodoItem (Egyszerű táblázatok>) gombra.
    • .NET-háttérrendszer esetén használjon SQL-eszközt, például SQL Server Management Studio vagy REST-ügyfelet, például a Fiddlert vagy a Postmant.
  4. Ellenőrizze, hogy az új elemek nincsenek-e szinkronizálva a kiszolgálóval.

  5. Módosítsa az URL-címet a megfelelőre a QSTodoService.m-ben, és futtassa újra az alkalmazást.

  6. A frissítési kézmozdulatot az elemek listájának lekérésével hajtja végre.
    Megjelenik egy folyamat-léptető.

  7. Tekintse meg újra a TodoItem-adatokat . Ekkor megjelennek az új és módosított teendők.

Összefoglalás

Az offline szinkronizálási funkció támogatásához a MSSyncTable felületet használtuk, és inicializáltuk MSClient.syncContext egy helyi tárolóval. Ebben az esetben a helyi tároló egy Core Data-alapú adatbázis volt.

Core Data helyi tároló használata esetén több táblát kell meghatároznia a megfelelő rendszertulajdonságokkal.

A mobilalkalmazások normál létrehozási, olvasási, frissítési és törlési (CRUD) műveletei úgy működnek, mintha az alkalmazás továbbra is csatlakoztatva van volna, de minden művelet a helyi áruházban történik.

Amikor szinkronizáltuk a helyi tárolót a kiszolgálóval, az MSSyncTable.pullWithQuery metódust használtuk.

További források