Using Xamarin.iOS preview of Mobile Services offline
Before we start
The steps below are for the Xamarin plugin for Visual Studio. If you're using Xamarin Studio instead, you should install the nuget addin for Xamarin and most of the instructions should be the same.
Using offline in Xamarin.iOS
Create a new Mobile Service or use an existing one and download the Xamarin quickstart for iOS.
Open the project and remove the reference to to Azure Mobile Services SDK in Components (we'll be adding a newer on via NuGet)
Install the prerelease package of the Mobile Services SQLiteStore using the following command in the Package Manager Console:
install-package WindowsAzure.MobileServices.SQLiteStore -Pre
In the references node, remove the references to
System.IO
,System.Runtime
andSystem.Threading.Tasks
Edit QSTodoService.cs
Add the declarations
using Microsoft.WindowsAzure.MobileServices; using Microsoft.WindowsAzure.MobileServices.Sync;
Change the type of the member
todoTable
toIMobileServiceSyncTable<ToDoItem> todoTable;
In the constructor for
QSTodoService
, change the initializer fortodoTable
:todoTable = client.GetSyncTable <ToDoItem> ();
In the constructor for
QSTodoService
, add this as the second line:SQLitePCL.CurrentPlatform.Init();
Add a method
InitializeAsync
:public async Task InitializeStoreAsync() { string path = "test1.db"; var store = new MobileServiceSQLiteStore(path); store.DefineTable<ToDoItem>(); await client.SyncContext.InitializeAsync(store); }
Add a method
SyncAsync
:public async Task SyncAsync() { try { await this.client.SyncContext.PushAsync(); await this.todoTable.PullAsync(); } catch (MobileServiceInvalidOperationException e) { Console.Error.WriteLine(@"Sync Failed: {0}", e.Message); } }
Edit QSTodoListViewController.cs
Add a call to
InitializeStoreAsync
inViewDidLoad()
, after the initialization oftodoService
:public override async void ViewDidLoad () { base.ViewDidLoad (); todoService = QSTodoService.DefaultService; await todoService.InitializeStoreAsync(); ... // more code }
Modify the method
AddRefreshControl
to callSyncAsync
before the call toRefreshAsync
:RefreshControl.ValueChanged += async (sender, e) => { await todoService.SyncAsync(); await RefreshAsync(); };
Edit ToDoItem.cs
Add the using statement:
using Microsoft.WindowsAzure.MobileServices;
Add the following members to the class
ToDoItem
:[Version] public string Version { get; set; } public override string ToString() { return "Text: " + Text + "\nComplete: " + Complete + "\n"; }
Optional: Add conflict handling
In
QSTodoService.cs
, modify the last line ofInitializeAsync
to specify a sync handler:await client.SyncContext.InitializeAsync(store, new ToDoSyncHandler());
Add a new sync handler:
Running the app
When you launch the app, the list of items will be empty, since it will no longer read items from the mobile service, but rather from the local store. Triggering the refresh operation will result in a call to SyncAsync
which will read items from the mobile service into the local SQLite store.
To manually trigger a conflict, you should synchronize changes, then change the item on the server (through either a REST client or SQL Server Management Studio). Then, change the item locally and perform the refresh gesture. If you added the conflict handler, then you will see a dialog that will ask how to resolve the conflict, in favor of the server or client.