Add Cloud Storage to Xamarin Apps with Azure Blob Storage

Brandon Minnick

Cloud Storage has become a must-have feature for mobile apps. It gives developers the ability to store large files in the cloud and securely distribute them to all mobile app users. Moving these large files to the cloud also helps reduce the size of the APKs and IPAs significantly. Azure Blob Storage makes it extremely easy for Xamarin developers to implement Cloud Storage code in your cross-platform apps, allowing us to share 100% code across iOS, Android, and Windows.

What is Azure Blob Storage?

Azure Blob Storage is basically a giant folder in the Cloud. Just like a folder in the cloud, we can add anything inside that we need such as PDFs, photos, Word documents, etc. Each of these files are assigned a unique URL to access the folder, along with the added benefits of cloud storage, like GeoReplication and User Authentication.

In this post, you’ll learn how to create an Azure Storage Resource and retrieve the images stored in the cloud using the Azure Storage .NET Client libraries from a Xamarin.Forms project.

The Xamarin Show

In this episode of The Xamarin Show, James and I explore how to use Azure Blob Storage in your Xamarin apps!

Getting Started with Cloud Storage

Before writing the code for our Xamarin app, let’s first use the Azure Portal to create an Azure Storage account for Blob Storage, then upload an image.

Free Azure Credits

If you are new to Azure, click here to get a free $200 credit!

Create New Azure Storage Resource

1. In the Azure Portal, create a new Storage Account.
Create Azure Blob Storage Container

Create New Blob Container

Now, let’s navigate to the newly created Azure Storage resource and upload some photos!
2. In the Azure Notification Menu (the bell icon at the top of the Azure Portal), select Go to Resource.
Navigate to Azure Blob Storage Resource
3. Click on Browse Blobs.
Click On Browse Blobs
4. Click on + Container.
  • Note: A container is like a folder in the cloud. In it, we will store Blobs which is just another name for a file
5. Name the new container “photos”.
6. Set the Public access level to Blob.
  • Note: For this example, we are creating a public blob storage container. For future projects that you do not want to be publicly accessible, set the Public access level to Private
7. Click Ok.
 Click On Add New Container
8. Click on the newly created container, “photos”.
Select Photos Container
9. Select Upload.
10. Select an image to upload from your computer.
11. Select Upload.
Select Upload Images
12. On the Azure Storage menu, select Access Keys.
13. Copy the Connection string for Key1. (We’ll need this for our Xamarin app!)
Copy Connection String
Our Azure Storage resource is complete. Let’s start working on our app!

Create a Simple Xamarin.Forms App

Let’s make a simple Xamarin.Forms app that uses our image from Azure Blob Storage. It will be a single-page app that communicates directly with our Azure Blob Storage Container using the Azure Storage SDK for .NET. The completed Simple Xamarin.Forms app can be found on my GitHub repo.

 

Add the following code to a Xamarin.Forms project, making sure to replace "Your Connection String" with the Connection String created in Step 13.
Simple Xamarin Forms App Using Azure Blob Storage

App.cs

App.cs  is the starting point for every Xamarin.Forms app! In App.cs, we will set the MainPage to be our ImagePage  which will be wrapped in a NavigationPage  to provide a title bar.
public class App : Application
{
    publicApp()
    {
        MainPage = new NavigationPage(new ImagePage());
    }
}

ImagePage.cs

This file will display our image. In its OnAppearing  method, which runs every time the page appears in our app, we include the logic to retrieve the image from Azure Blob Storage.
public class ImagePage : ContentPage
{
    readonly Label _title = new Label{ HorizontalTextAlignment = TextAlignment.Center };
    readonly Image _image = new Image();
    readonly ActivityIndicator _activityIndicator = new ActivityIndicator();

    public ImagePage()
    {
        Content = new StackLayout
        {
            Spacing = 15,
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            Children = {
                _title,
                _image,
                _activityIndicator
            }
        };

        Title = "Image Page";
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();

        _activityIndicator.IsRunning = true;

        var blobList = await BlobStorageService.GetBlobs<CloudBlockBlob>("photos");

        var firstBlob = blobList?.FirstOrDefault();
        var photo =  new PhotoModel { Title = firstBlob?.Name, Uri = firstBlob?.Uri };

        _title.Text = photo?.Title;
        _image.Source = ImageSource.FromUri(photo?.Uri);

        _activityIndicator.IsRunning = false;
        _activityIndicator.IsVisible = false;
    }
}

 BlobStorageService.cs 

This is a generic static class that can be used in any project. It contains two public methods: GetBlobs  and SaveBlockBlob which can be called from anywhere in our app to retrieve and upload blobs from/to Blob Storage accordingly.
readonly static CloudStorageAccount _cloudStorageAccount = CloudStorageAccount.Parse("Your Connection String");
readonly static CloudBlobClient _blobClient = _cloudStorageAccount.CreateCloudBlobClient();

public static async Task<List<T>> GetBlobs<T>(string containerName, string prefix = "", int? maxresultsPerQuery = null, BlobListingDetails blobListingDetails = BlobListingDetails.None) where T : ICloudBlob
{
    var blobContainer = _blobClient.GetContainerReference(containerName);

    var blobList = new List<T>();
    BlobContinuationToken continuationToken = null;

    try
    {
        do
        {
            var response = await blobContainer.ListBlobsSegmentedAsync(prefix, true, blobListingDetails, maxresultsPerQuery, continuationToken, null, null);

            continuationToken = response?.ContinuationToken;

            foreach (var blob in response?.Results?.OfType<T>())
            {
                blobList.Add(blob);
            }

        } while (continuationToken != null);
    }
    catch (Exception e)
    {
        //Handle Exception
    }

    return blobList;
}

public static async Task<CloudBlockBlob> SaveBlockBlob(string containerName, byte[] blob, string blobTitle)
{
    var blobContainer = _blobClient.GetContainerReference(containerName);

    var blockBlob = blobContainer.GetBlockBlobReference(blobTitle);
    await blockBlob.UploadFromByteArrayAsync(blob, 0, blob.Length);

    return blockBlob;
}

PhotoModel.cs

PhotoModel  is the model class for our photo metadata. It is used to store the photo’s Uri and Title.
public class PhotoModel
{
    public System.Uri Uri { get; set; }
    public string Title { get; set; }
}
That’s it! Now launch the app and enjoy!

Going Serverless with Azure Functions + Azure Storage

Azure Functions are a great compliment to Azure Blob Storage because they allow us to offload any metadata processing from the Xamarin app to the cloud, and they can help ensure our metadata doesn’t get corrupted. You can download an advanced example that incorporates Azure Functions from my GitHub repo.
Azure Blob Storage Sample App Diagram
This Xamarin app uses a SQLite Database to store the metadata of the Photos (e.g. Url, Title) locally on our Xamarin device. The local database syncs, via an Azure Function, with an Azure SQL Database that contains the metadata of the Photos stored in Azure Blob Storage. It also allows the user to take photos and save them to Azure Blob Storage. To do this, the Xamarin app uploads the image to an Azure Function, and the Azure Function saves the image in Azure Blob Storage, then adds the image metadata to the Azure SQL Database.

Learn More

Dive deeper into these topics and more on the Microsoft Docs:

About The Author

Brandon Minnick is a Xamarin + Azure Developer Advocate at Microsoft. As a Developer Advocate, Brandon loves helping developers build cloud-connected mobile apps! Brandon loves talking about mobile and invites you to start up a conversation @BrandonXamarin!

 

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Steven White 0

    Isn’t this method inherently insecure? Anyone who reverse engineers your code will have your connection string and full access to your storage.

Feedback usabilla icon