Over a million developers have joined DZone.

Xamarin.Forms, Akavache, and I: Initial Setup

DZone's Guide to

Xamarin.Forms, Akavache, and I: Initial Setup

In this series, we'll see how to make use of the Akavache caching solution with Xamarin, starting with getting everything set up and ready to go.

· Mobile Zone ·
Free Resource

Caching is never a trivial task. Sometimes, we can use built-in storage, but more often, these take quite some time when we are storing a large amount of data (e.g. large datasets or large JSON strings). I tried quite a few approaches, including:

  • Built-in storage
  • Self-handled files
  • Plugins that use one or both of the above
  • Akavache (which uses SQLite under the hood)

Why Akavache Wins

Well, the major reason is quite easy. It is fast. Really fast - at least compared to the other options. You may not notice the difference until you are using a background task that relies on the cached data or until you try to truly optimize startup performance of your Xamarin Android app. Those were the reasons for me to switch because once implemented, it does handle both jobs perfectly. Because it is so fast, there are quite a lot of apps that use it. Bonus: there are a lot of tips on StackOverflow as well as on GitHub, as it is already used by a lot of developers.

Getting Your Projects Ready

Well, as often, it all starts with the installation of NuGet packages. As I am trying to follow good practices wherever I can, I am using .netStandard whenever possible. The latest stable version of Akavache does work partially in .netStandard projects, but I recommend to use the latest alpha (by the time of this post) in your .netStandard project (even if VisualStudio keeps telling you that a pre-release dependency is not a good idea). If you are using the package reference in your project files, there might be some additional work to bring everything to build and run smoothly, especially in a Xamarin.Android project.

Your mileage may vary, but in my experience, you should install the following dependencies and Akavache separately:

After installing these packages in your Xamarin.Forms and platform projects, we are ready for the next step.

Initializing Akavache

Basically, you should be able to use Akavache very simply by just defining the application name like this during application initialization:

BlobCache.ApplicationName = "MyAkavachePoweredApp";

You can do this assignment in your platform project as well as in your Xamarin.Forms project; both ways will work. Just remember to do this, as to get my code working, this is a needed step.

There are static properties like BlobCache.LocalMachine one can use to cache data. However, once your app uses an advanced library like Akavache, it is very likely that the complexity of your app will force you into a more complex scenario. In my case, the use of a scheduled job on Android was the reason why I did the initialization on my own. The scheduled job starts a process for the application and the job updates data in the cache that the application uses. There were several cases where the standard initialization did not work, so I decided to make the special case to a standard case. The following code will also work in simple scenarios but keeps doors open for more complex ones as well. The second reason why I did my own implementation is the MVVM structure of my apps.

IBlobCacheInstanceHelper Rules Them All

When we want to use platform implementations, it all starts with an interface that dictates the functionality. Let's start with this simple one:

public interface IBlobCacheInstanceHelper
    void Init();
    IBlobCache LocalMachineCache { get; set; }

We are defining our own IBlobCacheinstance, which we will initialize with the Init() method on each platform. Let's have a look on the platform implementations:

[assembly: Xamarin.Forms.Dependency(typeof(PlatformBlobCacheInstanceHelper))]
    public class PlatformBlobCacheInstanceHelper : IBlobCacheInstanceHelper
        private IFilesystemProvider _filesystemProvider;

        public PlatformBlobCacheInstanceHelper() { }

        public void Init()
            _filesystemProvider = Locator.Current.GetService<IFilesystemProvider>();

        public IBlobCache LocalMachineCache { get; set; }

        private void GetLocalMachineCache()

            var localCache = new Lazy<IBlobCache>(() => 
                                                      return new SQLitePersistentBlobCache(Path.Combine(_filesystemProvider.GetDefaultLocalMachineCacheDirectory(), "blobs.db"), BlobCache.TaskpoolScheduler);

            this.LocalMachineCache = localCache.Value;

        //TODO: implement other cache types if necessary at some point

Let me explain what this code does.

As SQLite, which is powering Akavache, is file based, we need to provide a file path. The Init() method assigns Akavache's internal IFileSystemProviderinterface to the internal member. After getting an instance via Splat's Locator, we can now use it to get the file path and create the .db-file for our local cache. The GetLocalMachineCache()method is basically a copy of Akavache's internal registration. It lazily creates an instance of BlobCache through the IBlobCacheinterface. The create instance is then passed to the LocalMachineCacheproperty, which we will use later on. Finally, we will be using the DependencyService of Xamarin.Forms to get an instance of our platform implementation, which is why we need to define the Dependency attribute as well.

Note: you can name the file whatever you want. If you are already using Akavache and want to change the instance handling, you should keep the original names used by Akavache. This way, your users will not lose any data.

This implementation can be used for your Android, iOS, and UWP projects within your Xamarin.Forms app. If you are wondering why I do this separately for every platform, you are right. Until now, there is no need to do it that way. The code above would also work solely in your Xamarin.Forms project. Once you are coming to the point where you need encrypted data in your cache, the platform implementations will change on every platform. This will be topic of a future blog post, however.

If you have been reading my series about MVVMLight, you may guess the next step already. This is how I initialize the platform implementation within my ViewModelLocator:

var cacheInstanceHelper = DependencyService.Get<IBlobCacheInstanceHelper>();
if (!SimpleIoc.Default.IsRegistered<IBlobCacheInstanceHelper>())
     SimpleIoc.Default.Register<IBlobCacheInstanceHelper>(()=> cacheInstanceHelper);


So that's it, we are now ready to use our local cache powered by Akavache within our Xamarin.Forms project. In the next post, we will have a look at how to use Akavache for storing and retrieving data.

Until then, happy coding, everyone!

ios ,akavache ,xamarin ,sqlite ,caching ,mobile ,android ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}