Talk With Angel Garcia!

Talk With Angel Garcia!

a blog about software and beers

CabañasRD, from native to cross-platform with Xamarin Forms [3/4].

It’s Friday! that means we will continue with the third part of this series of blogs about migrating and redesigning an existing and popular app: CabañasRD.

The plan is to divide all the process in 4 parts:

  1. From Adobe XD to XAML: Design and structure.
  2. Implementing the command for opening native map, app icons, splash screens, info tab and also the search functionality over the map.
  3. Moving the data to the cloud: Let’s make our backend with Azure Functions and CosmosDB and consume it from the app (this post).
  4. Implementing continuous integration and continuous delivery to the stores with App Center.

Moving the data to the cloud: Let’s make our backend with Azure Functions and CosmosDB and consume it from the app.

I decided to make another post for the backend, if your are focused just in the app development you can continue reading this post without worry about the API, we will be using the one that is already deployed.

Our Xamarin app will consume this Azure Function:


Add a new folder called “Configs” in the App/CabanasRD project, in this new folder add a file called AppSettingsConstants.cs and put this content:

You can see how to get the ApiKey in this post about “Creating a simple serverless microservice using Azure Functions and CosmosDB”.

For consuming the service we will use Refit, an automatic type-safe REST library for .NET Core, Xamarin and .NET, so, let’s install the NuGet package for the library in the shared project (App/CabanasRD), once installed, the first thing we need is an interface for defining the RestService methods, for this add a folder called APIs in App/CabanasRD/Framework, in the new folder add an interface named ICabanasAPI with the following definition:

As you can see, we dont have defined the MotelResponse class yet, let’s add this new class to a folder called “Models” inside App/CabanasRD/Framework/APIs, and fill it with:

This model was generated using the JSON response from the service, with the help of we got the classes with the fields mapped.

Before using the ICabanasAPI, we will need to register it as a RestService in the App.xaml.cs file located in App/CabanasRD, and add the following code in the RegisterTypes method:

We are ready to consume the service by using the ICabanasAPI!

🤔 But… We don’t want to manually convert the service response to our domain model, that’s why we are going to introduce something called AutoMapper, a simple little library built to solve a deceptively complex problem – getting rid of code that mapped one object to another.

Install the AutoMapper NuGet package in the shared project App/CabanasRD, then add the following code to init and configure it in the App/CabanasRD/App.xaml.cs:

Now we are able to convert easily from the service response to our domain model.

As we are following Interface Segregation principle, changing the way we obtain our data is as simple as create another class that implements IMotelsSource, let’s create the MotelsSource.cs class in App/CabanasRD/Framework/DataSources with the following content:

One last thing for switching the InMemoryMotelsSource for the MotelSource, go to the App/CabanasRD/App.xaml.cs and change this:

That’s all, run the app, wait a few seconds in the map and voilà!

🤔🤔🤔 Hey, this introduces new security and UX problems:

  1. If we push this code to our repository the ApiKey will be exposed.
  2. We don’t have a “Loading” indicator anywhere.
  3. If any error occurred during the request the app will crash, there is a need for handling the exceptions.
  4. There are some motels without phones or services or images, we need some empty states.

Let’s make a deal 🤝, I will resolve the first issue and you are going to help me by resolving the rest of problems on GitHub by creating a PR with the changes.

For manage the ApiKey as a secret we will use this wonderful tool made by Dan Siegel called Mobile.BuildTools.

Install the Mobile.BuildTools NuGet package in the shared project App/CabanasRD, once installed we need to create a file in the root of App/CabanasRD called secrets.json and add it to the .gitignore, now that the file is ignored open it and put this:

If you build the app it should be a new file in App/CabanasRD/Helpers called Secrets.cs, it contains static references to the secrets we put in the secrets.json, this autogenerated file should be ignored too, for ignore both files add this to the .gitignore file:

PD: If the build does not generate the Secrets.cs file, add it and the Helpers folder manually and build again.

Nice, now our secrets are out of the source control!

Remove the ApiKey property from App/CabanasRD/Configs/AppSettingsConstants.cs and replace any reference of this removed prop with Helpers.Secrets.ApiKey rebuild and run the app.

Take your stuffs and go home, we are done!

See you in the next post of this serie! 🚀

See the code on Github


Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.