Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / UWP

UWP Storage Wrapper

4.33/5 (2 votes)
25 Dec 2018CPOL2 min read 8K   75  
UWP Storage Wrapper

Introduction

UWP Storage is a persistent name-value storage API for UWP apps. This article showcases a wrapper written in C++/CX that makes it easier to use in C++/CX. Though C# usage is already easy without the wrapper, the comparison of both with and without wrapper are still shown.

C++/CX Writing and Reading Primitive Value

In this C++/CX example, the code shows how to use UWP storage directly to store and read integer.

C++
Windows::Storage::ApplicationDataContainer^ localSettings =
    Windows::Storage::ApplicationData::Current->LocalSettings;

localSettings->Values->Insert("RawKey", 123);
bool exists = localSettings->Values->HasKey("RawKey");
if (exists)
{
    Platform::Object^ obj = localSettings->Values->Lookup("RawKey");
    int result = safe_cast<int>(obj);
}
localSettings->Values->Clear();

In this second C++/CX example, the code shows how to use UWP storage with the wrapper to store and read integer. The code is more concise. The second parameter of GetInt32 indicates if the name exists in the storage. If not, the third parameter will be returned as the default preferred value.

C++
UWPStorage^ storage = ref new UWPStorage(StorageType::Local);
storage->SetInt32("WrapperKey", 456);
bool exists = false;
int result = storage->GetInt32("WrapperKey", &exists, 444);
storage->Clear();

C# Writing and Reading Primitive Value

This C# example shows how to use UWP storage directly to store and read integer.

C#
Windows.Storage.ApplicationDataContainer localSettings =
    Windows.Storage.ApplicationData.Current.LocalSettings;

localSettings.Values["RawKey"] = 123;
int result = (int)(localSettings.Values["RawKey"]);
localSettings.Values.Clear();

This C# example shows how to use UWP storage directly to store and read integer. Similarly, The out parameter of GetInt32 indicates whether the name exists, else the third parameter will be returned. The code is not more concise. So there is no advantage to using the wrapper in C# except the wrapper can catch the exception for you when the casting to primitive type fails, instead you manually try-catching it.

C#
UWPStorage storage = new UWPStorage(StorageType.Local);
storage.SetInt32("WrapperKey", 456);
bool exists = false;
int result = storage.GetInt32("WrapperKey", out exists, 444);
storage.Clear();

C++/CX Writing and Reading Primitive Composite

Composite is a group of name-value settings. The C++/CX code to directly store and read a composite with 2 name-values. One is integer while other is string. Later the composite is deleted.

C++
Windows::Storage::ApplicationDataContainer^ localSettings =
    Windows::Storage::ApplicationData::Current->LocalSettings;

// Create a composite setting
ApplicationDataCompositeValue^ composite = 
    ref new ApplicationDataCompositeValue();
composite->Insert("intVal", dynamic_cast<PropertyValue^>
    (PropertyValue::CreateInt32(1212)));
composite->Insert("strVal", dynamic_cast<PropertyValue^>
    (PropertyValue::CreateString("string")));

auto values = localSettings->Values;
values->Insert("RawCompositeSetting", composite);

// Read data from a composite setting
ApplicationDataCompositeValue^ composite2 = 
    safe_cast<ApplicationDataCompositeValue^>
    (localSettings->Values->Lookup("RawCompositeSetting"));

if (composite2)
{
    // Access data in composite2["intVal"] and composite2["strVal"]
    int one = safe_cast<IPropertyValue^>
        (composite2->Lookup("intVal"))->GetInt32();
    String^ hello = safe_cast<String^>
        (composite2->Lookup("strVal"));
}
// Delete a composite setting
values->Remove("RawCompositeSetting");

The equivalent C++/CX code using UWP storage wrapper to store and read a composite with 2 name-values. One is integer while other is string. As you can see, the code is less verbose and saves many typings.

C++
UWPStorage^ storage = ref new UWPStorage(StorageType::Local);
// Create a composite setting
CompositeValue^ composite = ref new CompositeValue();
composite->SetInt32("intVal", 3434);
composite->SetString("strVal", "string");

storage->SetComposite("WrapperCompositeSetting", composite);

// Read data from a composite setting
bool exists = false;
CompositeValue^ composite2 = storage->GetComposite
    ("WrapperCompositeSetting", &exists);
if (exists)
{
    // Access data in composite2["intVal"] and composite2["strVal"]
    int one = composite2->GetInt32("intVal", &exists, 4444);
    String^ hello = composite2->GetString("strVal", &exists, "error");
}
// Delete a composite setting
storage->Remove("WrapperCompositeSetting");

C# Writing and Reading Primitive Composite

The C# code to directly store and read a composite with 2 name-values. One is integer while other is string. Later, the composite is deleted.

C#
Windows.Storage.ApplicationDataContainer localSettings = 
    Windows.Storage.ApplicationData.Current.LocalSettings;

// Create a composite setting
Windows.Storage.ApplicationDataCompositeValue composite = 
    new Windows.Storage.ApplicationDataCompositeValue();
composite["intVal"] = 1212;
composite["strVal"] = "string";

localSettings.Values["RawCompositeSetting"] = composite;

// Read data from a composite setting
Windows.Storage.ApplicationDataCompositeValue composite2 =
    (Windows.Storage.ApplicationDataCompositeValue)
    localSettings.Values["RawCompositeSetting"];

if (composite2!=null)
{
    // Access data in composite2["intVal"] and composite2["strVal"]
    int one = (int)(composite2["intVal"]);
    string hello = composite2["strVal"].ToString();
}

// Delete a composite setting
localSettings.Values.Remove("RawCompositeSetting");

The equivalent C# code relying on wrapper to store and read a composite with 2 name-values. One is integer while other is string. The code is equally concise.

C#
UWPStorage storage = new UWPStorage(StorageType.Local);
// Create a composite setting
CompositeValue composite = new CompositeValue();
composite.SetInt32("intVal", 3434);
composite.SetString("strVal", "string");

storage.SetComposite("WrapperCompositeSetting", composite);

// Read data from a composite setting
bool exists = false;
CompositeValue composite2 = storage.GetComposite
    ("WrapperCompositeSetting", out exists);
if (exists)
{
    // Access data in composite2["intVal"] and composite2["strVal"]
    int one = composite2.GetInt32("intVal", out exists, 4444);
    string hello = composite2.GetString("strVal", out exists, "error");
}
// Delete a composite setting
storage.Remove("WrapperCompositeSetting");

With this library, it is now possible to write a portable C++ storage class with the same interface that not only works on UWP but other OS like Linux and MacOSX, cutting the amount of work to port your UWP app to other platforms, if the need arises.

The code is hosted at Github.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)