Friday, September 29, 2017

UWP Tip #7 - UWP Community Toolkit - Part 5, Using the Streams Code Helper

Welcome back to the UWP Community Toolkit series. Previous Tips in the UWP Community Toolkit series:

Introduction

This tip will continue exploring the Code Helpers that we started looking at in Part 3. There are three types of helpers remaining, and today we will examine the StreamHelper class.

Purpose

The StreamHelper class contains methods to read files from a stream via local files or via a network stream. There is also a helper method to read data from an http source and write it directly to a local file. There are also some helper methods to check if files and folders exist for a given name and path.

Let's look at a few of the method signatures:

  • GetHttpStreamAsync(System.Uri uri) - Gets a stream from an HTTP request.
  • IsLocalFileExistsAsync(System.String fileName) - Checks if a local files exists in the application's folder.
  • IsLocalCacheFileExistsAsync(System.String fileName) - Checks if a local file exists in the cache folder.
  • ReadTextAsync(Windows.Storage.Streams.IRandomAccessStream stream,System.Text.Encoding encoding) - Takes a stream and reads it to a returned string.

Example

In this short example, we are going to create a StreamService for our project that implements an IStreamService interface for testability. Although the lack of an interface for the toolkit's StreamHelper makes it a little tricky to mock this for our tests. We'll leave this for another day or perhaps an issue to be filed on their GitHub.

The StreamService has two methods, one for getting a string back from and HTTP call and another to get one from reading a file in the local cache.

public class StreamService : IStreamService
{
    public async Task<string> GetStringFromUrlAsync(Uri source)
    {
        using (var stream = await StreamHelper.GetHttpStreamAsync(source))
        {
            return await stream.ReadTextAsync();
        }
    }
     public async Task<string> GetStringFromLocalCacheAsync(string fileName)
    {
        using (var stream = await StreamHelper.GetLocalCacheFileStreamAsync(fileName, Windows.Storage.FileAccessMode.Read))
        {
            return await stream.ReadTextAsync();
         }
    }
}

Everything is wrapped up with only strings and a Uri in and out, keeping the external dependency out of our ViewModels. To check out all of the available helper methods in the StreamHelper class, you can visit the API documentation here.

Wrap-Up

Only two helper types to go. Next time we will continue with the VisualTreeExtensions code helper in the UWP Community Toolkit.

Happy coding!

 

del.icio.us Tags: ,

Tuesday, September 26, 2017

UWP App Tips Recommended Video - Bringing Your WinForms/WPF Investments Forwards with UWP/.NET Standard 2.0

The UWP Community Toolkit tips series will continue later this week. Today's post is a video that I recommend to all Windows developers.

Last week, Microsoft's Channel 9 hosted the online virtual 3-day conference, .NET Conf. The conference covered topics ranging from ASP.NET Core to Xamarin to Visual Studio tooling and lots more. I recommend you go check out all of the sessions to see what interests you. Last I checked, there were 45 videos available for the conference.

The one video I wanted to call out for UWP and all other Windows developers is titled Bringing Your WinForms/WPF Investments Forwards with UWP/.NET Standard 2.0. This session was presented by Chris Barker and Daniel Jacobson is described as:

.NET Standard 2.0 with Visual Studio 2017 makes it even easier to bring your WinForms/WPF investments to the Universal Windows Platform - enabling you to reach new audiences and easily deliver a modern user experience, all whilst continuing to service your existing user base. This session will introduce you to the benefits of .NET Standard 2.0, and walk you through the process for extending the reach of your app efficiently.
The hosts are very engaging and I think this session is yet another indicator that Microsoft is standing firm on their position that UWP is the way forward for all Windows app development.While large legacy code bases on WinForms and WPF may not ever migrate to UWP. I work for a company with a mix of WPF, WinForms and MFC which is unlikely to take this path. However, it is a real possibility for many WPF and some WinForms applications, especially those which are smaller non-enterprise applications.

Enjoy the video and don't forget to peruse the rest of them on Channel 9!


Friday, September 22, 2017

UWP Tip #6 - UWP Community Toolkit - Part 4, Leveraging the StorageFiles and Storage Code Helpers

Welcome back to the UWP Community Toolkit series. You'll have to excuse the delay between posts as TechBash 2017 has been monopolizing my free time this month.

Previous Tips in the UWP Community Toolkit series:

Introduction

This tip will continue exploring the Code Helpers that we started looking at in Part 3. There are five types of helpers remaining, and today we'll look at the StorageFileHelper and Storage helpers.

StorageFiles

The StorageFileHelper utility class has helper methods for reading from and writing to disk. There are method overloads to read and write both text and binary data to a file either directly to the local storage folder or to given folderId and/or folderName. Some overloads for writing take a CreationCollisionOptions parameter to decide how to handle conflicts during file or folder creation. All StorageFile operations are async.

Here is a simple example of simple read and write service methods that wrap calls to the StorageFileHelper methods that use the user's local storage.

 public async Task WriteUserData(string data, string fileName)
{
    await StorageFileHelper.WriteTextToLocalFileAsync(data, fileName);
}

public async Task<string> ReadUserData(string fileName)
{
    return await StorageFileHelper.ReadTextFromLocalFileAsync(fileName);
}

Storage

The StorageService, not to be confused with the previous StorageFileHelper, is for reading and writing objects within your application. The objects can be read and written locally or you can choose to roam the data across all the user's devices. This selection is made by using either a LocalObjectStorageHelper or a RoamingObjectStorageHelper. Makes sense.

Let's say you had a health care application of some kind and you wanted to save an object containing the currently selected clinic's information.

 public class Clinic : IClinic
{
    public string Name { get; set; }
    public string Location { get; set; }
    public int NumberOfBeds { get; set; }
    public ClinicType Type { get; set; }
}

We want to take this and persist it for the current device. So, we'll create some service methods to read and write the object local to the current device.

    public class StorageService
    {
        private LocalObjectStorageHelper _localStorageHelper = new LocalObjectStorageHelper();

        public async Task SaveClinic(IClinic clinic, string key)
        {
            await _localStorageHelper.SaveFileAsync(key, clinic);
        }

        public async Task<IClinic> ReadClinic(string key)
        {
            return await _localStorageHelper.ReadFileAsync<IClinic>(key);
        }
    }

That's it. We've wrapped the methods to read and write and only need to deal with our own interfaces in and out. If you wrap this service class in an interface and inject the helper itself, it will be nicely abstracted for testability. You can use these service methods from any of the existing ViewModels in your UWP app.

Wrap-Up

Next time we will continue with the Code Helpers in the UWP Community Toolkit. The Streams helper is up next.

Happy coding!