Uncategorized

Creating & managing dev, staging and live versions of your Xamarin app

Posted on Updated on

When creating apps of moderate complexity in a team of several members including developers, designers, QA etc. it quickly becomes apparent that having a single version of an app with a single version of each dependent service doesn’t really work.

Today I’m going to share how we’ve dealt with this at JustGiving by creating 3 separate versions of our app. I’ll also show you how we manage this through source control and our continuous deployment system to be able to give everybody in the team ready access to these different versions, each with their own level of expectations around them.

cropped

 

There are two distinct parts to provisioning an app for various environments: 1) compiled configuration settings and 2) managing the iOS info.plist file. Managing compiled configuration settings will be the more familiar solution to regular .NET developers as this will only involve a simple combination of dependency injection and compiler flags. Managing the info.plist is a little more tricky as we’re going to use conventions of the iOS compilation process itself.

Compiled configuration settings

Any moderately complex app will inevitably connect to a variety of third party services for functions like analytics & crash reporting, push notifications, social sharing etc. Most if not all of these providers will have at least Staging and Live equivalents explicitly, or you can create your own (for example having multiple Facebook Apps for staging/live for Login With Facebook functionality). The main dependency that the JustGiving app has is of course the JustGiving Public API, for which we have Development, Staging and Live versions.

Using a simple combination of dependency injection and compilation symbols, we can easily manage a distinct set of configuration settings for each of our development, staging and live app environments.

First, we edit our configuration options of the iOS project to reflect our 3 environments, as depicted in this screenshot:

Solution Configuration Options
Xamarin Studio – Solution Configuration Options

This will allow us to compile the app in local development version (DEBUG), a staging version (RELEASE) and a live version (APPSTORE). You can effectively name these options whatever you like.

Next, we have to have a set of configuration settings that our dependency injection framework can bind differently based on those compilation symbols.

public interface IConfigurationSettings
{
string ThirdPartyApiKey {get;}
string AnotherThirdPartyApiKey { get; }
}

public class DebugConfigurationSettings : IConfigurationSettings
{
public string ThirdPartyApiKey { get; protected set;}
public string AnotherThirdPartyApiKey { get; protected set; }

public DebugConfigurationSettings ()
{
ThirdPartyApiKey = "debugKey";
AnotherThirdPartyApiKey = "otherDebugKey";
}
}

public class ReleaseConfigurationSettings : IConfigurationSettings
{
public string ThirdPartyApiKey { get; protected set;}
public string AnotherThirdPartyApiKey { get; protected set; }

public ReleaseConfigurationSettings ()
{
ThirdPartyApiKey = "stagingKey";
AnotherThirdPartyApiKey = "otherStagingKey";
}
}

public class AppStoreConfigurationSettings : IConfigurationSettings
{
public string ThirdPartyApiKey { get; protected set;}
public string AnotherThirdPartyApiKey { get; protected set; }

public AppStoreConfigurationSettings()
{
ThirdParyApiKey = "liveKey";
AnotherThirdParyApiKey = "otherLiveKey";
}
}

Now, deep in the setup code of the app, we have the following code to bind a different concrete implementation of our ConfigurationSettings class to our interface IConfigurationSettings, based on the relevant compilation symbol. Note that we are using MvvmCross, and so are using it’s own dependency injection framework, but the concept is the same regardless of what DI framework you will be using.

 #if DEBUG
 Mvx.LazyConstructAndRegisterSingleton<IConfigurationSettings, LocalDebugConfigurationSettings>();
 #elif RELEASE
 Mvx.LazyConstructAndRegisterSingleton<IConfigurationSettings, TestFlightReleaseConfigurationSettings>();
 #elif APPSTORE
 Mvx.LazyConstructAndRegisterSingleton<IConfigurationSettings, AppStoreConfigurationSettings>();
 #endif

So that sorts the configuration settings side of things out. Now let’s delve into the info.plist.

The iOS info.plist file can be thought of by .NET web developers as the equivalent of web.config. All manner of iOS-relevant configuration options appear in the info.plist including version information, supported orientations, iOS versions, the names of your image asset catalogues, etc. Additionally, some iOS 3rd party libraries require that you include certain values in this file (for example the Facebook SDK requires your Facebook App ID).

We originally had one info.plist file, and then our Jenkins build server would use plistbuddy to change individual values (like the Facebook App ID’s above) at build time depending on the environment being built for. However this meant the values were being stored by Jenkins rather than source control with everything else, and that felt rather opaque to the developers and not easy to lookup or quickly change.

We quickly refactored to simply having multiple versions of the info.plist file, one for each environment.

An info.plist for every environment
An info.plist for every environment

As with the compiled configuration settings before, this now allows you to easily manage 3 completely distinct build-time configuration option sets. A few of the more useful info.plist properties to differentiate between environments are:

CFBundleVersion
We have ‘Development’ or the Jenkins build number here. This appears in the Settings screen of the app, which means any team members (or indeed users) unsure of the version on which they’re on can quickly look it up.

CFBundleIdentifier
Things can get messy if you don’t vary the BundleId, which you can think of as the main identifier of your app. Many user-facing functions depend on BundleIds being congruent across services. For example, our Azure Mobile Services staging app for push notifications is provisioned with a APNS ‘Test’ certificate generated for an app with a BundleId of ‘com.justgiving.app.staging’. This same BundleId appears in our (staging) Facebook App iOS settings as well. As iOS devices can only have a single version of a single app (as identified by the BundleId) installed at once, having a different BundleId for each environment also allows users to have all 3 versions on their devices at the same time.

XSAppIconAssets
Using Asset Catalogues became the preferred way to manage and ship your assets from iOS 7 onwards. The good news is that if you’re doing it this way, it is easy relatively easy to vary your app icons by environments. This is obviously very useful to those members of your team likely to have multiple versions of the app on their phones at any one time!

We have a separate App icon asset catalogue for each environment:

An Asset Catalog per environment
An Asset Catalog per environment

And then the relevant value in each info.plist file:

Dev environment info.plist

This results in our beautifully illustrative and differing app icons:

App per environment

The final question is, how do we use these different info.plist files? Well, Jenkins (app ‘Release’ build job) simply deletes the info.plist on disk (which is the development version) and renames the ‘Info.Release.plist’ to ‘Info.plist’ prior to compiling the app as normal. Similarly, a step in the ‘AppStore’ Jenkins job renames ‘Info.AppStore.plist’ to ‘Info.plist’.

Jenkins renames the relevant info.plist files
Jenkins renames the relevant info.plist files

Simple but effective!

Keeping separate apps for each of your environments not only avoids confusion when your internal users are using your app, but also allows solid and predictable testing for your QA team and allows you to diagnose issues with more confidence. Using the two tricks described above, you can achieve this variance effortlessly and be on your way to further scaling up your app development!

Mark
Lead Developer, Mobile Platforms
JustGiving – The world’s social platform for giving

Advertisements

My 60 second review of QConLondon 2015.

Posted on Updated on

I was fortunate enough to attend QCon London 2015 last week, and so I present my 60 second review.

Observations:

1. THE WHOLE WORLD HAS GONE MICROSERVICE MAD!

I guess this speaks to the success people are having with microservices, but MS-talk was all over this QCon. In fact, too much so. There was a lot of duplicate knowledge presented in talks, and by the end of it I was a little tired of it all.

2. New meme: Binary protocols, and protocol design.

With the explosion of microservices in-house, focus naturally comes to performance issues around TCP/HTTP/JSON etc. Many folks are dropping down to lower level, sometimes custom-written, protocols, eg. tchannel on Thrift at Uber.

3. Oh Node Where Art Thou?

For all it’s popularity, Node.js was pretty absent and if mentioned, only in dispatches, I would’ve liked to see more node-love.

4. Potential new meme: Actor-model. Some people seem to be attacking concurrency using the Actor model or “actor-based concurrency” (eg. Halo4 built on Azure using Orleans). I will be reading up more on this!

Overall, I was glad I was there, but I don’t think the talk curatorship was as good as previous years, and I would hesitate if using my own money to buy conference ticket! (I helped out as crew, which I have done for several years, and so get a free pass).

I will though of course be back next year!

Videos of talks will be released over time here:

http://www.infoq.com/conferences/qconlondon2015

Blog’s 2013 in Review

Posted on

Not many chances to create a post with one click – so here is my ‘WordPress Year in Review’!

——–

The WordPress.com stats helper monkeys prepared a 2013 annual report for this blog.

Here’s an excerpt:

A San Francisco cable car holds 60 people. This blog was viewed about 1,300 times in 2013. If it were a cable car, it would take about 22 trips to carry that many people.

Click here to see the complete report.

Book Review: REMOTE: Office Not Required

Posted on

REMOTE: Office Not Required is the new book from successful software outfit 37Signals, authors of REWORK which I enjoyed immensely as it chimed with my own love of calling bullshit on the ‘norms’ of contemporary office & work culture. I was keenly awaiting the publication of REMOTE since Jason’s TED Talk on the same topic resonated with me greatly. I suspect many developers can sympathise with the notion of being constantly interrupted at work, sometimes in a good way by that hot girl/guy in HR, or sometimes in the most annoying way by a Project Manager wanting to know when it’ll be done. Either way, several of these interruptions spaced over the course of the day are all that is required to destroy flow-time and thus really retard productivity. Jason’s premise in the talk is that the modern office is just not the place where work is done anymore, especially if you are a ‘creative’ (includes designers, authors, journalists, and of course, software developers), and I have to broadly agree.

REMOTE: Office Not Required is a more in-depth exploration of remote working being a way to reclaim productivity by working in an environment that you fully control. Most of the book seems to focus on the increased happiness of the employee. While a lot of this was obvious (who wouldn’t want to skip the commute?) it did nonetheless open my mind even wider to what is available when your workplace offers very flexible remote working. My newest experimental idea is to travel for a long weekend to another city, but leave on the say the Wednesday night and work in a co-working space for Thursday and Friday, exploring the city by night on those days and on the weekend, and return on the following Tuesday. Cheaper transport as it’s off-peak, a long-weekend holiday and on top of that, no missing of work. Surely everyone wins! (Of course this probably only works for solo-trips, and there may be other constraints).

As a person who intensely hates wasting time, remote working is something I’m naturally attracted to. It saves 2 hours a day for me in not commuting. It also apparently makes me happier (see #3). A natural question that comes up when I discuss this with people is “How that extra time is spent – work or play”? Well to ask this question and other similar to this, is missing the point, and rather moot. They accept a clear time-dividing line between work and personal life as a basic first premise, which at least my life doesn’t apply. Why not conduct errands on a Thursday afternoon if you can complete that project on Sunday night for a few hours? As I do what I love and love what I do, the line between work and play has long since been blurred. In practice some workers may spend 2 hours of saved commute time on themselves always, on themselves sometimes, or on their work always. Point is, it’s 2 hours spent doing something you want to do instead of something you’re forced into. That’s got to be a good thing for employees and for employers that care about staff happiness. In a regular office where everyone is in 9-5, you’re still going to get people that perform better than others by using their time more wisely. The same is true for remote workers – you may want continue to structure your reward scheme such that people that produce more, even remotely, are rewarded more.

One of the more eye-opening chapters in the book is called “Morning remote, afternoon local” and speaks of one employee that spends each morning working from home, and comes into the office for the afternoon. I love this as it guarantees a minimum amount of flow-time and productivity every day, while also allowing you to catch up face-to-face with those you need to, and vice versa. I’ve tried this a couple of times and it does have the intended effect, but one side-effect is that it also means you’re commuting for 2 hours within 4 or 5 hours, and that felt like a lot of wasted time again! Definitely a net benefit though, as you can combine the commute & the lunch time break.

So all is good and well with remote working from the perspective of the employee, but I’ve also always been interested in what makes good companies perform well from a social and cultural perspective. What makes a good culture? What strengthens social capital? Some would say at least a little of this is serendipitous communication at work – “water cooler moments”. It seems likely that a 100% remote working company has challenges in these areas. REMOTE did not cover this a great deal, aside from a couple of notes about creating a “virtual water cooler” and suchlike. 37Signals is a company with the mostly remote employees, but also mostly tech-comfortable and ‘remote-ready’ employees: people that are not averse to hanging out in chatrooms. My company has over 100 employees, most with little remote experience and even fewer that are completely comfortable online. Added to that, we have a huge variety of roles and teams, and some I would suspect are not suited to remote working. How does the company manage the remoteness of some teams and not others? How do we manage the expectations of the non-remote teams when they need the help of remote workers? The book had few answers for these questions.

Another point that comes up in discussion is the fact that some people might abuse the trust placed in them as remote workers. This is true, and does happen, I’ve seen it. However, I also think that most often this degrading situation is not the fault of the remote worker, but rather of the employer/management. At best this person may not be sufficiently motivated because the work is boring or some other similar dysfunction and guess what, they’dbe just as demotivated at the office than they are at work (and thus, just as unproductive). And at worst, this person isn’t self-managed enough to respond to remote working and you’ve made a hiring mistake, which by the way would also play out similarly if the person had to come in every day. So you see, blaming remote working is just a cop-out for managers that don’t really understand how to manage true productivity (ie. work outcomes) and employee motivation.

Ultimately, on finishing the book, I realised that the book I wanted to read was not really a variety of anecdotes from an entrepreneur who set up his still <50 employee business over 10+ years from the get-go to be remote, but rather an in-depth expose’ of the high performance, 200+ employee frequently-shipping, distributed, software-delivery-machine that is Github (or perhaps Facebook – not sure what proportion of FB is remote). These are the companies that I want to start modelling my company on, and I suspect they have many more remote working learnings to supply than 37Signals. However this book will help win the PR war, and help to reposition remote working as an accepted, and eventually expected, practice.

I’m on to reading another book that talks about remote working – The Year Without Pants is Scott Berkun talking about his experiences coming in from the consulting world into a real company, Automattic, the WordPress.com company. Scott’s perspective is a more accurate proxy of my own devil’s advocate position on remote working and progressive company cultures in general, and I’m interested to see how he adjusts, given that the major portion of his working experience is from late 90’s Microsoft! 

Knockout Kickstart

Posted on Updated on

A few weeks ago I waded into KnockoutJS, using it for a simple CRUD screen at work. In short it was a really good experience and I was amazed at how little javascript I had to write to get everything going. I’m looking forward to combining Knockout with other JS frameworks to enable more complex scenarios with as little effort.

However looking for tutorials and example code online, I found some resources that weren’t that good, and then looked some more and found some better stuff. I did find that it took a bit of effort to find decent learning materials – there is a fair amount of confusing and sporadic KnockoutJS content around – so I thought I’d blog what ended up being the most helpful content, in order to save you the hassle. So if you’re wanting to get going, consider the following resources above others.

First, definitely go through the tutorial at Learn Knockout. This covers the basics and leads you to the official documentation that will serve as a great reference to the various building blocks you’ll need to refer back to (and copy code from!) when building your page/site. By the time you finish the tutorial you’ll understand the basic structure of a Knockout page, and the steps involved in building the necessary parts.

Second, definitely view Steve Michelotti’s excellent PluralSight tutorial “Knockout Fundamentals“. I actually watched the TekPub Knockout screencast first but found this didn’t actually cover the fundamentals as well as required to actually build a non-trivial page. It covered Knockout in an ad-hoc manner, missing some key pieces around handling arrays, rather than the logical and cumulative treatment (building up a big app over several videos) that Steve’s video provides. Steve’s course covers all the basics systematically, so you will cover everything you need to build a proper page. The Pluralsight course also ends up with more sophisticated app than the one in TekPub, stretching your KnockoutJS knowledge further on completion.  If you are not a subscriber to PluralSight, I would heartily recommend signing up (lots of great content) but failing that, the trial will give you free access to your first 200 minutes, which will cover the 1h40m KO course.

Just these two resources should be enough to get your first Knockout page/site built, but once you start hitting those edge cases and yearning for some advanced features, the following posts helped round out my Knockout knowledge even further:

Ryan Niemayer’s blog is generally pretty good, but here are two articles that are worth reading first:

Hope that helps! Next up I am going to discover how DurandalJS builds on top of KnockoutJS to make developing SPAs even easier!

 

Finding a new developer job in London

Posted on Updated on

As transparency seems to be the new black (I’ve read quite a few posts on HN recently about people fully documenting their earnings, for example), I thought I’d blog about finding a new developer job in London. Nothing too exciting but visiting various shops, comparing interview processes, and working with recruiters is always…entertaining.

Firstly, here’s a quick run down of the places I visited and some notes of my experience/observations (WordPress table editing is not so good, so excuse the rudimentary layout)

Company (type) Source Interview Stages Date Outcome Notes / Observations
Digital Agency in Croydon StackOverflow 1st (Face2Face) 7th Nov No callback First interview! This one was all about getting experience (I would probably never work in Croydon…); Had to hack a to-do list together in 20 mins. Unpracticed at Razor so this probably took longer than it should’ve! Good guys but company not really progressive enough in terms of technology
Shrink-wrapped Accountancy software in Charing Cross Jobserve (urgh) 1st (online test); 2nd (30 min phone interview) 9th Nov Not taken forward (by me) Online test was C#/CLR trivia galore (got 64% doh); phone interview was 3 guys asking some random questions, not very coherent. Not the best interview process in the world but no loss as unlikely that I’d work in something as exciting as accountancy!
Shoreditch Music industry startup StackOverflow 1st (pair programming f2f interview) 12th Nov No callback This was intimidating as I had/have these guys on a pedestal, especially the Director of Engineering who is active in the community and has seemingly done an amazing job using progressive ideas to create a successful engineering outfit. Consequently stuffed the interview up, howlers include trying to mock a concrete class with Moq and not pointing out mutability as problematic. At least I learned about the Chain-of-Responsibility pattern and was able to show them FluentAssertions. All is not lost!
Big City Management Consultancy StackOverflow 1st (30 mins HR phone interview) 15 Nov Not taken forward by them Pictured myself wearing suits everyday and going from client site to client site hacking in fixes in a tech debt creation frenzy (am I being harsh on city tech?). Interview went well but in the end I was “not a match for their requirements”, most likely because I said I wasn’t going to do any Java…
Charity platform Recruiter 1st (Online test); 2nd (f2f w/ CTO); 3rd (f2f w/ Architect & Technical Manager) 19 – 23 Nov Offer Accepted Great looking company that looks after its people and is technology-focused; liked the people I met in the interview – enthused, passionate, skilled, etc. High retension, always a good sign. Good tech stack, office space, progressive culture etc etc. Job done!

Some key observations and takeaways from the whole process:

  • Recruiters are the usual annoying and manipulative lot but actually finding a decent one is possible and can make a big difference.
  • Overall though, I’d definitely start with the StackOverflow job boards (avoid Jobserve like the plague!) where you can find lots of decent companies and also do THEM a favour, as if you’re recruited through SO their costs are lowered by around 7k-10k per role in recruiting fees. I did note that SO is slowly starting to “jump the shark” though, carrying ads from Big Consultancy Inc who aren’t really doing interesting things with tech. Along with SO who will feature most of the bigger, more established outfits, also be very sure to pay SiliconMilkRoundabout a visit at one of their twice-yearly shindigs, where there are many much smaller but very exciting companies who are looking for adventurous types to join their cutting edge startups. If working on something interesting and novel is high on your list, SMR is a must.
  • Another observation I made was the presence of huge variance in interview techniques and processes. In my opinion it turns out that the places you would rather work tend to avoid online tests of the multiple-choice questionnaire type, and have some element of your own code, whether that is pair programming at the interview or submitting your solution to their problem question over email. In my own hiring I have had the most success with:
    • 1st stage: CV screening that I do, screening on modern tech (ORMS, IoC, TDD etc) and passion for the craft (OSS/blogs/twitter/etc)
    • 2nd stage: 45 min phone interview going over technical basics (including questions like “What problem does IoC solve?”) and some recent work experience; If successful I give email a programming challenge and ask them to submit a project that solves it.
    • 3rd stage: 2 part face-to-face, 1st part soft-skills, 2nd part hard-skills where we talk about his/her code submission and possibly ask them to extend it in the interview.
  • Finally, the last observation I made was that it is seemingly quite a small world in the London tech scene! New hires in my old company were from places that invited me to interview, fellow colleagues from work were being submitted for some of the same jobs I was, some through the same recruiters, some through different recruiters, etc. Felt like a bit of a crowded space at times!

Anyway, my job is done as I’m now at a much better outfit than before, so hopefully I won’t have to traverse the recruitment maze again for a long while and I can get back to creating software and help building good teams. Hope you find this little anecdote interesting!

NBuilder Utility for Child Complex Types

Posted on Updated on

NBuilder is a tool for .NET that allows the easy creation of test objects. It provides new instances of any class you provide (as a generic parameter) and those instances are populated with garbage data. I find that using NBuilder for test objects is a nice explicit way to show that the test does not care about the data but just needs an object in a decent enough state not to produce NullReferenceExceptions.

So given:


public class ComplexType
{
    public string Name { get; set; }
    public int Number {get;set;}
}

You could have the following test:


[Test]
public void Should_Return_Instantiated_Object_With_Test_Values()
{
    var result = Builder<ComplexObject>.CreateNew().Build();
    result.Should().NotBeNull();
    result.Name.Should().Be("Name1");
    result.Number = 1;
}

By the way that was also using FluentAssertions.

However, even after a fair bit of Googling I’m not sure why it does not include the creation of child complex objects, recursively. Instead these end up as null. So given:


public class OuterComplexType
{
    public int Number { get; set; }
    public InnerComplexType InnerComplexType { get; set; }
}

public class InnerComplexType
{
    public string Name { get; set; }
}

The following test would fail:


[Test]
public void Should_Return_Instantiated_Object_When_Given_Object_With_Complex_Properties()
{
    var result = Builder<OuterComplexType>.CreateNew().Build();
    result.InnerComplexType.Should().NotBeNull();
    result.InnerComplexType.Name.Should().Be("Name1");
    result.Number = 1;
}

So I wrote a little utility class that helped with this situation (see the Gist here). I have not used it in anger very much yet, so let me know if you spot any potential improvements.

using System;
using System.Linq;

using FizzWare.NBuilder;

namespace MarkGibaud.UnitTest.Utilities
{
    public static class NBuilderUtility
    {
        public static T Create<T>()
        {
            return (T)Create(typeof(T));
        }

        private static object Create(Type type)
        {
            if (type.IsInterface)
            {
                var firstConcreteImplementation = type.Assembly.GetTypes().FirstOrDefault(t => type.IsAssignableFrom(t) && !t.IsInterface);
                if (firstConcreteImplementation != null)
                    type = firstConcreteImplementation;
                else
                    return null;
            }

            var baseType = Build(type) ?? Build(Nullable.GetUnderlyingType(type));

            var complexTypeProperties = baseType.GetType().GetProperties().Where(p => !p.PropertyType.Namespace.Contains("System")).ToList();

            if (!complexTypeProperties.Any())
            return baseType;

            foreach (var complexTypeProperty in complexTypeProperties)
                complexTypeProperty.SetValue(baseType, Create(complexTypeProperty.PropertyType), null);

            return baseType;
        }

        private static object Build(Type type)
        {
            var builderClassType = typeof(Builder<>);
            Type[] args = { type };
            var genericBuilderType = builderClassType.MakeGenericType(args);
            var builder = Activator.CreateInstance(genericBuilderType);
            var createNewMethodInfo = builder.GetType().GetMethod("CreateNew");
            var objectBuilder = createNewMethodInfo.Invoke(builder, null);
            var buildMethodInfo = objectBuilder.GetType().GetMethod("Build");
            return buildMethodInfo.Invoke(objectBuilder, null);
        }
    }
}

Usage is something like this:

[Test]
public void Should_Return_Instantiated_Object_When_Given_Object_With_ComplexType_Properties()
{
    var result = NBuilderUtility.Create<OuterComplexType>();
    result.InnerComplexType.Should().NotBeNull();
    result.InnerComplexType.Name.Should().Be("Name1");
    result.Number = 1;
}

I guess the next step is to integrate this functionality into a fork of the NBuilder project…I’ll save that for a rainy day.