Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Synchronizing Data for Offline Access with Azure Mobile Service

One of the core requirements of our real estate inspection tool is that it’s available offline. To this end I can leverage the synchronisation component of the Azure Mobile Service SDK to synchronise the entities we referenced in the previous post. In order to make use of this I will need to add another NuGet package which is the WindowsAzure.MobileService.SqliteStore package – you can think of this as the Sqlite storage wrapper which will handle persisting and providing an access layer to the offline data.

image

One thing you may notice that that there is a warning in your References list after adding this NuGet package. In this case you either haven’t got the Windows/Windows Phone Sqlite Extensions installed, or your version doesn’t align with the reference that was added as part of adding the previous package. After making sure you have the most recent version of the Sqlite extensions installed (get them from the Sqlite Download Page), you can then simply delete the reference with the warning, and then add a new reference to the extensions you just installed.

image

Next, you’ll probably still see warnings against the Sqlite and Visual C++ references – this is because neither of these references supports compiling using the AnyCPU option. Switch to building for one of the other platforms (x86 is probably the easiest to use for development since it’s compatible with the Windows Phone emulator, just don’t forget that if you’re testing  on an RT device or on a real Windows Phone, you’ll need to use an ARM build).

image

Now we have our references, let’s add some code to demonstrate synchronising, reading and writing from the offline data store. I already have my MobileService that I setup in a previous post but I’m going to replace my the method call to GetTable<>.ToListAsync() with code that will synchronise data for offline access. I’ll start by defining the offline data file, inspections.db, along with the entity tables that I want to include in the database. I then initialize the SyncContext of the MobileService using this data store

var data = new MobileServiceSQLiteStore("inspections.db");
data.DefineTable<RealEstateProperty>();
data.DefineTable<Inspection>();

await MobileService.SyncContext.InitializeAsync(data, new MobileServiceSyncHandler());

Invoking a sync is actually a two part process. First you need to pull data down from the Mobile Service. Here we’re passing in a default table query (which will pull down all entities in the table), and using the name of the data type as the synchronisation key. I repeat this for both entity types I want to synchronize.

var propertyQ = MobileService.GetSyncTable<RealEstateProperty>().CreateQuery();
await MobileService.GetSyncTable<RealEstateProperty>().PullAsync(typeof(RealEstateProperty).Name, propertyQ);

var inspectionQ = MobileService.GetSyncTable<Inspection>().CreateQuery();
await MobileService.GetSyncTable<Inspection>().PullAsync(typeof(Inspection).Name, inspectionQ);

You’ll notice that I’m calling GetSyncTable instead of GetTable – this is because I want to reference the local offline table, rather than the Mobile Service endpoint. Now that I’ve pulled data down from the Mobile Service I can call ToListAsync on the sync table to retrieve all the elements that are contained in the offline table.

var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();

Inserting items is a simple as creating them and inserting them into the sync table

var inspection = new Inspection
{
    InspectedBy = "Joe",
    RealEstatePropertyId = props[0].Id
};
await MobileService.GetSyncTable<Inspection>().InsertAsync(inspection);

Of course this only adds them to the local offline table. To push them up to the Mobile Service I call PushAsync on the synchronization context.
await MobileService.SyncContext.PushAsync();

Lastly to validate that the new items have appeared in the Mobile Service I can query it directly to get all items in the Mobile Service table

var inspections = await MobileService.GetTable<Inspection>().ToListAsync();

If you’re interested in what’s stored in the offline data file it can be found at C:\Users\<username>\AppData\Local\Packages\<package id>\LocalState and you can use a tool like SqliteStudio to view the contents of the database file

image

And you can use the SQL query window to write and execute sql to view the data.

image

Pingbacks and trackbacks (1)+

Comments are closed