# How to Use Realm Effectively in a Xamarin.Forms App

Taking care of persistence while developing a mobile application is fundamental nowadays. Even though mobile connection bandwidth, as well as coverage, has been steadily increasing over time, applications still are expected to work offline and in a limited connectivity environment.

This becomes even more cumbersome when working on applications that require a steady stream of data with the service in order to work effectively, such as collaborative applications.

Caching data coming from a service is difficult, but Realm can ease the burden by providing a very natural way of storing and accessing data. This in turn will make the application more responsive and allow the end user to work seamlessly regardless of the connection status.

The aim of this article is to show how to use Realm effectively, particularly in a Xamarin.Forms app. We will take a look at **SharedGroceries**, an app to share grocery lists with friends and family, backed by a REST API. With this application, we wanted to provide an example that would be simple but also somehow complete, in order to cover different common use cases. The code for the application can be found in the repository here. 

Before proceeding, please note that this is not an introductory article to Realm or Xamarin.Forms, so we expect you to have some familiarity with both. If you want to get an introduction to Realm, you can take a look at the documentation for the Realm .NET SDK. The official documentation for Xamarin.Forms and MVVM are valuable resources to learn about these topics.

> **Build better mobile apps with Atlas Device Sync**: Atlas Device Sync is a fully-managed mobile backend-as-a-service. Leverage out-of-the-box infrastructure, data synchronization capabilities, built-in network handling, and much more to quickly launch enterprise-grade mobile apps. Get started now by build: Deploy Sample for Free!

## The architecture

In this section, we are going to discuss the difference between the architecture of an application backed by a classic SQL database and the architecture of an application that uses Realm.

### Classic architecture

In an app backed by a classic SQL database, the structure of the application will be similar to the one shown in the diagram, where the arrows represent the dependency between different components of the application. The view model requests data from a repository that can retrieve it both from a remote data source (like a web service) when online and from a local database, depending on the situation. The repository also takes care of keeping the local database up to date with all the data retrieved from the web service.
This approach presents some issues:

* *Combining data coming from both the remote data source and the local one is difficult.* For example, when opening a view in an application for the first time, it's quite common to show locally cached data while the data coming from a web service is being fetched. In this case, it's not easy to synchronize the retrieval, as well as merge the data coming from both sources to present in the view.
* *The data coming from the local source is static.* The objects that are retrieved from the database are generally POCOs (plain old class object) and as such, they do not reflect the current state of the data present in the cache. For example, in order to keep the data shown to the user as fresh as possible, there could be a synchronization process in the background that is continuously retrieving data from the web service and inserting it into the database. It's quite complex to make this data available to the final user of the application, though, as with a classic SQL database we can get fresh data only with a new query, and this needs to be done manually, further increasing the need to coordinate different components of the application.
* *Pagination is hard.* Objects are fully loaded from the database upon retrieval, and this can cause performance issues when working with big datasets. In this case, pagination could be required to keep the application performant, but this is not easy to implement.

### Realm architecture

When working with Realm, instead, the structure of the application should be similar to the one in the diagram above.

In this approach, the realm is directly accessed from the view model, and not hidden behind a repository like before. When information is retrieved from the web service, it is inserted into the database, and the view model can update the UI thanks to notifications coming from the realm. In our architecture, we have decided to call *DataService* the entity responsible for the flow of the data in the application.

There are several advantages to this approach:

* *Single source of truth removes conflicts.* Because data is coming only from the realm, then there are no issues with merging and synchronizing data coming from multiple data sources on the UI. For example, when opening a view in an application for the first time, data coming from the realm is shown straight away. In the meantime, data from the web service is retrieved and inserted into the realm. This will trigger a notification in the view model that will update the UI accordingly.
* *Objects and collections are live*. This means that the data coming from the realm is always the latest available locally. There is no need to query again the database to get the latest version of the data as with an SQL database.
* *Objects and collections are lazily loaded.* This means that there is no need to worry about pagination, even when working with huge datasets.
* *Bindings.* Realm works out of the box with data bindings in Xamarin.Forms, greatly simplifying the use of the MVVM pattern.

As you can see in the diagram, the line between the view model and the DataService is dashed, to indicate that is optional. Due to the fact that the view model is showing only data coming from the realm, it does not actually need to have a dependency on the DataService, and the retrieval of data coming from the web service can happen independently. For example, the DataService could continuously request data to the web service to keep the data fresh, regardless of what is being shown to the user at a specific time. This continuous request approach can also be used a SQL database solution, but that would require additional synchronization and queries, as the data coming from the database is static. Sometimes, though, data needs to be exchanged with the web service in consequence of specific actions from the user—for example with pull-to-refresh—and in this case, the view model needs to depend on the DataService.

## SharedGroceries app

In this section, we are going to introduce our example application and how to run it.

SharedGroceries is a simple collaborative app that allows you to share grocery lists with friends and family, backed by a REST API. We have decided to use REST as it is quite a common choice and allowed us to create a service easily. We are not going to focus too much on the REST API service, as it is outside of the scope of this article.

Let's take a look at the application now. The screenshots here are taken from the iOS version of the application only, for simplicity:

* (a) The first page of the application is the login page, where the user can input their username and password to login.
* (b) After login, the user is presented with the shopping lists they are currently sharing. Additionally, the user can add a new list here.
* (c) When clicking on a row, it goes to the shopping list page that shows the content of such list. From here, the user can add and remove items, rename them, and check/uncheck them when they have been bought.

To run the app, you first need to run the web service with the REST API. In order to do so, open the `SharedGroceriesWebService` project, and run it. This should start the web service on `http://localhost:5000` by default. After that, you can simply run the `SharedGroceries` project that contains the code for the Xamarin.Forms application. The app is already configured to connect to the web service at the default address.

For simplicity, we do not cover the case of registering users, and they are all created already on the web service. In particular, there are three predefined users—`alice`, `bob`, and `charlie`, all with password set to `1234`—that can be used to access the app. A couple of shopping lists are also already created in the service to make it easier to test the application.

## Realm in practice

In this section, we are going to go into detail about the structure of the app and how to use Realm effectively. The structure follows the architecture that was described in the architecture section.

### Rest API

If we start from the lower part of the architecture schema, we have the `RestAPI` namespace that contains the code responsible for the communication with the web service. In particular, the `RestAPIClient` is making HTTP requests to the `SharedGroceriesWebService`. The data is exchanged in the form of DTOs (Data Transfer Objects), simple objects used for the serialization and deserialization of data over the network. In this simple app, we could avoid using DTOs, and direcly use our Realm model objects, but it's always a good idea to use specific objects just for the data transfer, as this allows us to have independence between the local persistence model and the service model. With this separation, we don't necessarily need to change our local model in case the service model changes.

Here you have the example of one of the DTOs in the app:

``` csharp
public class UserInfoDTO
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public UserInfo ToModel()
    {
        return new UserInfo
        {
            Id = Id,
            Name = Name,
        };
    }

    public static UserInfoDTO FromModel(UserInfo user)
    {
        return new UserInfoDTO
        {
            Id = user.Id,
            Name = user.Name,
        };
    }
}
```

`UserInfoDTO` is just a container used for the serialization/deserialization of data transmitted in the API calls, and contains methods for converting to and from the local model (in this case, the `UserInfo` class).

### RealmService

`RealmService` is responsible for providing a reference to a realm:

``` csharp
public static class RealmService
{
    public static Realm GetRealm() => Realm.GetInstance();
}
```

The class is quite simple at the moment, as we are using the default configuration for the realm. Having a separate class becomes more useful, though, when we have a more complicated configuration for the realm, and we want avoid having code duplication.

Please note that the `GetRealm` method is creating a new realm instance when it is called. Because realm instances need to be used on the same thread where they have been created, this method can be used from everywhere in our code, without the need to worry about threading issues.
It's also important to dispose of realm instances when they are not needed anymore, especially on background threads.

### DataService

The `DataService` class is responsible for managing the flow of data in the application. When needed, the class requests data from the `RestAPIClient`, and then persists it in the realm. A typical method in this class would look like this:

``` csharp
public static async Task RetrieveUsers()
{
    try
    {
        //Retrieve data from the API
        var users = await RestAPIClient.GetAllUsers();

        //Persist data in Realm
        using var realm = RealmService.GetRealm();
        realm.Write(() =>
        {
            realm.Add(users.Select(u => u.ToModel()), update: true);
        });
    }
    catch (HttpRequestException) //Offline/Service is not reachable
    {
    }
}
```

The `RetrieveUsers` method is first retrieving the list of users (in the form of DTOs) from the Rest API, and then inserting them into the realm, after a conversion from DTOs to model objects. Here you can see the use of the `using` declaration to dispose of the realm at the end of the try block.

### Realm models

The definition of the model for Realm is generally straightforward, as it is possible to use a simple C# class as a model with very little modifications. In the following snippet, you can see the three model classes that we are using in SharedGroceries:

``` csharp
public class UserInfo : RealmObject
{
    [PrimaryKey]
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class GroceryItem : EmbeddedObject
{
    public string Name { get; set; }
    public bool Purchased { get; set; }
}

public class ShoppingList : RealmObject
{
    [PrimaryKey]
    public Guid Id { get; set; } = Guid.NewGuid();
    public string Name { get; set; }
    public ISet Owners { get; }
    public IList Items { get; }
}
```

The models are pretty simple, and strictly resemble the DTO objects that are retrieved from the web service. One of the few caveats when writing Realm model classes is to remember that collections (lists, sets, and dictionaries) need to be declared with a getter only property and the correspondent interface type (`IList`, `ISet`, `IDictionary`), as it is happening with `ShoppingList`.

Another thing to notice here is that `GroceryItem` is defined as an `EmbeddedObject`, to indicate that it cannot exist as an independent Realm object (and thus it cannot have a `PrimaryKey`), and has the same lifecycle of the `ShoppingList` that contains it. This implies that `GroceryItem`s get deleted when the parent `ShoppingList` is deleted.

### View models

We will now go through the two main view models in the app, and discuss the most important points. We are going to skip `LoginViewModel`, as it is not particularly interesting.

#### ShoppingListsCollectionViewModel

`ShoppingListsCollectionViewModel` is the view model backing `ShoppingListsCollectionPage`, the main page of the application, that shows the list of shopping lists for the current user. Let's take a look look at the main elements:

``` csharp
public class ShoppingListsCollectionViewModel : BaseViewModel
{
    private readonly Realm realm;
    private bool loaded;

    public ICommand AddListCommand { get; }
    public ICommand OpenListCommand { get; }

    public IEnumerable Lists { get; }

    public ShoppingList SelectedList
    {
        get => null;
        set
        {
            OpenListCommand.Execute(value);
            OnPropertyChanged();
        }
    }

    public ShoppingListsCollectionViewModel()
    {
        //1
        realm = RealmService.GetRealm();
        Lists = realm.All();

        AddListCommand = new AsyncCommand(AddList);
        OpenListCommand = new AsyncCommand(OpenList);
    }

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

        IDisposable loadingIndicator = null;

        try
        {
            //2
            if (!loaded)
            {
                //Page is appearing for the first time, sync with service
                //and retrieve users and shopping lists
                loaded = true;
                loadingIndicator = DialogService.ShowLoading();
                await DataService.TrySync();
                await DataService.RetrieveUsers();
                await DataService.RetrieveShoppingLists();
            }
            else
            {
                DataService.FinishEditing();
            }
        }
        catch
        {
            await DialogService.ShowAlert("Error", "Error while loading the page");
        }
        finally
        {
            loadingIndicator?.Dispose();
        }
    }

    //3
    private async Task AddList()
    {
        var newList = new ShoppingList();
        newList.Owners.Add(DataService.CurrentUser);
        realm.Write(() =>
        {
            return realm.Add(newList, true);
        });

        await OpenList(newList);
    }

    private async Task OpenList(ShoppingList list)
    {
        DataService.StartEditing(list.Id);
        await NavigationService.NavigateTo(new ShoppingListViewModel(list));
    }
}
```

In the constructor of the view model (*1*), we are initializing `realm` and also `Lists`. That is a queryable collection of `ShoppingList` elements, representing all the shopping lists of the user. `Lists` is defined as a public property with a getter, and this allows to bind it to the UI, as we can see in `ShoppingListsCollectionPage.xaml`:

``` xml

    
    
        
            
                
                
            
        
    

```

The content of the page is a `ListView` whose `ItemsSource` is bound to `Lists` (*A*). This means that the rows of the `ListView` are actually bound to the elements of `Lists` (that is, a collection of `ShoppingList`). A little bit down, we can see that each of the rows of the `ListView` is a `TextCell` whose text is bound to the variable `Name` of `ShoppingList` (*B*). Together, this means that this page will show a row for each of the shopping lists, with the name of list in the row.

An important thing to know is that, behind the curtains, Realm collections (like `Lists`, in this case) implement `INotifyCollectionChanged`, and that Realm objects implement `INotifyPropertyChanged`. This means that the UI will get automatically updated whenever there is a change in the collection (for example, by adding or removing elements), as well as whenever there is a change in an object (if a property changes). This greatly simplifies using the MVVM pattern, as implementing those interfaces manually is a tedious and error-prone process.

Coming back to `ShoppingListsCollectionViewModel`, in `OnAppearing`, we can see how the Realm collection is actually populated. If the page has not been loaded before (*2*), we call the methods `DataService.RetrieveUsers` and `DataService.RetrieveShoppingLists`, that retrieve the list of users and shopping lists from the service and insert them into the realm. Due to the fact that Realm collections are live, `Lists` will notify the UI that its contents have changed, and the list on the screen will get populated automatically.
Note that there are also some more interesting elements here that are related to the synchronization of local data with the web service, but we will discuss them later.

Finally, we have the `AddList` and `OpenList` methods (*3*) that are invoked, respectively, when the *Add* button is clicked or when a list is clicked. The `OpenList` method just passes the clicked `list` to the `ShoppingListViewModel`, while `AddList` first creates a new empty list, adds the current user in the list of owners, adds it to the realm, and then opens the list.

#### ShoppingListViewModel

`ShoppingListViewModel` is the view model backing `ShoppingListPage`, the page that shows the content of a certain list and allows us to modify it:

``` csharp
public class ShoppingListViewModel : BaseViewModel
{
    private readonly Realm realm;

    public ShoppingList ShoppingList { get; }
    public IEnumerable CheckedItems { get; }
    public IEnumerable UncheckedItems { get; }

    public ICommand DeleteItemCommand { get; }
    public ICommand AddItemCommand { get; }
    public ICommand DeleteCommand { get; }

    public ShoppingListViewModel(ShoppingList list)
    {
        realm = RealmService.GetRealm();

        ShoppingList = list;

        //1
        CheckedItems = ShoppingList.Items.AsRealmQueryable().Where(i => i.Purchased);
        UncheckedItems = ShoppingList.Items.AsRealmQueryable().Where(i => !i.Purchased);

        DeleteItemCommand = new Command(DeleteItem);
        AddItemCommand = new Command(AddItem);
        DeleteCommand = new AsyncCommand(Delete);
    }

    //2
    private void AddItem()
    {
        realm.Write(() =>
        {
            ShoppingList.Items.Add(new GroceryItem());
        });
    }

    private void DeleteItem(GroceryItem item)
    {
        realm.Write(() =>
        {
            ShoppingList.Items.Remove(item);
        });
    }

    private async Task Delete()
    {
        var confirmDelete = await DialogService.ShowConfirm("Deletion",
            "Are you sure you want to delete the shopping list?");

        if (!confirmDelete)
        {
            return;
        }

        var listId = ShoppingList.Id;
        realm.Write(() =>
        {
            realm.Remove(ShoppingList);
        });

        await NavigationService.GoBack();
    }
}
```

As we will see in a second, the page is binding to two different collections, `CheckedItems` and `UncheckedItems`, that represent, respectively, the list of items that have been checked (purchased) and those that haven't been. In order to obtain those, `AsRealmQueryable` is called on `ShoppingList.Items`, to convert the `IList` to a Realm-backed query, that can be queried with LINQ.

The xaml code for the page can be found in `ShoppingListPage.xaml`. Here is the main content:

``` xml

    
        
        
            
            
            
            
                
                    
                        
                        
                            
                            
                            
                            
                            
                            
                        
                    
                
            
             
            
             
            
            
            
            
                
                    
                        
                            
                            
                            
                        
                    
                
            
        
    

```

This page is composed by an external `StackLayout` (A) that contains:

* (B) An `Editor` whose `Text` is bound to `ShoppingList.Name`. This allows the user to read and eventually modify the name of the list.
* (C) A bindable `StackLayout` that is bound to `UncheckedItems`. This is the list of items that need to be purchased. Each of the rows of the `StackLayout` are bound to an element of `UncheckedItems`, and thus to a `GroceryItem`.
* (D) A `Button` that allows us to add new elements to the list.
* (E) A separator (the `BoxView`) and a `Label` that describe how many elements of the list have been ticked, thanks to the binding to `CheckedItems.Count`.
* (F ) A bindable `StackLayout` that is bound to `CheckedItems`. This is the list of items that have been already purchased. Each of the rows of the `StackLayout` are bound to an element of `CheckedItems`, and thus to a `GroceryItem`.

If we focus our attention on on the `DataTemplate` of the first bindable `StackLayout`, we can see that each row is composed by three elements:

* (H) A `Checkbox` that is bound to `Purchased` of `GroceryItem`. This allows us to check and uncheck items.
* (I) An `Entry` that is bound to `Name` of `GroceryItem`. This allows us to change the name of the items.
* (J) A `Button` that, when clicked, executed the `DeleteItemCommand` command on the view model, with `GroceryItem` as argument. This allows us to delete an item.

Please note that for simplicity, we have decided to use a bindable `StackLayout` to display the items of the shopping list. In a production application, it could be necessary to use a view that supports virtualization, such as a `ListView` or `CollectionView`, depending on the expected amount of elements in the collection.

An interesting thing to notice is that all the bindings are actually two-ways, so they go both from the view model to the page and from the page to the view model. This, for example, allows the user to modify the name of a shopping list, as well as check and uncheck items. The view elements are bound directly to Realm objects and collections (`ShoppingList`, `UncheckedItems`, and `CheckedItems`), and so all these changes are automatically persisted in the realm.

To make a more complete example about what is happening, let us focus on checking/unchecking items. When the user checks an item, the property `Purchased` of a `GroceryItem` is set to true, thanks to the bindings. This means that this item is no more part of `UncheckedItems` (defined as the collection of `GroceryItem` with `Purchased` set to false in the query (*1*)), and thus it will disappear from the top list. Now the item will be part of `CheckedItems` (defined as the collection of `GroceryItem` with `Purchased` set to true in the query (*1*)), and as such it will appear in the bottom list. Given that the number of elements in `CheckedItems` has changed, the text in `Label` (*E*) will be also updated.

Coming back to the view model, we then have the `AddItem`, `DeleteItem`, and `Delete` methods (*2*) that are invoked, respectively, when an item is added, when an item is removed, and when the whole list needs to be removed. The methods are pretty straightforward, and at their core just execute a write transaction modifying or deleting `ShoppingList`.

## Editing and synchronization

In this section, we are going to discuss how shopping list editing is done in the app, and how to synchronize it back to the service.

In a mobile application, there are generally two different ways of approaching *editing*:

* *Save button*. The user modifies what they need in the application, and then presses a save button to persist their changes when satisfied.
* *Continuous save*. The changes by the user are continually saved by the application, so there is no need for an explicit save button.

Generally, the second choice is more common in modern applications, and for this reason, it is also the approach that we decided to use in our example.

The main editing in `SharedGroceries` happens in the `ShoppingListPage`, where the user can modify or delete shopping lists. As we discussed before, all the changes that are done by the user are automatically persisted in the realm thanks to the two-way bindings, and so the next step is to synchronize those changes back to the web service. Even though the changes are saved as they happen, we decided to synchronize those to the service only after the user is finished with modifying a certain list, and went away from the `ShoppingListPage`. This allows us to send the whole updated list to the service, instead of a series of individual updates. This is a choice that we made to keep the application simple, but obviously, the requirements could be different in another case.

In order to implement the synchronization mechanism we have discussed, we needed to keep track of which shopping list was being edited at a certain time and which shopping lists have already been edited (and so can be sent to the web service). This is implemented in the following methods from the `DataService` class:

``` csharp
public static void StartEditing(Guid listId)
{
    PreferencesManager.SetEditingListId(listId);
}

public static void FinishEditing()
{
    var editingListId = PreferencesManager.GetEditingListId();

    if (editingListId == null)
    {
        return;
    }

    //1
    PreferencesManager.RemoveEditingListId();
    //2
    PreferencesManager.AddReadyForSyncListId(editingListId.Value);

    //3
    Task.Run(TrySync);
}

public static async Task TrySync()
{
    //4
    var readyForSyncListsId = PreferencesManager.GetReadyForSyncListsId();

    //5
    var editingListId = PreferencesManager.GetEditingListId();

    foreach (var readyForSyncListId in readyForSyncListsId)
    {
        //6
        if (readyForSyncListId == editingListId)  //The list is still being edited
        {
            continue;
        }

        //7
        var updateSuccessful = await UpdateShoppingList(readyForSyncListId);
        if (updateSuccessful)
        {
            //8
            PreferencesManager.RemoveReadyForSyncListId(readyForSyncListId);
        }
    }
}
```

The method `StartEditing` is called when opening a list in `ShoppingListsCollectionViewModel`:

``` csharp
private async Task OpenList(ShoppingList list)
{
    DataService.StartEditing(list.Id);
    await NavigationService.NavigateTo(new ShoppingListViewModel(list));
}
```

This method persists to disk the `Id` of the list that is being currently edited.

The method `FinishEditing` is called in `OnAppearing` in `ShoppingListsCollectionViewModel`:

``` csharp
internal override async void OnAppearing()
{
    base.OnAppearing();

        if (!loaded)
        {
            ....
            await DataService.TrySync();
            ....
        }
        else
        {
            DataService.FinishEditing();
        }
    }

}
```

This method is called when `ShoppingListsCollectionPage` appears on screen, and so the user possibly went back from the `ShoppingListsPage` after finishing editing. This method removes the identifier of the shopping list that is currently being edited (if it exists)(*1*), and adds it to the collection of identifiers for lists that are ready to be synced (*2*). Finally, it calls the method `TrySync` (*3*) in another thread.

Finally, the method `TrySync` is called both in `DataService.FinishEditing` and in `ShoppingListsCollectionViewModel.OnAppearing`, as we have seen before. This method takes care of synchronizing all the local changes back to the web service:

* It first retrieves the ids of the lists that are ready to be synced (*4*), and then the id of the (eventual) list being edited at the moment (*5*).
* Then, for each of the identifiers of the lists ready to be synced (`readyForSyncListsId`), if the list is being edited right now (*6*), it just skips this iteration of the loop. Otherwise, it updates the shopping list on the service (*7*).
* Finally, if the update was successful, it removes the identifier from the collection of lists that have been edited (*8*).

This method is called also in `OnAppearing` of `ShoppingListsCollectionViewModel` if this is the first time the corresponding page is loaded. We do so as we need to be sure to synchronize data back to the service when the application starts, in case there have been connection issues previously.

Overall, this is probably a very simplified approach to synchronization, as we did not consider several problems that need to be addressed in a production application:

* What happens if the service is not reachable? What is our retry policy?
* How do we resolve conflicts on the service when data is being modified by multiple users?
* How do we respect consistency of the data? How do we make sure that the changes coming from the web service are not overriding the local changes?

Those are only part of the possible issues that can arise when working with synchronization, especially in a collaborative applications like ours.

## Conclusion

In this article, we have shown how Realm can be used effectively in a Xamarin.Forms app, thanks to notifications, bindings, and live objects.

The use of Realm as the source of truth for the application greatly simplified the architecture of SharedGroceries and the automatic bindings, together with notifications, also streamlined the implementation of the MVVM pattern.

Nevertheless, synchronization in a collaborative app such as SharedGroceries is still hard. In our example, we have covered only part of the possible synchronization issues that can arise, but you can already see the amount of effort necessary to ensure that everything stays in sync between the mobile application and the web service.

In a following article, we are going to see how we can use Realm Sync to greatly simplify the architecture of the application and resolve our synchronization issues.