Reviving a dead pet (project)

I’ve been working on a problem for more than a decade on and off now, and last week I decided I was going to take it seriously.  Seriously enough to set up an Office 365 subscription attached to the project’s domain along with an Azure DevOps subscription for keeping everything in one place.  I’ll regularly be blogging about the project so I thought it’d probably best to write this to provide context for future posts.

History of the project

It’ the first week at university (did I mention I went to Drama School?) and I’m being forced to use a lighting control desk called the ETC Express. It’s like an idiots version of the Strand 500 series, which is the system that I know and love. If you’re not experienced with lighting control then know that lighting programmers often define themselves by their tools, just like we programmers frequently do with our languages and frameworks of choice.

 

Programming a show on my parents dinning table on a Strand 520i.

 

I was whining profusely about how limited the ETC Express was and my tutor said: “well why don’t you build your own then?”. In hindsight, she probably said this out of frustration but I agreed that I could do a better job, and thus commenced my journey back into .NET development and ultimately a career at Microsoft.
Lighting control systems haven’t advanced past the innovations of the Hog 2 created by my good friend Nick Archdale. I wanted to create something unique, but most importantly it had to be as intuitive as the light switches we use at home every day. Initially, I was picturing a huge multi-touch screen, but the technology wasn’t available back then (the original iPhone hadn’t even been announced). I wanted to create a console that could be played like an instrument as lighting can be just as expressive as any musical instrument but frankly, I lacked the skills required to deliver my vision.
Hog 2 Lighting Control Console
Non the less, I started building lots of proof of concepts using WPF to see how it might work. Eventually, had a pretty solid idea of what I wanted to build but I couldn’t even match the features of existing systems with the knowledge I had at the time.
An old screenshot of a proof of concept.

Rebooting the project

Earlier this year I visited Nicks business in West London to discuss licensing some of his technology for a mobile app. One of the chaps there asked if the app would control any lights. It wasn’t in my spec as controlling lights is much more complex than you’d reasonably imagine, but this simple question has derailed the app and reminded me of an itch I’ve been ignoring for years.

I went home and started creating some POCs using my experience gained from a decade of .NET development. I think I’ve cracked the secret sauce for creating a workable, scalable control system. The system HAS to be modular in every aspect from C# projects to physical hardware.

The future

Right now I’ve got the beginnings of a the important components of the control system working and I’m tying them together to build a minimal viable product before I start on the multi-touch instrument like parts that I’ve dream of for the last decade.

I’ve not yet decided how it’ll be released yet. I’m hoping to release bits of this as OSS but can’t promise anything just yet but if you’re interested in getting involved then ping me a message and we can chat!

Right now my UI is HEAVILY inspired by Nicks Hog 3 console but using Prism makes this insanely easy to change! Below is a video I recorded showing one of my small bugs in the windowing system so you can an idea of where I’m at (very early days)

 

Special Thanks

I feel a need to thank a few influential people who’ve helped me over the years to reach the point of being able to tackle this technical problem with some degree of competence.

Rachel Nicholson for the idea and belief that I could create a control system.

Nick Hunt for mentoring me through my dissertation as I investigated what an intuitive lighting control might look like.

Nick Archdale and Richard Mead for hiring me out of university and encouraging me to be a better developer and licensing their fixture data to the project while I develop the control system.

You can reach me anything DMX related at mike@litemic.com

Updated Resilient Networking with Xamarin

Rob Gibbons wrote a fantastic blog post back in 2015 on how best to write network requests layers for your Xamarin Apps. I’ve personally used this approach many times, but I felt that it needed updating for 2018, so here it is. A slightly updated approach to resilient networking services with Xamarin. And when I say ‘slightly update’, I honestly mean it’s a minor change!

we-dont-throw

Refit

For those of you who are familiar with Rob’s approach, he uses pulls together a few libraries to create a robust networking layer. One of the critical elements of his strategy is the use of Refit. Refit is a REST library which allows us to interact with remote APIs with minimal boiler-plate code. It makes heavy use of generics and abstractions to define our REST API calls as a C# Interfaces which are then used with am instance HTTPClient to handle all the requests. All serialisation is dealt with for us! I still believe Refit to be a great library to use so we’ll keep this as the core of this pattern.

Let’s have a look at an example interface for use with Refit.

public interface IBeerServiceAPI`
{
    [Get("/beer/")]
    Task GetBeers();
}

We use attributes to define the request type as well as its path (relative to the HTTPClients base URL).

We then define what we expect back from the API and leave Refit to handle making the call, deserialising the response and handing it back to us as a concrete type.

To expand on this, we can add many more types of requests.

[Get("/beer/{id}/")]
Task GetBeerById(string id);

[Post("/beer/")]
Task CreateBeer([Body] Beer beer);

[Delete("/beer/{id}/")]
Task DeleteBeer(string id);

[Put("/beer/{id}/")]
Task UpdateBeer(string id, [Body] Beer beer);

We can now use the interface to make calls to our remote endpoint. I usually place these methods within a class that is unique to the service I’m calling. I’m this example; it’d be a “BeersService.”

//Create new beer item
public async Task<Beer> CreateBeerAsync(Beer beer)
 {
    var apiInstance = RestService.For<IBeerServiceAPI>(Helpers.Constants.BaseUrl);
    return await apiInstance.CreateBeer(beer);
}

//Get by ID
public async Task<Beer> GetBeerByIdAsync(string id)
{
    var apiInstance = RestService.For<IBeerServiceAPI>(Helpers.Constants.BaseUrl);
    return await apiInstance.GetBeerById(id);
}

That’s all it takes for us to starts interacting with a remote API. If you’re wondering how to test this, it’s incredibly easy to swap out implementations with mock services when using this architecture!

Resiliency

Building a resilient networking service requires a few things. We need to understand what our current connectivity looks like, as well as find a solution for caching data locally to ensure our app still ‘works’ in offline situations.

We can achieve both of these tasks by leveraging packages from Motz. He’s created a plugin for checking connectivity status as well as developed a library for caching.

Lets first take a look at connectivity status.

You’ll want to add the Connectivity Plugin nuget package to every client project in the solution as well as the PCL. The following platforms are supported:

  • Xamarin.iOS
  • tvOS (Xamarin)
  • Xamarin.Android
  • Windows 10 UWP
  • Xamarin.Mac
  • .NET 4.5/WPF
  • .NET Core
  • Samsung Tizen

To use the connectivity plugin, we can simple make the following call:

var isConnected = CrossConnectivity.Current.IsConnected;

Caching

Now that we can check for connectivity, we detect that we’re offline. Let’s have a look at how to implement that.

public async Task<List<Beer>> GetBeersAsync()
{
    Handle online/offline scenario
    if (!CrossConnectivity.Current.IsConnected)
    {
        //If no connectivity, we need to fail... :(
        throw new Exception("No connectivity");
    }
    //Create an instance of the Refit RestService for the beer interface.
    var apiInstance = RestService.For<IBeerServiceAPI>(Helpers.Constants.BaseUrl);
    var beers = await apiInstance.GetBeers());

    return beers;
}

Returning no results for most requests isn’t a great solution. We can dramatically improve the user experience by keeping a cache of data to show in offline situations. To implement that, we’re going to use Monkey Cache. To use Monkey Cache, we have to first configure the ApplicationId.  A folder created for your app on disk with the ApplicationId, so you should avoid changing it.

Barrel.ApplicationId = "your_unique_name_here";

Adding Monkey Cache is super simple. First, of, we want to define a key. Think of this as the collection (barrel) name. After that, we implement the necessary logic to handle caching.

public async Task<List<Beer>> GetBeersAsync()
{
    var key = "Beers";

    Handle online/offline scenario
    if (!CrossConnectivity.Current.IsConnected && Barrel.Current.Exists(key))
    {
        //If no connectivity, we'll return the cached beers list.
        return Barrel.Current.Get<List<Beer>>(key);
    }

    //If the data isn't too old, we'll go ahead and return it rather than call the backend again.
    if (!Barrel.Current.IsExpired(key) && Barrel.Current.Exists(key))
    {
        return Barrel.Current.Get<List<Beer>>(key);
    }            

    //Create an instance of the Refit RestService for the beer interface.
    var apiInstance = RestService.For<IBeerServiceAPI>(Helpers.Constants.BaseUrl);
    var beers = await apiInstance.GetBeers());

    //Save beers into the cache
    Barrel.Current.Add(key: key, data: beers, expireIn: TimeSpan.FromHours(5));

    return beers;
}

Polly

Returning to Rob’s original post, we’ll want to add Polly. Polly helps us handle network requests sanely. It allows us to retry, and process failures robustly.

We’re going to use Polly to define a retry logic that forces the service to retry five times, each time waiting twice as long as before.

public async Task<List<Beer>> GetBeersAsync()
{
    var key = "Beers";

    Handle online/offline scenario
    if (!CrossConnectivity.Current.IsConnected && Barrel.Current.Exists(key))
    {
        //If no connectivity, we'll return the cached beers list.
        return Barrel.Current.Get<List<Beer>>(key);
    }

    //If the data isn't too old, we'll go ahead and return it rather than call the backend again.
    if (!Barrel.Current.IsExpired(key) && Barrel.Current.Exists(key))
    {
        return Barrel.Current.Get<List<Beer>>(key);
    }            

    //Create an instance of the Refit RestService for the beer interface.
    var apiInstance = RestService.For<IBeerServiceAPI>(Helpers.Constants.BaseUrl);

    //Use Polly to handle retrying (helps with bad connectivity) 
    var beers = await Policy
        .Handle<WebException>()
        .Or<HttpRequestException>()
        .Or<TimeoutException>()
        .WaitAndRetryAsync
        (
            retryCount: 5,
            sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
        ).ExecuteAsync(async () => await apiInstance.GetBeers());


    //Save beers into the cache
    Barrel.Current.Add(key: key, data: beers, expireIn: TimeSpan.FromSeconds(5));

    return beers;
}

Wrapping Up

This is a great way to implement your networking layer within your apps as it can sit within a .NET Standard library and be used in all your client apps.

If you’d like to see a more real-world example of this approach, then check out the Mobile Cloud Workshop I created with Robin-Manuel. The Xamarin.Forms app uses this approach and, it’s been working very well for us!

Big thanks to Rob for the original post and documenting such a simple solution to complex problem!

How to fix the IPv4 loopback interface: port already in use error.

Super quick post here. Sometimes when debugging your .NET Core application on Mac, you’ll find the port won’t free up, and thus you can’t redeploy without getting the following fatal error:

Unable to start Kestrel. System.IO.IOException: Failed to bind to address http://localhost:5000 on the IPv4 loopback interface: port already in use.

To fix this, you’ll need to fire up Terminal and enter the following:

sudo lsof -i :5000

In my case, this outputted the following:

Screen Shot 2017-10-20 at 18.54.54.png

I know the error is referencing the IPv4 Type which allows me to quickly find the PID number, which I’ll use to kill the connection. I do this with the following command

kill -9 18057

With that done, I can now get back to debugging my .NET Core web API on macOS.

Stretchy UITableView Headers with Xamarin

The Yahoo News Digest app includes a couple of interesting user interface elements that I wanted to use within my own apps. The feature that I was most keen to recreate was the stretching UITableViewHeader. Its an effect seen in lots of iOS (sometimes referred to as a parallax header). As Beer Drinkin is going to support multi-tasking on iOS, I needed to ensure my implementation continues to support Storyboards and Auto Layout. Fortunately it proved very simple to get everything setup. In this blog post I’ll be sharing how I went about implementing it

beerdrinkinStretchy

Setting up the Storyboard

Adding a header view

To get started I opened my existing Storyboard and selected the UIViewController that requires the tableview header. In my case the scene (or view controller) isn’t a UITableViewController because I require a floating ‘Check in’ button to be visible at all times. Its worth noting that all the steps in the tutorial work with both UITableViewControllers and UIViewControllers.

Screen Shot 2016-02-01 at 11.36.06

Once I had the storyboard loaded, I dragged a UIView from the toolbox and made sure to insert it above the UITableViewCells as a the header view for the table. I then added a UIImageView to the new UIView and set its constraints to be 0,0,0,0. This way when the parent view (the UIView) resizes, the UIImageView will resize as well. I also made sure to set the UIImageView view mode property to Aspect Fit, which makes sure the image looks great no matter what size the view.

Screen Shot 2016-02-01 at 11.39.13

Adding some C#

Adding the resize code

If I were to have run this now, the table header would be displayed but wouldn’t resize with scroll events. To add scaling, I needed to add a code into my ViewController to setup the stretchy goodness that I wanted.

Because I use the header views height in a number of locations throughout the beer description view controller, I went ahead and created a variable rather than scattering magic numbers over my class.

[sourcecode language=”csharp”]
private nfloat headerViewHeight = 200;
[/sourcecode]

Managing the header view

To allow me to manage the table header, I needed to remove it from the UITableView and keep it as a variable for use later. To do this I created a variable in the beer description view controller.

[sourcecode language=”csharp”]
private UIView headerView;
[/sourcecode]

When we load the view controller, we’ll want to set our headerView variable and then set the UITableViews header property to null. This means the tableview has no header view to manage anymore, instead I’ve taken control of the view which allows me to ensure it resizes correctly as the table view scrolls.Despite having just removed the header view from the UITableView, I actually want to go ahead and add it to the table view hierarchy (but not as the header view property of the UITableView)

[sourcecode langauge =”csharp”]
headerView = tableView.TableHeaderView;
tableView.TableHeaderView = null;
tableView.AddSubview (headerView);
tableView.ContentInset = new UIEdgeInsets (headerViewHeight, 0, 0, 0);
tableView.BackgroundColor = UIColor.Clear;
[/sourcecode]

Listening to TableViewDidScroll

In order to successfully respond to the DidScroll event of the UITableViewSource, I’ll need to create an event in the table views delegate. This is because of an issue with the UITableView DidScroll event not firing when a delegate has been set.

[sourcecode language=”csharp”]
public override void Scrolled (UIScrollView scrollView)
{
DidScroll ();
}

public event DidScrollEventHandler DidScroll;
[/sourcecode]

We can now hook up the table DidScroll event with a small piece of logic for resizing the view.

[sourcecode language=”csharp”]
//Update Tableview
tableView.Source = new BeerDescriptionDataSource(ref cells);
var deleg = new DescriptionDelegate (ref cells);
deleg.DidScroll += UpdateHeaderView;
tableView.Delegate = deleg;

tableView.ReloadData ();
View.SetNeedsDisplay ();
//…
void UpdateHeaderView ()
{
var headerRect = new CGRect (0, -headerViewHeight, tableView.Frame.Width, headerViewHeight);
if (tableView.ContentOffset.Y &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; -headerViewHeight)
{
headerRect.Location = new CGPoint (headerRect.Location.X, tableView.ContentOffset.Y);
headerRect.Size = new CGSize (headerRect.Size.Width, -tableView.ContentOffset.Y);
}
headerView.Frame = headerRect;
}
[/sourcecode]

Conclusion

Its very easy to use this approach to add resizing animations to any number of controls within your UITableView. My favourite part of this solution is that it works perfectly across all iOS devices and doesn’t force me to drop support of Autolayout.

Find your users gender without asking

The app I’m working on in my spare time (BeerDrinkin) requires a modest amount of user data to in the future provide the best possible suggestions for new beers the user might like to try. Part of building a great model of my users is knowing thier gender.

When a user authenticates within BeerDrinkin using Facebook, I can simply parse the returned information and add the users gender to my database. Unfortunately, not all social authentication providers were born equal. With the recent addition of Google Auth, which I added to allow my father (who isn’t even sure what Facebook is) to use my app, I was unable to get the users gender.

Its for this reason that I’ve created a library that allows me to query Genderize. Genderize is a restful service which allows me to determine the gender of a user based on only a first name. It offers a free tier which includes the ability to query 1000 names a day which is more than enough for my requirements. If I find myself hitting the limit I’ll firstly buy a bottle of champagne to celebrate high user adoption and to drink away the thoughts of my Azure bill. On a serious note, Genderize provide the option to upgrade the account plan for a nominal fee to 100,000 users a month.

Given that BeerDrinkin does some sneaky UX to make a Facebook auth more likely (I delay showing the Google sign-in button for a few seconds so the user intially is confronted with only 1 option. Its very subtle but seems to help push Facebook as the prefered option), the free teir should be perfect for me.

Creating a PCL to interact with Genderize

To get started I headed over to the Genderize’s documentation to see what response I should expect back when querying the service. It’s actually increbily easy to use this service so much so that the entire PCL consists of no more than 100 lines of code.

Sample JSON response

[sourcecode language=”xml”]
{
“name”:“peter”,
“gender”:“male”,
“probability”:“0.99”,
“count”:796
}
[/sourcecode]

Corresponding C# model

[sourcecode language=”csharp”]

public class Response
{
private string gender { get; set; }

[JsonProperty(“name”)]
public string Name { get; set; }

[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

[JsonProperty(“probability”)]
public string Probability { get; set; }

[JsonProperty(“count”)]
public int Count { get; set; }
}

public enum Gender
{
Male,
Female,
None,
}
[/sourcecode]

One thing to note is that I’m using Json.NET’s JsonConverter to deal with converting from a string gender to an enum. This is just one of the many featuress of Json.NET that make it a pleasure to use.

Genderize Client Code

[sourcecode language =”csharp”]

public class Client
{
public Client()
{
}

public async Task GenderizeSingleName(string name)
{
if (_client == null)
_client = new HttpClient();

Response model;

var url = string.Format(“http://api.genderize.io/?name={0}”, name);
var response = await _client.GetAsync(url);

var jsonString = response.Content.ReadAsStringAsync();
jsonString.Wait();
model = JsonConvert.DeserializeObject(jsonString.Result);

return model;
}

HttpClient _client;
}
[/sourcecode]

As always, its open source

If you want to use the library, you can go ahead and grab a copy from my GitHub page. Once I get home from Australia I’ll add more features and publish to Nuget.

 

Cross-Platform Desktop UIs with C#

xplatDesktop

I’ve spent the last 4 weeks traveling Europe for the Xamarin European roadshow, and have had the opportunity to meet a few thousand C# developers who share a passion for cross-platform development.

In almost every city, I’ve been asked to recommend a Xamarin.Forms style library for developing desktop applications. In this blog post I’m going to give an overview of the different options available to desktop developers who wish to target Windows, Mac and Linux.

Traditional Approach

The first approach is what we’ve named at Xamarin the ‘traditional’ approach. You’ve probably seen this approach, but for mobile. The general idea is that you should implement your user interface uniquely for each platform you wish to target. This means on Mac, you would use Cocoa (Xamarin.Mac), Windows would use WPF and Linux would use Gtk (Gtk#). This approach will guarantee that your desktop application looks and behaves as the platform users expect. It also means that your application looks great if Apple, Microsoft or the OpenSource community decide to update the look and feel of the underlying OS. It’s also worth noting that with this approach you gain 100% access to every UI control and API available in the UI libraries, and won’t be limited in your ability to create beautiful experiences for your users.

In case you’re in any doubt, this is the approach I recommend you take when developing your apps. This is actually the approach Xamarin has started to use for our new products. You can see this in action with our Profiler and Android Simulator; both of these use WPF on Windows, and Xamarin.Mac (Cocoa) on OS X.

XWT

Much like Xamarin.Forms, Xwt allows you to use one API that maps to the native widgets of the platform. This means your application when running on Windows will be using WPF widgets, on Mac its Cocoa, and Linux is Gtk. This results in a 100% native user interface on three platforms from one codebase. Much like Xamarin.Forms, because its aim is to create a unified API for all desktop platforms, it only maps to a subset of widgets and properties. It’s worth noting that with Xwt you still have the ability to implement a native widget which isn’t mapped as part of the API.

For all platforms you can use the native engine, or the Gtk engine. If you’re wondering what a Gtk app looks like on Windows and Mac, then I recommend downloading Xamarin Studio. This is primarily built using Gtk, and in areas actually uses Xwt. On Windows the native engine is WPF, on OS X its Cocoa, and on Linux it remains Gtk (using Gtk#).

Webview

One other option you might want to consider, is using a WebView for your user interface whilst maintaining a C# backend. This is the approach that Rdio has taken for their OS X client, and to a novice it’s difficult to spot that it’s not a native app. This approach can produce some great looking applications which can even run in the Cloud, but it would be difficult to claim you’ve created an application when the reality is you’ve packaged up a website.

QtSharp

Although this approach is not yet ready for consumption, I thought I would mention it as it’s a project on GitHub that excites me. Much like Xamarin.Mac is a binding to the Cocoa framework, a group of enterprising .Net developers are aiming to create a .Net binding to the Qt library. Having used Qt in a previous life, I can confirm that the UIs can often be a little hit or miss (because it’s a lowest common denominator approach). That said, if you’re developing an internal application, or willing to take the time to craft the UI for each platform (different layouts for each platform) then it can work really well.

The project is still in its infancy, and many developers have tried and failed at this approach. Its not ready for production as yet (it doesn’t appear to even be close) but its a great start. My fingers are crossed that the developers continue to invest their time in the project, and the .Net community gains access to one of the most widely used cross-platform user interfaces frameworks in existence.

Renaming your Xamarin.Mac App

Apple has a number of guidelines and rules for developers looking to publish their Apps to Apple’s app ecosystem. One of these rules relates to the name of your app. To give you a quick overview of how some developers can have issues with theses rules, I’ve gone ahead and listed a few of them below:

  • Apps with names, descriptions, screenshots, or previews that are not relevant to the content and functionality of the App will be rejected.
  • App names in iTunes Connect and as displayed on a device should be similar, so as to not cause confusion
  • Apps that misspell Apple product names in their App name (i.e., GPS for Iphone, iTunz) will be rejected.

If your App has any of the following issues then Apple will reject your binary and ask you to change the app name. In this tutorial, I will show you the properties you need to change your app name.

Menubar & About dialog

To update the name in the Finder menu bar and the About dialog, you will need to update the Bundle Name which can be found in your projects Info.plist (you will need to select the ‘Source’ tab).

xamMacRenameInfo

Dock

To update the name displayed in the Dock (on hovering over the app icon), you will need to change the “Assembly name.” To do this, you will need to navigate to the project options (right click the project and select “Options”). You will find the Assembly name property under the “Output” tab.

xamMacProperties

Installer Package

If you’re producing an installer package for your App, you will need to edit the project name in order for the generated package to have your new name. To do this, simply right click on the project and select “Rename”.