Tuesday, May 15, 2012

LocationServices for Windows Phone: now with caching support!

I’ve added a simple caching container for the framework, enabling you to cache the results from a criteria.

Simply set the CacheProvider property on the service to a cache provider that implements ICacheProvider from the framework, then configure the caching in the CacheSettings property of the criteria.

Consider the following Instagram criteria search:

        public Service.Instagram.Reactive.ServiceLayer instagramservicelayer { get; private set; }

        public MainViewModel()
        {
            this.instagramservicelayer = new Service.Instagram.Reactive.ServiceLayer();
        }

        private void WireInstagramPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem instagram = new GenericPivotItem() { Header = "photos", Source = "instagram" };
            SearchCriterias.Instagram.MediaByLocation criteria = new SearchCriterias.Instagram.MediaByLocation(new GeoCoordinate(40.74917, -73.98529));
            
            var rxinstagram = instagramservicelayer.GetMediaByLocation(criteria)
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(instagram);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        instagram.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });
        }

Now, to add caching to that you simply add a provider to the service and specify caching on the criteria:

        public MainViewModel()
        {
            this.instagramservicelayer = new Service.Instagram.Reactive.ServiceLayer() 
            { 
                CacheProvider = new LocationServices.Caching.IsoStoreCache.IsolatedStorageCacheProvider() 
            };
        }

        public Service.Instagram.Reactive.ServiceLayer instagramservicelayer { get; private set; }

        private void WireInstagramPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem instagram = new GenericPivotItem() { Header = "photos", Source = "instagram" };
            SearchCriterias.Instagram.MediaByLocation criteria = new SearchCriterias.Instagram.MediaByLocation(new GeoCoordinate(40.74917, -73.98529))
                {
                    CacheSettings = new SearchCriterias.CriteriaCacheSettings(60 * 60 * 24)
                };
 
            var rxinstagram = instagramservicelayer.GetMediaByLocation(criteria)
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(instagram);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        instagram.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });

        }

In the code above the cache duration (specified in the CacheSettings) is the number of seconds the cached item(s) should be considered valid, here 60*60*24 = 24 hours.

You can of course create your own cache provider - simply implement the ICacheProvider interface and it’s methods in your own provider class. You’ll find the interface in the Caching namespace in the Usoniandream.WindowsPhone.LocationServices library.

The framework libraries, source code and sample app are all on GitHub: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

No comments: