Xamarin Forms and HTTP

By July 9, 2014Xamarin

Let’s say we’re building an application, and we want to list the titles and publication NuGet HTTP Librarydates from an RSS feed.  

We can do this using a ListView, but we have to get the feed, and to do that we need a library; specifically the NuGet package Microsoft.Http.Client Libraries.  

[Click on the image to see it full size]
This is part of the on-going series of posts on Learning Xamarin; a complete index to the series can be found here.

To create our application we’ll start with a new Forms application by firing up Xamarin Studio and selecting New Solution ->  C# -> Mobile Apps -> Blank App (Xamarin.Forms.Portable

Let’s add structure to the app by adding these folders:

Models
Services
View Models
Views

Creating the Model

Our Model is very simple, just one class: BlogEntry,

public class BlogEntry
{
    public string Title { get; set; }
 
    public string Link { get; set; }
 
    public string Description { get; set; }
 
    public string PubDate { get; set; }
}

Of these properties, for now we’ll only be concerned with Title and PubDate.

Creating the View Model

The View Model (VM) will mediate between the model and the view. Again, ours is very simple.  Create a file named BlogsViewModel,

public class BlogsViewModel
{
    public ObservableCollection<BlogEntry> Blogs { get; set; }
}

Creating the View

Right-click on the Views folder and choose Add->New File -> Forms -> Forms Content Page XAML.   Name the new page BlogsPage

In the Xaml we’ll add a ListView and modify the Cel to display both the Title and the PubDate,

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Falafel2GoV2.BlogsPage">
    <ContentPage.Content>
        <StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
            <ListView x:Name="list" ItemsSource="{Binding Blogs}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
<!--                                    <Label Text="{Binding Link}" />-->
 
                                        <Label Text="{Binding Title}" Font="12" />
                                        <Label Text="{Binding PubDate}" Font="10" />
 
                                </StackLayout>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

The list itself binds to Blogs; the collection declared in the View Model.  We’ll make the connection to the VM as the binding context in the code behind.  Similarly, the two Labels bind their Text properties to properties on each BlogEntry object in the list.

Services

The code behind for the view depends on our Services files. There are two files. The first, Urls.cs is pretty simple,

public static class Urls
{
    public enum UrlType
    {
        Blogs,
        Tweets,
        Website,
        Videos}
 
    ;
 
    public static string GetUrl (UrlType urlToRetrieve)
    {
        switch (urlToRetrieve) {
        case UrlType.Blogs:
            return "http://blog.falafel.com/Feeds/all-blogs";
        default:
            return "";
        }
    }
}

For now, the only URL we care about is the RSS feed for the Falafel blogs.  Later we can add other URLs for other types of data, as hinted at by the enum.

The second, and more important class, is the DataLoader class,

public class DataLoader
{
    public async Task<List<BlogEntry>> GetRecentBlogs ()
    {
        using (var httpClient = new HttpClient ()) {
            Stream data =
                await httpClient.GetStreamAsync (
                    Urls.GetUrl (Urls.UrlType.Blogs));
            List<BlogEntry> blogs = await Task.Run (() =>
                GetBlogList (data));
            return blogs;
        }
    }
 
    private List<BlogEntry> GetBlogList (Stream blogRSSData)
    {
        IEnumerable<XElement> items = XElement.Load (
            blogRSSData).Descendants ("item");
 
        var blogList = (from blog in items
                        select new BlogEntry () {
            Link = blog.Element ("link").Value,
            Title = blog.Element ("title").Value,
            Description = blog.Element ("description").Value,
            PubDate = blog.Element ("pubDate").Value
        }).ToList<BlogEntry> ();
 
        return blogList;
    }
}

You can see that this consists of a key public method, GetRecentBlogs and a helper method, GetBlogList.  The first uses the HttpClient library referred to earlier. To add this to your project, right click on the project and select Add -> Add Packages and search for Microsoft.Http.Client.  Check the Microsoft.Http.Client libraries and click Add Package.  Hey! Presto! It is added to your project, along with the appropriate references.

Notice that this runs asynchronously.  We’ll want to remember that in a moment when we return to the view to add the call to this method.

Back in BlogPage.xaml.cs you’ll create a constructor and a private method GetBlogs.  The constructor calls GetBlogs and GetBlogs calls the loader asynchronously.  

public partial class BlogsPage : ContentPage
{
    private BlogsViewModel vm;
 
    public BlogsPage ()
    {
        InitializeComponent ();
        vm = new BlogsViewModel ();
        GetBlogs ();
    }
 
    private async void GetBlogs ()
    {
        var loader = new DataLoader ();
 
        List<BlogEntry> recentBlogs = await loader.GetRecentBlogs ();
        vm.Blogs = new System.Collections.ObjectModel.ObservableCollection<BlogEntry> (recentBlogs);
        this.BindingContext = vm;
    }
}

That’s it, your page will come up and a few moments later it will populate with the titles and the publication date.

Source Code

There are a few essential things to take care of, such as showing an indeterminate progress indicator while loading the data and adding links to the blog titles, but we’ll leave those for another day.


falafelcon
  I’ll be speaking on Xamarin at FalafelCon! 
  More information here.

The following two tabs change content below.