Presentation at Microsoft Modern Jago

13 February 2013

Yesterday I was lucky enough to be invited to do a short presentation to the London Windows Store App Developer Group at Microsoft's Modern Jago studios in East London (thanks to @mtaulty for the image).

The first part of the evening was devoted to a really excellent presentation by Microsoft's Mike Taulty (@mtaulty) on using Windows Azure Mobile Services with Windows 8 apps. I've seen Mike speak a couple of times before, and he really knows his stuff on WinRT development! I think everybody at the meeting was engaged and impressed with the content of the presentation and the practical demos. I certainly learnt a lot, including Mike's use of the http PATCH verb with RESTful services!

The presentation I gave centred around my experiences with developing apps for the Windows Store, something I've documented in this post. In particular, I went into some of the implementation challenges I faced when working with files in the Documents library (i.e. not being able directly read/write files without first having the user grant permission through the use of the FolderPicker mechanism).

Mike Taulty mentioned that it was possible to save the access permissions granted through using the FolderPicker for subsequent sessions. This extremely useful facility was something I hadn't been aware of, so I decided to investigate further...

Saving Folder Access Permissions to Survive App Restarts

After a bit of searching, I found the Windows.Storage.AccessCache.StorageApplicationPermissions class, which essentially helps you maintain a MRU (most-recently used) list and a list of access permissions (for both files and folders) for an app. Here's how you can acquire an access permission token (a GUID, in string format) from the FutureAccessList property:

:
// Future access token property
public string DocumentsLibraryAccessToken { get; set; }
:
:
private async void SelectFolder(object sender, TappedRoutedEventArgs e)
{
    // Get the user to select the Documents library folder (or a sub-folder),
    // thereby granting you access permissions...
    var picker = new FolderPicker();
    picker.FileTypeFilter.Add("*");
    var folder = await picker.PickSingleFolderAsync();
    if (folder == null) return;

    // Get the future access token by adding the StorageFolder object to the FutureAccessList, 
    // then save the token for future use (it can be re-used after quitting and re-starting app)
    DocumentsLibraryAccessToken = StorageApplicationPermissions.FutureAccessList.Add(folder);

    // Save the token in the app's roaming settings
    ApplicationData.Current.RoamingSettings.Values["DocumentsLibraryAccessToken"] = DocumentsLibraryAccessToken;
}

You can restore the token (e.g. in the app's main Page) from roaming settings like this:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("DocumentsLibraryAccessToken"))
        DocumentsLibraryAccessToken = (string)ApplicationData.Current.RoamingSettings.Values["DocumentsLibraryAccessToken"];
}

Then, when we want to access the Documents library, we re-acquire a StorageFolder object with the necessary permissions by calling the FutureAccessList.GetFolderAsync method, and passing our token:

private async void WriteToDocLib(object sender, TappedRoutedEventArgs e)
{
    try
    {
        // Get the previously allocated DocumentsLibraryAccessToken
        if (string.IsNullOrEmpty(DocumentsLibraryAccessToken)) SelectFolder(this, null);

        // Get a StorageFolder object using the DocumentsLibraryAccessToken
        var folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(DocumentsLibraryAccessToken);

        // Check we still have access
        var accessAllowed = StorageApplicationPermissions.FutureAccessList.CheckAccess(folder);
        if (!accessAllowed) SelectFolder(this, null);

        // Write a file
        var file = await folder.CreateFileAsync(DateTime.Now.Ticks.ToString() + ".txt");
        FileIO.WriteTextAsync(file, "Testing...");

        // Now access a sub-folder in the Documents lib and write a file...
        var subfolder = await folder.GetFolderAsync("MySubFolder");
        var file2 = await subfolder.CreateFileAsync(DateTime.Now.Ticks.ToString() + ".txt");
        FileIO.WriteTextAsync(file2, "Testing2...");
    }
    catch
    {
    }
}

This is an incredibly useful feature - I wish I'd known about it a few months back! Many thanks to Microsoft's Mike Taulty for putting me on the right track!