My Life With a MacBook Pro – 3 Years In

Hmm  … where to start?

I had to buy a MacBook, I need to write and compile apps for iPhones and iPads.  I would have preferred to spend the extortionate cost for it on something else, like keeping it as inheritance for my kids or buy a house.  But well, my hand was forced by Apple.

I’d love to be able to say it’s been a pleasure to own but frankly it hasn’t.  I know it’s fine for the average user who wants to browse the web, send a few emails and “facetime” but trying to use it for my needs and it a pig frankly.  I’ve had more weird issues with this one laptop than I’ve had in previous 18 years of Windows based PC ownership, I’m not exaggerating.

It just works? If it “just works”, why the need for genius bars?

I’m a power user, a software engineer and I build desktop PCs and mission critical servers so I know stuff about hardware as well as software.  I just do not rate these machines.  They look pretty but my god when something goes wrong you end up in a mess.

Hardware Issues

Great hardware I hear people saying?  In these three years I’ve had to replace the power supply twice (£65 a pop – £195 on power supplies!!!).  I’ve never replaced a power supply on anything in my life, let alone a laptop.  I’ve also never had a port on a machine die.  This is a £2000 laptop and I’ve experienced both multiple times.

The first Thunderbolt port became less than reliable after the first 12 months, now this weekend the one that did work also suddenly stopped working.  Now to continue using my Ethernet network connection I have to purchase some more hardware just to keep using what has been a computer standard for decades – the RJ45 connector.

Add to those problems the completely unserviceable build methodology and it seems I’m slowly cruising towards owning a very expensive brick.

I’ve also got to make an appointment with the “genius bar” folks as this laptop is also afflicted with the screen coating issue Apple have issued a recall over.  Luckily my MacBook Pro doesn’t seem to have the issue with the video card (which also effects early 2013 MBP).

Remember, this is a PREMIUM £2000 laptop … I’m really not impressed to be honest.  Two major recalls (there may be more I don’t know about) on a product like this isn’t good.

Bluetooth has also been a constant source of hate for me.  For the majority of the time I have owned this laptop I couldn’t use the Magic Mouse & W-Fi at the same time.  The Magic Mouse, at the best of times, drops it’s connection for a hobby.  How dare I expect to use the mouse and internet at the same time!  But it doesn’t matter since I stopped using the Magic Mouse completely because it would make my Wi-Fi either painfully slow or not work at all.  So there’s another £59 pissed up the wall.

Software Issues

OSX is horrific.  I hate it.  I hate it’s design and I hate the way it operates.  Loads of things hidden in the UI until you press the option key is a usability disaster.  The finder is a joke of disk navigating tool.

When I first got my hands of OSX (Mavericks) I was literally blown away by what it couldn’t do out of the box.  Finding that I had to buy additional software tools to do proper window management was a joke.

But OSX doesn’t get viruses I hear everyone yelling.  Well, in the past 20 years I’ve had … lets see … 2 viruses on a PC that I had to deal with.  Both back when I was using Windows 98SE.  So shut up, this is moot issue.  If people will click on every link or dodgy web site they’re sent they should expect them to get viruses.  A bad workman always blames his tools …

Every time I’ve done an upgrade on the OS I’m left with crap to deal with.  Resetting the PRAM or SCM or both because some issue has crept into the system.  Either Wi-Fi not working or the Bluetooth connectivity going nuts.  For the longest time after the Yosemity update I couldn’t use my UEBoom at all as the audio was never in sync with the video.

One of the reasons Windows is so pervasive is backwards compatibility.  I had programs from 1995 that I can happily run on my Windows 10 box.  It seems with every update of OSX something stops working.  The classic example is Parallels.  They seem to capitalise on this fact with their marketing and will scare users into upgrading, even when their app will carry on working.  But for me Parallels 8 stopped working on El Capitan, so I switched to using VirtualBox (which is free).

All in all, I won’t be recommending Apple stuff anymore.  To those that I have recommended they get an Apple product, I apologise.  The problem is that now I’m an iOS developer I’ll always need a Mac around for code compilation duties.  But, no more MacBook for me, I’ll get a Mini and hide it away somewhere so I don’t have to look at it.

Crisp Retina displays on the MacBook are no compensation for the issues I have.  Particularly when the hardware is all glued together.  That fact renders this gadget as basically throw away tech.  £2000 throw away tech.  How Apple can boast of being green is beyond my comprehension.

As for developing software for the Apple platforms?  I’ll leave that to a future post as that is even worse than dealing with their hardware …

The one thing that Apple gets absolutely correct – marketing.


TeamCity – Sharing Build Properties

Sharing parameters and properties can be a bit confusing for new users of TeamCity.  Lets use a simple example to illustrate how you can do this.

For sake of this explanation lets say that you have two build configurations that are essentially building the same thing but for different distribution uses, the source code is the same which would result in the same revision or commit of the source repository etc.  The only material difference is maybe some certificates or binary labels or identifiers.

Another scenario might be to integrate with an external system for deployment like Octopus Deploy and you want to kick that off in its own build configuration. Due to this you want the two build configurations to have the same build number.

Lets say you have an application called MyApp with a Debug, Release and Deploy build configurations and you want the Deploy configuration to use the Release build number.

So, to do this:

  1. Navigate to the Release build configuration and note down the buildTypeId from the browser URL (for this example lets say this is webrelease).
  2. Navigate to the Deploy build configuration
  3. Click on Edit Configuration Settings, then Dependencies, then Add Snapshot Dependency
  4. In the dialog that pops up select the check-box that corresponds to the Release build configuration and set any other relevant settings
  5. You now have “linked” the two build configurations which means you can use the %dep.x% parameter notation
  6. Now in the case to set the build number we navigate to the General Settings on the same Deploy build configuration
  7. In the Build Number Format text box we can enter

Voila!  The next execution of the Deploy build configuration will have the same build number as the Release configuration.  Go nuts with your params!



Xamarin iOS TeamCity Build

So this turned into a complete nightmare for a while.

TeamCity Mac Agent Push Installation

I started by trying to get TeamCity to do a push install of a new agent on my MacBook Pro and very quickly things got very, very ugly.  First off it couldn’t find a JDK (which was installed) so I was using bash to update my ~/.bash_profile with the JAVA_HOME variable, but nothing seemed to work.  I fixed that by simply downloading the latest JDK release package and installing it.

Once the JDK errors and my /.bash_profile were fixed I then got the error (this is it in its entirety) “su: Sorry” … at that point I threw in the towel.  I’ve got better things to do that battle with this crap.  I abandoned the plan to push install the agent as I simply couldn’t figure out what was wrong with no information, the error text above was all that appeared in the agents log file as well so its  anyones guess as to what the problem really was.

NOTE: Make sure you can browse to the TeamCity site on your network using the agent machine

So I dialed into my TeamCity server, grabbed the zip installer and did it all manually.  This worked first time (after amending the buildAgent properties file) so what ever the issues were with the push installation I don’t know and frankly I don’t care, JetBrains have some tiding up to do both on this.

Build Steps

Since the build for the iOS application is now happening using Xamarin Studio installed on the Mac the build process is much simpler.  At the moment my unit tests are all run during debug builds only and these occur on a PC running another build agent.  I will revisit this to start executing test runs on the Mac agent to make for a more holistic testing process.

Updating Plist Files

There are a number of ways you can update the plist data on OSX.  Some people seem to suggest using the termainal DEFAULTS command but I found that didn’t work when presented with an iOS style Info.plist.  Chiefly it seemed to be confused by the internal layouts having arrays and a dict element.

By far the simplest way I found was making use of the standard OSX tool PlistBuddy which can deal with our iOS plist data.  So I added a new build step (executed before the compile step) and have configured it to allow me to update it’s internal version numbers and bundle identifiers based on the build configuration.

I normally use a 4 element version number for .NET (major).(minor).(build).(revision) which gives full traceability back to the source control for an individual release.  But if you use this in all cases you’ll have problems as iOS uses the semantic version number format (major).(minor).(build) for the “CFBundleShortVersionString” version number.

But you can also use arbitrary values in the “CFBundleVersion”.  Lots of people seem to ignore the AssemblyInformationalVersionAttribute in .NET but this is a great feature as you can use arbitrary strings as well as the more formal version format when using it in .NET assemblies.

<br />
$ /usr/libexec/PlistBuddy -c &quot;Set :CFBundleIndentifier (yourbundleid)&quot; Info.plist<br />
$ /usr/libexec/PlistBuddy -c &quot;Set :CFBundleShortVersionString %build.number%&quot; Info.plist<br />
$ /usr/libexec/PlistBuddy -c &quot;Set :CFBundleVersion %build.number%.%build.vcs.number%&quot; Info.plist<br />

Compile – Obsolete

The build step for compiling the iOS configuration is executed using a CommandLine build runner with a simple command like this:

<br />
/Applications/Xamarin\ build &quot;--configuration:Debug|iPhone&quot; /path/to/solution.sln<br />

Archiving Builds – Obsolete

Once the build is complete you’ll want to automatically create your archive. When you come to distribute your application to the App Store or to TestFlight via the XCode you’ll want to use xcarchive. You can use IPA files from the Build step with the Application Loader but as far as I can tell there is no way to upload dSYM files for any symbolicate processes which is a bit crazy (unless I’ve missed something)

Create another build step and use:

<br />
/Applications/Xamarin\ -v archive &quot;--configuration:Debug|iPhone&quot; /path/to/solution.sln<br />

This will place an xcarchive file into ~/Library/Developer/XCode/Archives/.  You can then validate this archive via XCode -> Window -> Organizer on the Archives panel.


So, it seems the recent versions of Xamarin Studio and the MDTOOL method of compiling and archiving have become problematic.  I started to see builds failing with some odd errors relating to my Droid project inside the build logs of the iOS builds.  Hugely confusing.  I never got to the bottom of why this was occurring and decided to review the whole process.  Both the compile and archive steps are now combined into one step and one command.  The command I’m now using is:

<br />
/Library/Frameworks/Mono.framework/Commands/xbuild /p:Configuration=AppStore /p:Platform=iPhone /p:BuildIpa=true /p:ArchiveOnBuild=true /target:Build /path/to/solution.sln<br />

Obviously you can change any of the configuration or platform parameters to suit your requirements / project setup.

As I work through the next steps of this process I’ll keep this blog post updated – you can read the Android version here.


Source Control – Learning Git

Over the years I’ve used many source control systems.  Most of them seemed pretty simple to use after a short period of time.  However they all have their idiosyncrasies that will occasionally catch you out and some of them have been next to useless at their intended purpose.

The worst of these systems I have had personal experience with was Visual SourceSafe from Microsoft, this shouldn’t be used by anyone, ever.  I’ve seen it do the only thing a source control system should never do – lose your work.  I must admit that all my experiences with Microsoft solutions for this particular task have been poor.  I’ve only had TFS inflicted on me once and that experience was extremely lumpy and I really never want to have it again.  Certainly after reading that at the core of TFS is a re-written Visual Source Safe, shudder.

There are many source control systems to choose from which can make it a bewildering decision to make.  They range in price from free to eye-wateringly expensive for “corporate solutions”.  Source control is source control, it either does it or it doesn’t, you can keep your bells and whistles thank you!  I haven’t had the opportunity to try any of those since I haven’t worked for a massive organisation that was ever prepared to spend that kind of cash – yes they really can be THAT expensive, think six figure sums of cold hard cash, just on source control.  Your product has to be worth millions before you’d even consider them.

Subversion Source Control

For the most time, including my home projects and business source control tasks I have been using Subversion, particularly SVNServer and TortoiseSVN.  Since these projects are a one developer affair the extra functionality of a distributed architecture for collaboration was never a consideration and since I was also already very familiar with the system this was a no-brainer decision.  Install, setup a repository, get on with code.

To be honest SVN still isn’t a terrible choice (unless your name is Linus then you are stupid and ugly by default).  It does the job, it doesn’t get in my way (that often) and since everything is local to my machine it also performs well.  As soon as you have to start going over the network the performance can degrade dramatically though.

Enter Git Source Control

So last year (yes I know I’m very late to the party) I had my first commercial requirement to use Git and I also started using GitHub to host some of my own projects related to my Prism articles (part1, part2) and other bits and bobs.  I think one of the reasons that I had at that point kept Git at arms length was that I hadn’t been given a compelling reason to NOT carry on using Subversion.  I also hadn’t been given a commercial reason to NEED to use Git, I was already busy enough writing code to start changing core elements of my workflow.

Another issue was that during my first commercial use of Git, when I hit an issue the guys who owned the repository also didn’t know how to solve the issues which wasn’t very reassuring.  That just put a flag up for me hammering home that “Git was inherently complicated” – avoid.  I had also struggled to get some of my own stuff up onto GitHub using their own Git client application (which I now don’t use as I don’t think it’s very good to be honest).

There was no denying the rise and rise of GitHub as a platform and the fact that all my fellow developers seemed to be flocking to Git and loving it.  The final straw that led to this blog post was that I really wanted to help out on some open source projects – chiefly MvvmCross.

Now I had to learn Git and boy am I glad I did.

From the initial confusion, which is absolutely related to the way you think about source control and the choice of verbs like Add, Commit and Branch (among others), is that Git thinks very differently about these verbs.  It also does very different things in response to them on the command line.  BUT once you get it, you’ll realise the shortcomings of all the source control systems you’ve used before.

Git solves problems you didn’t even know you had.

The biggest difference that WILL confuse you is going from a traditional centralised repository model to Gits distributed model.  Don’t assume you will just get this fact, I thought I would, I didn’t, it hurt.  The best graphic I’ve seen that encapsulates this is …

source control git distributed model

Gits distributed model

The basic gist of this is that there is no one master repository that you are used to interacting with.  There are many but most importantly you have both a local “working copy” and a “local master repository” or “staging area” which you commit to.  You can link to an arbitrary number of “remotes” (other repositories) and push and pull from any of them as if they were all master repositories (in centralised parlance).  It couldn’t be more different from something like Subversion.

In the graphic above the origin can be thought of as a traditional central repository but you can have lots of these if you want.  More importantly you can also pull changes from anyone else and they can pull (update in SVN terms) from you.  All very cool, and very powerful.

Switching to Git Source Control

To get started with Git you first need to install Git itself (none of the gui downloads include Git).  A good GUI client (none of them are perfect) is SourceTree from Atlassian.  They also provide great resources here.  There is also a completely free Pro Git book.

I’m not going to go into any more details about that here as this is what the videos and links are for.  All these resources and the main video above will give you some context on Git.  Once you’ve watched that video this is the next one you should watch to get to grips with the nuts and bolts of Git.


Bye, Bye Parallels – Hello Virtual Box

So I finally did it.  When I first purchased my MacBook Pro I bought a copy of Parallels 8.  What a mistake that turned out to be.  Don’t get me wrong the software did what it should have done when I bought it whilst running Mountain Lion.  Then their marketing kicked in banging on about how Parallels won’t work after each upgrade of OSX.  You can read about some of that story here so I won’t go over that again here.

I finally upgraded to El Capitan and boom, Parallels issues with the networking, I tried a few fixes published on various sites, none of which worked.  I refuse to give them any more cash frankly so – bye, bye Parallels – hello Virtual Box.

I’ll keep this thread up-to-date with anything relevant or potentially interesting that happens during the switch.

Installing Virtual Box & Win7 Virtual Machine

Theres practically nothing to write about this, it was ridiculously easy.  Virtual Box installed without any issues at all.  Plugged in the SuperDrive to the Mac, launched Virtual Box, went through the VM wizard and Win7 installed without any issues.

Thumbs up all round frankly.  And no cash changed hands!


MvvmCross iOS Support and Samples

A while ago Martijn van Dijk and I had a very brief chat about creating an MvvmCross iOS Support library for use with MvvmCross.  Just to add in some general usage bits and bobs to make iOS development with MvvmCross a little bit easier.  I had been creating some useful bits for my own projects and could definitely see the value in them for other people to use in their projects.  But … as ever, my time is stupidly short.

Turns out it’s not as short as I thought and to be honest it didn’t take much effort to pull some things out and wrap them up in a self-contained fashion.  So today I spent a bit of time doing just that.  The results are now available in the MvvmCross iOS Support GitHub repository along with a newly minted MvvmCross iOS Support sample application.

MvvmCross iOS Support

The library really only contains one “helper” element at the moment in the shape of a pretty nifty presenter called – MvxSidePanelsPresenter.  Mvx Presenters are a kind of “glue class” that orchestrates what happens in between a view model navigation request and the presentation of it’s view in the application UI.  So any calls like ShowViewModel<TViewModel>(); will eventually end up being processed by a presenter, which decides what to do with it.

The presenter provides 3 panels as view “targets”, a main central panel, a right panel and a left panel.  Where a view is placed is controlled by a class level attribute.

Panel Presentation

<br />
[Register(&quot;CenterPanelView&quot;)]<br />
[MvxPanelPresentation(MvxPanelEnum.Center, MvxPanelHintType.ActivePanel, true)]<br />
public class CenterPanelView : BaseViewController&amp;lt;CenterPanelViewModel&amp;gt;<br />
{<br />
}<br />

So to explain this example it’s telling the presenter that I want to be displayed in the center panel as the active panel and I also want to be shown immediately.  If this was requesting MvxPanelEnum.Left for instance this would show the view in the left hand panel and would also immediately slide the left panel into view.  Pretty neat.

Combining A UISplitViewController for Master / Detail Views

Another neat feature of the presenter is that it can present views in a split view if the presentation attribute includes the a specific request to do so (by specifying MvxSplitViewBehaviour) and the application is also running on an iPad.  In the case where there are split view behaviours added to the attribute and the application is running in an iPhone these behaviours will be ignored. The views are in that case presented in whichever panel has been specified. So there is a graceful fallback to default behaviour when needed.  You can specify this split view behaviour like this:

<br />
[Register(&quot;MasterView&quot;)]<br />
[MvxPanelPresentation(MvxPanelEnum.Center, MvxPanelHintType.ActivePanel, true, MvxSplitViewBehaviour.Master)]<br />
public class MasterView : BaseViewController&lt;MasterViewModel&gt;<br />
{<br />
<p>[Register(&quot;DetailView&quot;)]<br />
[MvxPanelPresentation(MvxPanelEnum.Center, MvxPanelHintType.ActivePanel, true, MvxSplitViewBehaviour.Detail)]<br />
public class DetailView : BaseViewController&lt;DetailViewModel&gt;<br />
{<br />

The master view with be shown in the left hand portion of the split view and any detail views will be automatically shown in the right hand portion of the same split view.

Let me know if you find this stuff useful and obviously open any pull requests or open issues for any bugs.

You can see the code here on GitHub.  And you can read the more official documentation for this library on the MvvmCross documentation pages here.