Sinara_Pos_DIGITAL

Building a mobile trading platform using Xamarin.Forms

When one of our clients requested a mobile trading platform to complement their existing web system, our team knew this would be a particularly interesting project allowing us to make use of several important frameworks and technologies. (more...)

When one of our clients requested a mobile trading platform to complement their existing web system, our team knew this would be a particularly interesting project allowing us to make use of several important frameworks and technologies. For years, server-side, web-based and desktop app development have dominated the financial software space, but as the technology has matured and become commonplace, the demand for effective mobile solutions has grown. Here at Sinara, we’re certainly anticipating many new mobile projects to tackle in 2020 and beyond.

With this in mind, I felt it would be remiss of me not to share our recent experience of mobile development. By exploring the highs and the lows, I hope to offer some insight into what mobile app development can entail.

So let’s begin.

About Xamarin

For the unacquainted, Xamarin is a cross-platform toolkit allowing native apps to be written in C#. The code we write is compiled into native application packages, meaning we only write a single codebase (for the most part) which can then be used across Android, iOS and Windows mobile apps.

Sidenote: An unavoidable part of using a cross-platform toolkit is that the tools need to work across platforms. Xamarin.Forms applications typically make use of a .NET Standard library, so this meant converting some of our NuGet libraries (which used .NET Framework) to support .NET Standard. If how we went about this interests you, let us know!

Using Xamarin (and specifically Xamarin.Forms) to develop our app seemed like the natural choice for a team of .NET developers. We knew we wanted a native, performant app over, say, a built-in browser environment and fundamentally, we like coding in C#.

And that was the first challenge we completed: deciding how to build our app. But it wouldn’t make for a long enough blog post if it was plain sailing from there on out. So please read on.

The great iPhone vs Android debate

  • In Visual Studio, debugging with Android works like a charm; with iOS it gets dicey
  • About 10% of code can’t be shared…

If you are working on a Windows machine, there are quite a few more steps involved in Xamarin.iOS development over Android. To build native iOS apps you need Apple’s build tools and they only run on a Mac – so you’ll need one of those to act as a build host. It’s certainly do-able but for when you’re testing as you code (as I’m sure we all do) it often ends up being more time-consuming to Pair to Mac than it is to hit F5.

Using an emulator is a great way to test your app but we found that debugging on devices was generally quicker. Takeaway: Often, when testing code: devices > emulators and android > (or at least faster than) apple. I would advise you factor in some extra time at the start of your project for iOS related debugging woes.

For the code that can’t be shared, the platform specific stuff, like Face iD for Apple, you will need to write platform specific code. To do this you can add an interface to the shared mobile project and then it’s as simple as implementing it into concrete classes in the .Android and .iOS projects.

Strongly typed classes and SignalR

As a trading platform, our mobile app needed to provide real time communication with an ASP.NET web app; this is technology we’re familiar with (for the SignalR enthusiasts, see Tom’s blog post)

Alongside our Xamarin app, deployed to, well, mobiles, we had an ASP.NET project that the devices communicated with using SignalR.

If you take the same design path as us, your Xamarin app will be a .NET SignalR client. By default, the .NET client and the hub it talks to use dynamic typing – so there is only run-time checking that you’ve spelt method names correctly, used correct parameters etc. If you would like strong, checked at compile time (who doesn’t?) typing for your .NET client, look no further:

  • Create a shared assembly MyServerInterface
  • In this shared assembly, define two C# interfaces: IMyHub and IMyHubClient
  • In the server code, define your hub as strongly or statically typed using these interfaces:

public class MyHub : Hub<IMyHubClient>, IMyHub { /* Implementations for your hub methods here */ }

  • In the client code, create an implementation of the hub client interface, to handle method calls from the server to client:

public class MyHubClient : IMyHubClient { /* Implementations for your hub client methods here */ }

  • In the client code, create a proxy class which implements the hub interface, and use this to call hub methods and receive client method calls:

public class MyHubProxy : IMyHub

{

        private const string MyHubName = "MyHub";

        private readonly string _connectionString;

        private HubConnection _connection;

        private IHubProxy _proxy;

        public MyHubProxy(string connectionString)

        {

            _connectionString = connectionString;

        }

        public async Task Connect(IMyHubClient client)

        {

            _connection = new HubConnection(_connectionString);

#if DEBUG

            _connection.TraceLevel = TraceLevels.All;

            _connection.TraceWriter = Console.Out;

#endif

            // set up proxy for calling server methods

            _proxy = _connection.CreateHubProxy(MyHubName);

            // set up handling for method calls from the server by forwarding them to the IMyHubClient implementation

            _proxy.On<string>(nameof(IMyHubClient.SendMessage), (msg) =>

            {

                Task.Run(() => { client.SendMessage(msg); });

            });

            await _connection.Start();

        }

        // call server methods using IHubProxy.Invoke

        public Task SayHello()

        {

            return _proxy.Invoke(nameof(IMyHub.SayHello));

        }

}

And now a note on debugging your solution.

A lot of development and debugging can only be done by debugging the components (Xamarin app or ASP.NET app) in isolation and running the other without the debugger. If you want to run the debugger against the web app and the mobile app at the same time, you need to set up IIS express to run through visual studio AND allow other machines to access it.

By default, Visual Studio only allows access to localhost, meaning only browsers on your computer have access to it. We discovered that when writing a Xamarin app that makes use of a web app, at times, it’s helpful to debug both simultaneously.

A final note relating to the objects your sending back and forth to devices: bear in mind that the information is getting sent to the device. If the user doesn’t need it, why send it? Not only from a security standpoint but sending only the relevant information in your objects ensures they remain efficient and you code performant.

Finally, let’s talk UI

Xamarin.Forms provides a common API that renders native controls across platforms. Read: not only can we create a single shared codebase in C# for our business logic, but we can do the same with for UI using XAML and C# code-behind, as it gets converted into platform specific elements at runtime.

So our app has a native look and feel on each platform. It looks like an iOS app on iOS and an Android app on Android (if that makes sense), despite sharing the same code.

When it came to actually implementing the frontend design, we employed the trusty MVVM pattern (if it isn’t broken…) and were pleasantly surprised to find that writing the UI using XAML was quite like writing WPF apps with XAML. Certain bugs unique to Xamarin.Forms were found, as is to be expected, and we also noticed if something works on Android it’s no guarantee it works in iOS – so test your code with both platforms (I feel like I bring up testing a lot, but you really should).

And there you have it. Some practical tips about using Xamarin.Forms to build a real-time cross-platform mobile app.

Share the Post:

Related Posts