Makale Özeti

Bu makalemde Windows 8 Metro Style uygulamalarda uygulamalarımıza ait verileri nasıl tutabileceğimizi göreceğiz. Bu sayede suspended olmuş veya terminated olmuş bir uygulamanın verilerini nasıl koruyabileceğini veya farklı makinalar arasında bilginin nasıl taşınabildiğini inceleyeceğiz

Makale

Merhabalar,

Bu makalemde Windows 8 Metro Style uygulamalarda uygulamalarımıza ait verileri nasıl tutabileceğimizi göreceğiz. Bu sayede suspended olmuş veya terminated olmuş bir uygulamanın verilerini nasıl koruyabileceğini veya farklı makinalar arasında bilginin nasıl taşınabildiğini inceleyeceğiz. Makalenin sonunda da incelediğimiz tüm bu kombinasyonlarda Application Data yazabilen ve okuyabilen bir manager sınıfı yazacağız.

Application data bir uygulamaya ait özel bilgilerdir. Application Data'da tutulması önerilen bilgiler kullanıcının tercihleri, ayarları, cache'lenmesi gereken ufak verilerdir. Application Data'ya uygulama çalıştığı sürece erişmek mümkün olmaktadır. Application Data olarak ne çeşit verileri, ne gibi fiziksel saklama ortamlarını ve ne gibi depolama mekanizmaları olduğundan makalemin ilerleyen kısımlarında bahsedeceğim.

Application data ile bilinmesi gereken en önemli bilgi Application Data'ya uygulama çalıştığı sürece erişilebilmesi ve uygulama kaldırıldığında Application Data'nın tekrar erişilemez bir şekilde silindiğidir. Bundan dolayı kullanıcıların kritik bilgilerini saklamak için Application Data yerine kullanıcının fiziksel disk sürücüsü veya Skydrive tercih edilmelidir.

Application Data temel olarak iki farklı depolama alanında veri tutmaktadır. Bunlardan biri registry(setting) diğeri ise dosya sistemi(file)dir.

Application data kullanımında 3 çeşit depolama mekanizması vardır. Bunlar;

Local : Veri sadece mevcut cihazın üzerinde saklanır.

Roaming : Veriye kullanıcının uygulamayı kurduğu diğer cihazlardanda erişilebilir.

Temporary : Veri geçici olarak saklanır ve sistem tarafından herhangi bir zamanda silinebilir.

Uygulamamızda istersek application data bazında versiyonlama da yapabiliriz. Böylece uygulama versiyonu değiştiğinde application data'da oluşabilecek uyumluluk sorunlarının önüne geçebiliriz.

Şimdi bahsettiğimiz 3 depolama mekanizmasını kullanabileceğimizi örneklerle inceleyelim. İlk olarak Local application data ile başlayalım:

Local application data'yı uygulama açılıp kapandığında kaybolmaması gereken verileri tutmak için kullanabiliriz. Aynı zamanda boyut olarak roaming data'da tutmamıza olanak olmayan verileri de Local application data'da tutabiliriz. Çünkü local application data'da tutulacak verinin miktarında herhangi bir sınırlama bulunmamaktadır. Local application data'nın kullanımı ise aşağıdaki gibidir:

   Windows.Storage.ApplicationDataContainer setting = Windows.Storage.ApplicationData.Current.LocalSettings;
   
   setting.Values["deneme"] = "Windows 8";
   
   Object value = setting.Values["deneme"];

Local application data'da tuttuğumuz bir veriyi silmek içinse aşağıdaki kodu yazıyoruz:

setting.Values.Remove("deneme");

Dosya API'lerini kullanarak local application data store'a dosya oluşturabilir, uygulama verisini burada saklayabilir veya dosyadaki bir veriyi güncelleyebiliriz. Bunun için Windows.Storage.StorageFolder.CreateFileAsync ve Windows.Storage.FileIO.WriteTextAsync metodlarını kullanabiliriz:

        async void Write()
        {
            Windows.Storage.StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;

            StorageFile file = await folder.CreateFileAsync("myname.txt", CreationCollisionOption.ReplaceExisting);

            await FileIO.WriteTextAsync(file, "Tamer Oz");
        }

Oluşturulan dosyayı AppData klasörünün içinde görebiliriz:

Roaming application data'yı inceleyecek olursak, kullanıcının birden fazla cihazda senkron halde tutması gerekebilen veri için roaming application data kullanabilirsiniz. Kullanıcı uygulamanızı birden fazla cihaza kurmuşsa bir cihazdan diğerine aktarılması gereken verileri olabilir. Bunlar kullanıcının uygulama ayarları olabileceği gibi üzerinde çalıştığı ve başka bir cihaza kurulum yaptığında çalışmasına devam etmek istediği bir işle ilgili olan veriler olabilir. Bu gibi durumlarda veriyi roaming application data'da tutulacak şekilde kodlama yapabiliriz. Roaming data'da tutulan veri güncellendiği zaman cloud'da replike olur ve uygulamanın kurulu olduğu tüm cihazlarda senkronize edilir. Roaming application data'nın kullanımı Local Application Data ile aynıdır ancak ApplicationDataContainer tipi olarak Windows.Storage.ApplicationData.Current.RoamingSettings enum'u StorageFolder tipi olarak ise ApplicationData.Current.RoamingFolder enum'u kullanılmalıdır.

Temporary data kullanımında ise yine kullanım aynı şekildedir. TemporaryData kullanımında sadece dosya tutulabilmekte setting tutulamamaktadır. StorageFolder tipi olarak ise ApplicationData.Current.TemporaryFolder kullanılmalıdır.

Şimdi tüm bu bahsettiğimiz kodları içeren bir class'ı nasıl yazdığımızı inceleyelim.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace AppData.Common
{
    public enum Data
    {
        Data1,
        Data2,
        Data3
    }
    public enum AppDataStorage
    {
        Local,
        Roaming,
        Temporary
    }
    public enum AppDataType
    {
        Setting,
        File
    }
    public static class AppDataManager<T>
    {
        public static async void SetAppData(Data key, AppDataStorage storage, AppDataType type, T data)
        {
            Windows.Storage.ApplicationDataContainer settings = null;
            Windows.Storage.StorageFolder folder = null;

            switch (storage)
            {
                case AppDataStorage.Local:

                    switch (type)
                    {
                        case AppDataType.Setting:
                            settings = Windows.Storage.ApplicationData.Current.LocalSettings;
                            settings.Values[key.ToString()] = data;
                            break;
                        case AppDataType.File:
                            folder = ApplicationData.Current.LocalFolder;
                            StorageFile file = await folder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
                            await FileIO.WriteTextAsync(file, data.ToString());
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                    break;
                case AppDataStorage.Roaming:

                    switch (type)
                    {
                        case AppDataType.Setting:
                            settings = Windows.Storage.ApplicationData.Current.RoamingSettings;
                            settings.Values[key.ToString()] = data;
                            break;
                        case AppDataType.File:
                            folder = ApplicationData.Current.RoamingFolder;
                            StorageFile file = await folder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
                            await FileIO.WriteTextAsync(file, data.ToString());
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                    break;
                case AppDataStorage.Temporary:
                    switch (type)
                    {
                        case AppDataType.Setting:
                            throw new NotSupportedException();
                        case AppDataType.File:
                            folder = ApplicationData.Current.TemporaryFolder;
                            StorageFile file = await folder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
                            await FileIO.WriteTextAsync(file, data.ToString());
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                    break;
                default:
                    throw new NotSupportedException();
            }
        }
        public static async Task<T> GetAppData(Data key, AppDataStorage storage, AppDataType type)
        {
            Windows.Storage.ApplicationDataContainer settings = null;
            Windows.Storage.StorageFolder folder = null;

            switch (storage)
            {
                case AppDataStorage.Local:
                    switch (type)
                    {
                        case AppDataType.Setting:
                            settings = Windows.Storage.ApplicationData.Current.LocalSettings;
                            bool hasSetting = false;
                            hasSetting = settings.Values.ContainsKey(key.ToString());
                            if (hasSetting)
                            {
                                return (T)settings.Values[key.ToString()];
                            }
                            break;
                        case AppDataType.File:
                            folder = ApplicationData.Current.LocalFolder;
                            StorageFile file = await folder.GetFileAsync("dataFile.txt");
                            var x = await FileIO.ReadTextAsync(file);
                            return (T)(x as object);
                        default:
                            throw new NotSupportedException();
                    }
                    break;
                case AppDataStorage.Roaming:
                    switch (type)
                    {
                        case AppDataType.Setting:
                            settings = Windows.Storage.ApplicationData.Current.RoamingSettings;

                            bool hasSetting = false;

                            hasSetting = settings.Values.ContainsKey(key.ToString());
                            if (hasSetting)
                            {
                                return (T)settings.Values[key.ToString()];
                            }

                            break;
                        case AppDataType.File:
                            folder = ApplicationData.Current.RoamingFolder;
                            StorageFile file = await folder.GetFileAsync("dataFile.txt");
                            var x = await FileIO.ReadTextAsync(file).AsTask();
                            return (T)(x as object);

                        default:
                            throw new NotSupportedException();
                    }
                    break;
                case AppDataStorage.Temporary:
                    switch (type)
                    {
                        case AppDataType.Setting:
                            throw new NotSupportedException();
                        case AppDataType.File:
                            folder = ApplicationData.Current.TemporaryFolder;
                            StorageFile file = await folder.GetFileAsync("dataFile.txt");
                            var x = await FileIO.ReadTextAsync(file).AsTask();
                            return (T)(x as object);

                        default:
                            throw new NotSupportedException();
                    }
                default:
                    throw new NotSupportedException();
            }

            return default(T);
        }

    }

}

Uygulamamızda kullanmak istediğimiz data'lara ait isimleri Data enum'u içerisinde yazıyoruz. Ve diğer enum'ları kullanarak istediğimiz dataya ait bilgiyi appdata ya yazabiliyor veya buradan okuyabiliyoruz.

Umarım faydalı olmuştur.