Phillip Trelford's Array

POKE 36879,255

X-Platform development with Xamarin.Forms & F#

This post is part of the F# Advent Calendar in English 2016 series organized by Sergey Tihon.

Last month on November 16 – 17, IDTechEx held their largest annual conference and tradeshow on emerging technologies in California with over 200 speakers and close to 4,000 attendees.

exhibition

The show covers a wide variety of topics including electric vehicles, energy harvesting, energy storage, IoT, graphene, printed electronics, robotics, sensors, AR, VR and wearables. Coming from a software background, I couldn’t help but marvel at the size of the event and the level of genuine innovation and entrepreneurship on show. If you’re based in Europe I’d highly recommend attending the Berlin event in May 2017.

IDTechEx wanted an app where users can easily browse information, including research, journals and upcoming webinars, when they’re out and about, even in a WiFi dead spot. The app needed to be released before the show in California so that at a minimum users could download and browse the conference agenda, list of exhibitors and easily find the venue on a map. Xamarin.Forms and F# were successfully used to build the app which was published in the iTunes and Google Play stores a week before the conference, and well received by attendees:

This post will talk about some of the development process and some of the design decisions for this app.

Xamarin.Forms

IDTechEx wanted a native business app that targeted the vast majority of mobile users which concretely meant iOS and Android support. Xamarin.Forms was chosen as it allows business style apps to be built for both iOS and Android where most of the code can be shared. It is hoped that over the life of the product that the use of Xamarin.Forms should help reduce maintenance costs and improve time-to-market.

Check out Xamarin’s pre-built examples for sample code and to see what can be done: https://www.xamarin.com/prebuilt

Why F#

Xamarin’s ecosystem, including Xamarin.Forms, supports both the C# and F# programming languages. F# is a pragmatic, low ceremony, code-oriented programming language, and the preferred language choice for IDTechEx and it’s development staff.

If you’re new to F# and interested in learning more, I’d recommend checking out these resources:

Creating an F# cross platform Xamarin.Forms solution

To get started I followed Charles Petzold’s detailed article on Writing Xamarin.Forms Apps with F#, where the steps for creating a cross platform solution can be briefly summarised as:

  • Make sure you’re on the latest and greatest stable version of Xamarin (and Visual Studio if you’re on Windows)
  • Create a C#/.Net >> Cross Platform >> Blank App (Xamarin.Form Portable)
  • Replace the C# Portable library with an F# one

Development environments

During development I used 2 environments off of the same code base:

  • Visual Studio 2015 and Windows for testing and deploying the Android version
  • Xamarin Studio and Mac for testing and deploying the iOS version

Switching between Xamarin Studio and Visual Studio on the respective operating systems was seamless.

Build one to throw away

Initially I built a couple of very simple prototype apps using only a a subset of the data, one using XAML and data binding and another using just code. After some playing I came down on the side of the code only approach.

Xamarin.Forms is quite close to WPF, Silverlight and Windows Store application development. I built a working skeleton/prototype as an F# script using WPF and the F# REPL which gives incredibly fast feedback during development.

Once the flow and views of the application were better defined, and I’d received early feedback from users, I threw away the prototype and rebuilt the app fully in Xamarin.Forms.

Note: the plan to throw one away referenced in this section heading refers to Fred Brooks Jr’s suggestion in his seminal book The Mythical Man Month.

Forms DSL

During development in both WPF and Xamarin.Forms I built up a minimal domain-specific language to simplify form building, for example:

    let label text = Label(Text=text)

    let bold (label:Label) = label.FontAttributes <- FontAttributes.Bold; label

    let italic (label:Label) = label.FontAttributes <- FontAttributes.Italic; label

    let namedSize name (label:Label) = label.FontSize <- Device.GetNamedSize(name, typeof<Label>); label

    let micro label = label |> namedSize NamedSize.Micro

    let small label = label |> namedSize NamedSize.Small

    let medium label = label |> namedSize NamedSize.Medium

    let large label = label |> namedSize NamedSize.Large

 

With this the exhibitor page could be written as:

    let exhibitorPage (exhibitor:json) =

        let program = exhibitor?memberOf?programName.AsString()

        let layout =

            StackLayoutEx(VerticalOptions = LayoutOptions.FillAndExpand, Padding=Thickness 10.0)

            + (cachedImage (exhibitor?logo.AsString(), 130.0, 78.0))

            + (exhibitor?name.AsString() |> label |> bold |> medium)

            + (program |> label |> color (programColor program))

            + (exhibitor?location?name.AsString() |> label)

            + ("Company Profile" |> label |> bold)

            + (exhibitor?description.AsString() |> label)

        let url = exhibitor?url.AsString()

        if not <| System.String.IsNullOrEmpty(url)

        then

            let action () = Device.OpenUri(System.Uri(url))

            Button(Text="Website", Command=Command(action)) |> layout.Children.Add

        ContentPage(Title="Exhibitor", Content=layout)

 

Below is a screen shot from the Android App of a exhibitor page generated by the code above:

 

 image

 

Lists

For lists of items, for example exhibitors or presentations, I used Xamarin.Form’s built-in ListView control and the ImageCell and TextCell, along with a custom cell providing more subheadings.

The screen shot below is from the iOS version and shows a list of presentations using a custom cell:

 

presentations

 

Other Libraries

For image loading I used the excellent FFImageLoading which can cache image files on the user’s device.

To show a map for the venue I used Xamarin.Forms.Maps control:

iPhone Screenshot 5

Summary

Using Xamarin.Forms and F# allowed be to successfully build and publish a cross platform mobile app targeting iOS and Android in a short time frame. F# allowed fast prototyping and quick feedback while building the app. Xamarin.Forms worked well and meant that almost all of the code was shared between the platforms. I’d whole heartedly recommend this approach for similar business applications and we plan to extend the app heavily in future releases.

Silverlight Resurrection

Silverlight, once hailed by Microsoft evangelists, is now dead, crucified by the side of Flash by Jobs when he brought down his tablets from mountain view, and then buried by Sinofsky under his surfaces. But is it really dead? Silverlight certainly seems dead in the browser with Google cutting off support in Chrome followed by Microsoft in Edge. Yet Silverlight still lives on in Windows Phone and Windows Store (formerly Windows Runtime, formerly Metro).

Resurrection

Back in 2010 and 2011 I made a series of mini games written in F# with Silverlight and hosted on this blog along with some online arcade sites likes GameJolt and SilverArcade. Rather than let them slide into the sands of time never to be played again I thought I’d have a go at resurrecting them for Windows Phone.

Search for a stable… environment

I started by attempting to create a Windows Phone project in my shiny new installation of Visual Studio 2015 Community, but failed at the first hurdle. To run the Windows Phone emulator you need the Professional version of Windows and silly old me had installed the Standard edition when I rebuilt my Windows partition after a fatal blue screen in the new year.

Then I moved on and tried trusty Visual Studio 2013 but hit the same hurdle. Not to be deterred I went back another year to Visual Studio 2012 but hit a new obstacle, where the 2012 tools don’t work if you have 2013 installed.

Back to the Future

No problem, I span up a virtual machine in Oracle’s Virtual Box with ye old faithful Windows 7 and Visual Studio 2010 installed, and after pushing on VS2010 SP1 and the Windows Phone tools, then some obligatory rebooting and service patches, I was up and running and had a game ported and playing on the emulator. I used a Windows Phone project template from Dan Mohl, which requires an empty C# host project because CLR stands for Common C# Language Runtime apparently. My only remaining issue was that running the phone emulator within a VM was painful. My next step was to purchase dedicated hardware in the form of a refurbished Thinkpad (circa 2010) from Morgan Computers and I finally had a stable environment with an emulator for porting the apps and games over (although no option to deploy to a device as the Zune software is no longer supported).

Lenovo /IBM X201 Intel i5-520M 2.4GHz 12.1

Across the Universe

Microsoft are currently touting the Universal Windows Platform as the future, letting you easily deploy your apps between Windows 10 Phone, Store and other platforms. That said with Visual Studio 2010 I can target the entire Windows Phone range from 7 up to 10, note that number 9 went missing somewhere along the way.

Also note the Windows Phone 7 market currently appears to be almost as “large” as Windows 10 Mobile.

Alien Resurrection

The first game I ported over was Invadurz, a homage to a classic 80s arcade game. It’s available in the Windows Store and I’ve recently upgraded it with low-latency sound effect support via XNA.

Screenshot

And despite the screen shot being the wrong way round a few people have even downloaded it Smile

image

With a simple and stable porting system in place I quickly submitted another 4 apps and games, all available free in the store:

Submission

With some experience under my belt I recently headed down to London to the Windows App London meetup (previously the Windows Phone user group) for the Submit it! hackathon, and during the day I managed 5 submissions:

and won an Easter Egg from Tesco for my efforts!

Second Coming

Just as in the bible, a second coming is in the offing. XNA is dead, long live MonoGame.

I’m currently working on moving the Windows Phone submissions lock stock and barrel over to XNA which should give me a route to full cross platform resurrection via MonoGame with deployment to Android, iOS and beyond…

CNUG6LkWwAAlpuJ.png (433×242)

and many more users, or at least that’s the theory.

Procedural Invaders

Procedural invaders are space invader like characters generated as 5 x 5 pixel characters from just 15 bits using symmetry. The earliest post on procedural invaders appears to be from a J Tarbell in 2003. Thanks go to Ross McKinlay for suggesting having a look.

Below are some sheets of randomly generated invaders with generated names that you can click on to generate a tweet with F# code that generates the invader as ASCII art when sent to Mathias Brandewinder’s @fsibot.

invaders ocodehkiauoyemixuoocuucenotiyofecalepergucjucjoxnoxebatigzuyanitiereypunefegaajusaacorgipciguweejeqemaulaiborruxuvawedayamgasihhedlorifuaelioixejqabexiqiiboquaiwazavvijuzapbuiouxompoqqesonteuitocijwuwtalmufefuysurbuwpujxorroirajjokijgobfibqeejiokusiporixxokajavgolcoqeloooviwemisaguxovegnujepfequpeuaiutoazeleinijtirqenqaesiozawufafuaavexuzumiupomrijeeqipokeeaumehmooezuxixifihohaicebyezboiniokamugucar

invaders

uleraitupisurleyfopupitqohteerodeguzocvunujqeracaciugiktufewkomigepdufuqwoesusahawayuyrayutixezajexowusqixtomurexhaquobepruomagxiihookuzidomexixiuqoqekoyohviiuyugajihakqubseqeweficosepbieebafaaouheeguqkoogamvabbenpoaouoivifhivesjeecoiduvooauuuveuwirigguqfoakedzoovogxekbalerokitukilimfitjeqarwomiiaonoporgaketagmovuharuarobbanaepuiodaskueajudpeluqoejazosowmeafivxureroxoqroralurotemaearuunafionedqelamfopimukagaxesiscivusamazezalafowosanamutitozunimihodlerduaiupirufeniyakmoeuwaneujeboisiasoleutuserquwazalifqukotjisasojukniqetejeuxocemeaqupjevkefewerarzifaeyovarejuguieiofaqeqiqoyilaphapaoacorzowoibavwosgoakugmuxwahoeweakiizownaqootimqamufutoulimoziecoyumuxuwubovezoynonitlargusiycibqudubueerunleceisiayojaehofayiruuukecamayuaenebuxmoviigosyoyretluqmakirhufoydoruweibihalureociycokuszaanozounuquvofenahyurezzeqhepevcagefhizseupivxigulifohdoleaugoyefageoiuemenvucexinucolayyiwbuzuweluhivqumbizevugeoziucovixufuwusemkoluhikkuykiqindecculapereyoiyigamuxomoppeleorawxunnoqdaxyuvooaituelugoufejayisootauwujzomouuegujefubaomepuvopecitobyoctalqufcirishuspijutisagezuuzayaokobyejigomigeorillehbepsoqezojoyulupazuuedenoxzuscafjiaweoetufeginukgixhoskimadogualexnirmirayapofaqafauwivluwqikhidqewboeepihihawudhebakoecoekadgaweryeguiavadepealowagnuhuwavhoecuqihquvaauwoxtupodengodbecazadopuootadxiblabweeuzaoqiqejeelusosiszohzoruhaoceuqieyadibjinilimufimrasyizuqiovopfayeturoqobitiooayezqozeiisictaufijyovtelivasuvejeaaiouopeteuhurisumxakqivuqeecuavezdaduxiyifawohjumerkihpogquhoqaxuttuvilucewyupgohisfesqipcojdafopoffeduroaiiucadbixufguvebisufataufaysesruwauyipilusxiyalatgugerabxuoweuwufumvadierevicununofipojeofofouehilmorser

Techie bit

The sheets of invaders are drawn on to a bitmap image and saved as a png file (see invader bitmap generation F# snippet), with the bit pattern for each invader generated from the hash code of it’s generated name (see pseudoword generation F# snippet). At the same time a matching HTML image-map is generated with the coordinates of each invader with a link that generates a tweet for the specified name.