Cross Platform C#
Here’s a look -- with code samples -- at two series of updates that will improve the feature set and, most important, performance of Microsoft’s cross-platform UI solution.
I have an interesting relationship with Xamarin.Forms (XF). My view of cross-platform interfaces was born back in 1993 during a hallway conversation regarding cross-platform (Windows and Mac at the time) and how an interface that looked like Windows on the Mac meant the Mac users were going to come for you with pitchforks.
I had several conversations from 2011 to 2013 with various people from Xamarin about the need for a cross-platform visual UI for mobile devices. Basically, I was hearing from customers that there was a need for a cross-platform UI API. There needed to be some type of API that developers could call for buttons, textboxes and lists that spanned iOS and Android platforms. My favorite response was: "When hell freezes over." I laughed about this because I hate cross-platform APIs that don’t look like the underlying platform. I’ve seen this several times with cross-platform UIs.
Then I was in Las Vegas in 2013 and my friend told me that "Hell has indeed frozen over." I laughed because I knew exactly what he was talking about. A few weeks later I was in San Francisco and had about three hours of discussion with Jason Smith -- the mastermind behind XF who comes from the gaming industry where performance is key -- regarding XF, how it would work, some of the underlying pieces and a bunch of things that were well over my head.
Fast forward almost four years, and I’ve seen some highs and lows with XF. It works well for things that are fairly simple. For apps that are complex, I’ve been less sold on the idea. Having to load a lot of external components to get the native device functionality into a project isn’t a formula for success, I found. I’ve been bitten by components no longer supported, components not working as advertised and my general distrust for components not part of a main product package. Add with the experience of XF running fine on iOS and horribly slow on anything but the most recent Android devices, I’d become quite concerned about the feasibility of XF. I’ve been concerned about the amount of dependence on XF as the singular cross-platform development solution with Xamarin. Thankfully, over the past year I’ve doubled down on my testing of XF. I’ve written two applications for my startup and used XF. Each application has been thoroughly tested on my 2-year-old Android phone. These apps seem to run well, but they’re admittedly simple and might not be a good example measurement. After all, both deal more with data, pictures and Web services than they do with a lot of UI interaction.
The recent Microsoft Build 2017 presentation detailed what’s coming in XF regarding features and -- most important -- performance. To that end, Xamarin announced two sets of updates:
- XF 2.3.5: XF 2.3.5 is a current time-frame update that includes a number of bug fixes, as well as performance enhancements.
- XF 3.0 Series: First off, what is the XF 3.0 Series? The XF 3.0 Series basically means the XF 3.0 release, as well as a set of features that will build on the XF 3.0 feature set. Some features in the series probably won’t be included in the initial rollout, but could be in a 3.01, 3.1, 3.2 or subsequent release. The XF enhancements will include performance improvements, as well as an expanded feature set.
Note: XF 2.3.5 is currently in beta and is available as a pre-release NuGet package at the time of this writing.
Startup Time: Seriously, who hasn’t written an app with XF and not had to wait and wait for the application to load. It’s not too bad on iOS, but on Android our apps feel like they’re taking forever to load. Xamarin has heard this and is working on as many of the performance issues as they can.
Fast Renderers: Currently, views in a layout are recreated in memory. There’s a virtual implementation, as well as the actual visual representation. While this feature isn’t a major problem on iOS, it causes more performance overhead in Android both in memory and speed. Fast Renderers will take these two views in memory and reduce them to one. That will decrease the amount of memory used and decrease the amount of processing used to keep the two control implementations in sync in an application. Depending on the number of controls in an application, this might end up being a significant win.
One word of warning about Fast Renderers: They’ll roll out slowly. The XF team has to create these individually for each control and each platform. This will take a while.
Mac OS: There’s now a beta version for XF for the Mac. While building a Mac version of an application may not be high on the list of features, there are certain pieces of the market segment that could use XF on the Mac. I see two scenarios where XF on the Mac makes sense:
- It would be a cheap, easy and quick way to get something working on the Mac to satisfy a specific need.
- It would be helpful to debug an application without getting too involved with emulators, setting them up and so forth.
Figure 1 is a screenshot of an XF application running on a Mac and Figure 2 is a comparison picture running in the iOS simulator.
While there are clearly some visual differences between the application running on the two different platforms, the same functionality is all there.
Note: While XF for the Mac works, the developer is responsible for making sure that all of the NuGet packages, plug-ins, components, images and so on are all available and set up in the Mac project. Otherwise, strange errors can easily occur.
Xamarin is continually working on new features. A series of improvements has been announced in the XF 3.0 Series that may not appear in the initial XF 3.0 release, but will be released eventually:
FlexLayout is a CSS-inspired layout system that will flow elements. These can be used in gallery-style applications.
There will be a Standardized Renderer API. Currently, Renderer APIs aren’t standardized across renderers and platforms. This should improve the programming experience.
One Time Binding has been added. ListViews will be improved to support the binding in one direction.
XAMLC improvements have been included.
CSS-like styling will be offered.
The Visual State Manager is a new feature.
Embedding will allow an XF page to be used within a Xamarin iOS or Android application.
New back-end support has been added. Back-ends that have been announced include Tizen, Windows Presentation Foundation and GTK#.
- Embedding XF code inside of an X.iOS or X.A application will be easier and simpler. It will allow for easier implementation inside a Xamarin.iOS or Xamarin.Android application.
- More Fast Renderers will roll out throughout the 3.0 Series.
- Layout Compression will be offered.
- There will be ListView improvements:
- The requirement to use cells will be removed
- Some intermediate layers in the ListView will be removed.
- Direct item insertion will be added.
Embedding XF in an X.iOS or X.A
With the release of XF 3.0, Xamarin will introduce some fairly easy usage in X.iOS and X.A. This will be helpful for applications that need some native iOS/Android application functionality but would benefit from some simple code sharing -- XF might be a good way to do it. The basic two-step process within X.iOS and X.A will be:
- An instance of the XF content page will be created programmatically.
- With the instance of the content page, there will be some functionality to create a native UI element. This could be functionality to create a UIViewController, a Fragment, an Activity or some other similar platform-specific element.
Let’s look at some XF implementations of this.
XF Embedding in iOS: In the following code sample, a content page instance is created from an XF project. The next step is to create a UI View Controller and, finally, to push the View Controller on to the navigation stack in iOS:
if (_history == null)
// #2 Use it
_history = new HistoryPage().CreateViewController();
// And push it onto the navigation stack
XF Embedding in Android The following Android code sample is similar to the iOS example. Once again, a content page is created, a fragment is created next and then the fragment is added via the fragment manager:
if (_history == null)
// #1 Initialize Forms.Init(Context, Bundle)
// #2 Use it with CreateFragment(Context)
_history = new HistoryPage().CreateFragment(this);
// And push that fragment onto the stack
FragmentTransaction ft = FragmentManager.BeginTransaction();
ft.Replace(Resource.Id.fragment_frame_layout, _history, "history");
Android developers will see how this is the same concept as working with fragments in Android. For more details on embedding XF and data binding, check out Greg Shackles’ article, " Looking Ahead to Xamarin.Forms 3.0."
iOS has a great control for displaying groups of data in something besides a table, called UICollectionView. The UI Collection View is also good for displaying data on the iPad. Unfortunately, XF has been a little bit limited in this area. The 3.0 series will include FlexLayout, which will offer a layout view that will flow around the screen. Here’s some example code from Xamarin:
<Label Text="Element 1" />
<Label Text="Element 2" />
<Label Text="Element 3" />
<Label Text="Element 4" />
<Label Text="Element 5" />
<Label Text="Element 6" />
This will result in something like Figure 3.
Features in FlexLayout will include the ability to align the content, align items and set the position. Other features include the ability to handle overflows, wrapping, order and a host of other properties.
Microsoft’s first attempt at cross-platform libraries was the Portable Class Library (PCL). PCLs are an OK solution as long as the developer only wants to target a couple of platforms. The idea that PCLs would only support the .NET APIs on every platform made sense. Unfortunately, the number of platforms that support.NET has grown from just flavors of Windows to iOS, Android, Windows, ASP.NET, ASP.NET Core, Xbox, Mac, Linux and more. Other platforms are coming down the road, including Tizen. But having more than three or four profiles becomes nearly impossible to keep in one’s head.
Microsoft took feedback about this issue and decided to go in a different direction. The idea is, instead of having a mathematical cross section of the APIs available across the platforms in use, to have a defined set of APIs available across all platforms. With .NET Standard, all platforms have a defined set of APIs supported in the .NET Framework on the platform. That should get rid of problems such as tracking down what platform supports what.
XF is definitely guided by XAML. Unfortunately, the dialect/language is a bit different. Controls in XF are defined differently from controls in Windows 10 XAML. With XAML Standard in XF, developers will be able to use a single API to define their XAML layouts. This is still a ways off, but it has at least been announced.
Along with XAML Standard, Xamarin has announced improvements to XAMLC, the XF XAML compiler. XAMLC helps improve XAML performance by compiling the XAML at compile time instead of waiting until the class is created on an Android phone. One of the problems with performance in Android is the hierarchical nature of Android layouts. The problem is so bad that Android has its own tool to develop a hierarchical layout viewer. XAMLC helps when the application has a complicated UI that’s fairly hierarchical. By pre-compiling XAML, XAMLC helps speed up creation of an Android layout. The factor of the improvement depends on the complexity of the user information.
XF has come a long way in the last four years -- from a simple place to create a simple UI data-bound application to today’s platform where developers can build full-featured applications. Xamarin is clearly hearing the problems of the development community with its tools and is working on solving them. The step to XF 2.3.5 and the future step to 3.0 shows that the platform will continue to be updated in the future.