Flying with Xamarin and Telerik UI

Ask any developer about what code they are really proud to have written – the stories would be amazing. Maybe it is life-saving software in a healthcare system, or mission critical app in a global business or simply an open source library used freely by thousands of other developers. We software developers should take pride in our craftsmanship.

As for me, it was a WPF application – yup, I know, sounds boring. But I used to work at a private aviation company and we saw direct application of technology to aid the aviation industry.

Our application was used extensively by company dispatchers to do flight planning, tail routing and maintain operational safety. And boy – you do not want production bugs when you are flying business executives and Hollywood or sports celebrities. Glitches in our software could bring down planes and the company would probably not recover from the public relations disaster.

Sure we had some scary moments, but overall it was pride and craftsmanship in our applications that kept planes flying safely – day in and day out. I wish we had Xamarin for making cross-platform mobile apps back in those days.

This article combines two of my passions – a pure love for aviation and building connected mobile apps with Xamarin.

You got wings!

In this age of busy jet-setting across the globe, it is easy to forget the obvious – the absolute miracle of aviation. The next time you complain about failing WiFi over trans-Atlantic flights, let us try to remember the simple yet magical science that it takes to fly at cruising altitudes of up to 50,000 feet in a metal tube – all the while enjoying the comforts of food, drinks and entertainment at your fingertips.

Modern planes are amazing. If you're an aviation nerd or plain curious, read on – or, if you are not, simply skip over to the next section.

I, for one, often choose my flight itineraries based on the planes that the airliners are flying. My two absolute favorites big jets: the Boeing Dreamliner 787 and the Airbus A380.

The Boeing Dreamliner 787 is a modern, efficient beauty – the composite carbon fiber body isn't susceptible to metal fatigue, thus ensuring higher cabin pressurization and easier breathing for passengers. Here's the Dreamliner pulling off some impressive maneuvers on a test flight – a near combat takeoff with tremendous stress on the wings, sharp banked turns and short landing.

The Airbus A380 continues to be the largest passenger plane – fully-loaded, the double-decker's maximum take-off weight is a whopping 560K kg or 1200K lbs. Below is an Emirates Airbus 380 taking off – as smooth as a hand glider off a cliff. All that weight pulled up with such basic laws of physics – Bernoulli's principle says slower moving air under the wings exerts far greater pressure thus causing lift.

It is easy to take flying for granted, but a little notice will help in greater appreciation of modern airplanes. Next time you fly, ask yourself these questions:

  • What's your plane's V1 speed?
  • How do pilots calculate fuel amounts? How do JetStreams make a difference?
  • What's an altimeter? What's a TCAS?
  • If all engines and hydraulics are lost, what basic controls can keep a plane gliding along?
  • If all pilots are knocked unconscious, can you land your plane following ATC guidance?
  • How much crosswinds can your plane handle during landing?

Planes are most vulnerable during takeoff and landing. So just for 60 seconds, take off that headphone and be the additional ears/eyes of the crew. Raise concerns if you have any – it will surely make it to the pilot. And above everything else, enjoy that wonderful flight of yours.

Building an App for Private Aviation

Private aviation is an interesting industry – it shares a lot of the same headaches as commercial aviation, but faces some unique operational challenges.

For starters, we are dealing with inherently small planes and it takes the precision of an orchestra to keep the fleet running. For small jets, weight and balance become big factors – something we do not even consider in modern commercial jets. Pilots have to meticulously plan the distribution of people and luggage to get the balance just right for takeoff/landing.

The rich and famous do not quite fly like we do though – most private jets are luxurious and stunning for their versatility. The interiors are customized for comfort, and what better time saver than having a plane that runs to your schedule!

Now, say you are the CEO of a private aviation company – quite the enviable job. You manage a fleet of popular business jets that your customers rent for use. Wouldn't you want a first class mobile experience so your customers can look up information about your planes?

For consumers, you'd want to show a list of all your planes along with pertinent detailed information. And of course, you'd want your lone .NET developer (in this case, me) to cater to all mobile platforms from a single codebase. Enter Xamarin and Telerik UI for Xamarin.

The Data

First, let's get the fleet organized – we have some of the best private jets around, with, maybe, the GulfStream V being my personal favorite. I can host data about our fleet anywhere – hopefully with one of the many cloud infrastructure providers, and not under my desk.

I'm choosing to use Telerik Backend Services – a reliable backend companion to my mobile/web apps. You can give it a spin with a free trial as well, if you do not already have a subscription.

I have images for each of the jets – though, in the future, I'll likely want to host hundreds more exterior/interior images to make things enticing for our customers. Here are my image files, sitting on Backend Services – each image with its own ID and URL.

bizjetimages

Next, I have a simple table that lists all the available jets – the pertinent pieces of information are the aircraft name, passenger capacity and URL to its corresponding image. Think of this as a SQL Server table – just running in the cloud with bells and whistles.

bizjetstable

The Service

I can host my data anywhere, but the end goal is to have an easy RESTful endpoint to access the data from. This service needs to produce data quickly for consumption from any application platform, and also extend itself to manipulating the underlying data easily. With Telerik Backend Services, creating a RESTful service is free and automatic.

Every content table in Backend Services, like my BizJets one, is essentially an entity – a RESTful endpoint is exposed for each. And every Telerik Platform app gets an unique App ID for basic security. So I could go to https://api.everlive.com/v1/"app-id"/BizJets in my browser and get some JSON back – straight out of the BizJets entity.

bizjetsjson

I could play with this API service all day from my browser or favorite HTTP tool like Fiddler or Postman. And it's not just JSON for consumption – it's a true RESTful endpoint that supports all CRUD data operations for easy data manipulation.

The App

With data and RESTful service in place, I want to focus on building a native mobile app for consumer consumption – after all, they'll be the ones picking the fancy jets for private usage. Being the lone developer in the company, I want easy maintainability of the app from a single code base. So I fire up a Xamarin.Forms project template and start building up my app from scratch following a loose MVVM pattern.

The Model

With a RESTful endpoint providing data, I could consume and use the cloud API from any platform, but hand-coding HTTP requests can be such a chore. Telerik Backend Services gives me wrappers for just about any platform – they make it easier to work with the data by sugar-coating the underlying HTTP calls. In the Downloads section of the Platform app are the Backend Services SDKs – I want to grab the .NET one for my Xamarin project.

baassdk

Once downloaded, I simply add a reference to the Everlive DLL in my project. Everything I'm doing here is pretty generic and not specific to iOS/Android/Windows – so the best place would be shared PCL or .NET Standards library.

The easiest way to work with Backend Services data is to have a Model that mimics the entity table in the cloud – the data marshaling becomes free. I can craft my model however I like – by naming things differently from the entity table or selectively choose fields, but I want to implement the INotifyPropertyChanged pattern for easy 2-way data binding with my Model's data.

Here's a sample of what a model could like for my BizJets entity.

using System;
using Telerik.Everlive.Sdk.Core;
    
using Telerik.Everlive.Sdk.Core.Model.Base;
using Telerik.Everlive.Sdk.Core.Serialization;
    
namespace Aviation
{
    [ServerType("BizJets")]
    public class BizJets : DataItem
    {
        private string aircraftName;
        public string AircraftName
        {
            get
            {
                return this.aircraftName;
            }
            set
            {
                this.aircraftName = value;
                this.OnPropertyChanged("AircraftName");
            }
        }
    
        private string aircraftCapacity;
        public string AircraftCapacity
        {
            get
            {
                return this.aircraftCapacity;
            }
            set
            {
                this.aircraftCapacity = value;
                this.OnPropertyChanged("AircraftCapacity");
            }
        }
    
        private string aircraftImageURL;
        public string AircraftImageURL
        {
            get
            {
                return this.aircraftImageURL;
            }
            set
            {
                this.aircraftImageURL = value;
                this.OnPropertyChanged("AircraftImageURL");
            }
         }
     }
 }

The ViewModel

Each of my ViewModels handle all the data that is needed for the corresponding Views. Below is some sample code to bring down a list of all BizJet entity contents. Two things to note here:

  • The usage of ObservableCollection<BizJets> – this will be the Observable collection to do 2-way binding with our UI.
  • Notice how easily the Backend (Everlive) SDK wraps HTTP calls – even with the asynchronous Async-Await pattern.
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
    
using Telerik.Everlive.Sdk.Core;
    
namespace Aviation
{
    public class BizJetsViewModel
    {
        private string BSAppId = "your-app-id";
        private EverliveApp ELHandle;
    
        public ObservableCollection<BizJets> BizJetsCollection { get; set; }
    
        public BizJetsViewModel()
        {
            EverliveAppSettings appSettings = new EverliveAppSettings() { AppId = BSAppId, UseHttps = true };
            ELHandle = new EverliveApp(appSettings);
        }
    
        public async Task<ObservableCollection<BizJets>> GetAllBizJets()
        {
            var bizJetsManager = ELHandle.WorkWith().Data<BizJets>();
            var allBizJets = await bizJetsManager.GetAll().ExecuteAsync();
    
            BizJetsCollection = new ObservableCollection<BizJets>();
            foreach (BizJets serializedBizJet in allBizJets)
            {
                BizJetsCollection.Add(serializedBizJet);
            }
    
            return BizJetsCollection;
        }
    }
}

The View

The first ask is to display all our BizJets in a nice list. Most apps need to display a list of things – but this isn't so trivial. I'm going to pick up a ListView on steroids – the one that comes with Telerik UI for Xamarin. Why? Because I immediately gain rich features out-the-box like UI virtualization, various layout modes, pull to refresh, item swipe and extreme performance to name a few.

There are a couple of lines of initialization, like what's added here to the AppDelegate.cs file for iOS apps – the docs offer guidance on initializing controls correctly.

using System;
using System.Collections.Generic;
using System.Linq;
    
using Foundation;
using UIKit;
    
[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.DataControls.RadListView), typeof(Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer))]
    
namespace Aviation.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
    
            Telerik.XamarinForms.Common.iOS.TelerikForms.Init();
            new Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer();
    
            LoadApplication(new App());
    
            return base.FinishedLaunching(app, options);
        }
    }
}

Now, I'll set the BizJet list page to be the starting page in my app. Here's a super-simplified sample of XAML markup that shows the user a list of all the BizJets coming from the cloud API call. Notice the usage of RadListView here and the standard data binding to the elements of the BizJets entity.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Aviation.BizJetsView"
             xmlns:TelerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
             xmlns:TelerikListView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls">
    <ContentPage.Content>
        <TelerikDataControls:RadListView x:Name="BizJetsList" SelectionMode="Single">
            <TelerikDataControls:RadListView.ItemTemplate>
                <DataTemplate>
                    <TelerikListView:ListViewTemplateCell>
                    <TelerikListView:ListViewTemplateCell.View>
                      <StackLayout Orientation="Horizontal" Padding="20">
                            <Image Source="{Binding AircraftImageURL}" WidthRequest="100" HeightRequest="100" />
                            <StackLayout Orientation="Vertical" Padding="0,20,0,0">
                                <Label Text="{Binding AircraftName}" TextColor="Black" FontAttributes="Bold" />
                                <StackLayout Orientation="Horizontal">
                                    <Label Text="Passenger Capacity: " TextColor="Gray" />  
                                    <Label Text="{Binding AircraftCapacity}" TextColor="Navy" />
                                </StackLayout>
                            </StackLayout>
                      </StackLayout>
                    </TelerikListView:ListViewTemplateCell.View>
                  </TelerikListView:ListViewTemplateCell>
                </DataTemplate>
            </TelerikDataControls:RadListView.ItemTemplate> 
        </TelerikDataControls:RadListView>  
    </ContentPage.Content>
</ContentPage>

And finally, the XAML.cs code behind file – where things are stitched together. Notice how the corresponding ViewModel is leveraged here – simply fetch the data and data-bind to the ListView.

using System;
using System.Collections.Generic;
    
using Xamarin.Forms;
    
namespace Aviation
{
    public partial class BizJetsView : ContentPage
    {
        public BizJetsView()
        {
            InitializeComponent();
            this.FetchViewData();
        }
    
        private async void FetchViewData()
        {
            BizJetsViewModel BZVM = new BizJetsViewModel();
            await BZVM.GetAllBizJets();
            this.BizJetsList.ItemsSource = BZVM.BizJetsCollection;
        }
    
    }
}

If I run the app at this point – from inside of Visual Studio for Windows or Mac – I see a simple yet attractive list of all our BizJets, like as shown below in the iOS simulator.

bizjetsinapp

If I want my users to be able to tap on a certain BizJet and get more detailed information, I simply add an ItemTapped event on the ListView and its corresponding event handler in the code behind. I could perhaps, grab the chosen BizJet and navigate to a detail page or take an appropriate action.

<TelerikDataControls:RadListView x:Name="BizJetsList" SelectionMode="Single" ItemTapped="BizJet_Selected">
  ...
  ...
</TelerikDataControls:RadListView>  

private  BizJet_Selected(object sender, Telerik.XamarinForms.DataControls.ListView.ItemTapEventArgs e)
{
    // Do stuff here.
}

Conclusion

Xamarin gives you the unique ability to maintain one .NET code base to target all mobile platforms. And Telerik UI for Xamarin provides you with rich performant UI components out-of-the-box, like the feature-rich yet versatile ListView to serve as the cornerstone towards your dream app. Plus, it's easy to connect your app to a cloud service through the right RESTful APIs.

Xamarin gives you wings. And Telerik UI for Xamarin gives you thrust. Go fly. And remember to appreciate that next flight of yours just a little.

Comments