Converting a RAC 3.0 project from Swift 1.2 to Swift 2.0

I've been loving ReactiveCocoa 3.0 (now that I've finally grok'd it), and today I was able to switch to the swift2 branch to start updating Tacks's Swift 1.2 code for iOS9.0.

Aside from converting all usages of '|>' to simply '.' instead ( which is much better! we now have code completion! 🎉), a few things tripped me up when switching to the Swift 2.0 api.


Firstly, catch is now a reserved word in Swift 2.0, so you should simply replace all usages with flatMapErrors - it's the same.


edit: as of Sept 7th, convenience methods have been added to get around this, i.e. startWithNext, startWithCompleted, startWithError, as well as for observing Signals: observeNext, etc.

Secondly, the compiler now seems to have problems identifying which default parameter it should use when you pass a closure to start:. The method signature of start: is really:

start(error error: (E -> ())? = nil, completed: (() -> ())? = nil, interrupted: (() -> ())? = nil, next: (T -> ())? = nil) -> Disposable

and previously it was common to use the following shorthand:

producer.start { value in ... }`

Which would really mean (I assume because next was the last parameter?):

producer.start(next: {value in ...})

The Swift 2.0 compiler (Xcode 7 b6, at least) makes a different decision about what we're trying to do. Due to the fact that we're passing a single block parameter, it now assumes that we want to call the start(sink: Event<T, E>.Sink) method instead. This is our clue that something's not right, as we start seeing that our blocks are being passed variables of type Event<YourType, NoError> rather than the expected type.

The solution is easy: either just be clearer about what you're calling by reinstating the next: parameter name:

producer.start(next: {value in ...})`

.. or provide more type information in your closure, to help the poor compiler out:

producer.start { (displayableAnnotations: YourType) in ... }


We no longer use .put(x) to set the value on a MutableProperty type - .value is now settable, so we just get and set .value directly. This is probably good, though I liked the separation before - it made it more obvious that MutableProperty also dealt in events. But like I say, it's probably simpler now.

Edit: Extra!

Don't forget to remove the Box dependancy as well, because it's no longer needed with Swift 2.0

ReactiveCocoa 3.0 alpha 1

I had some troubles even installing this build (Swift 1.2).

Firstly, the version of LlamaKit that cocoapods installed wasn't compatible with Swift 1.2 (which RAC3.0 is currently targetted at).

I tried the manual install next, but it seems like there's a step missing. If you get some issues like "No such module Result" or "No such module Box", the solution is here - you have to add more than just ReactiveCocoa.xcodeproj. I filed an issue and the Readme is updated to explain this now.

Taking a month off

Last week I was contracting on a great project at Philips. I'd been there since December, and before that I was working on something else, and before that something else.

Time was passing by, and part-time projects were piling up, gathering dust. This last year I'd really dug into ReactiveCocoa, but as a consequence I hadn't really learned Swift yet, and I hadn't been making any open-source contributions for god-knows how long. My portfolio site needs updating, my side-project app lies long since forgotten. I've been living in the Netherlands for 18 months, and hadn't started a Dutch class yet - though I'm pretty hot on Duolingo - challenge me ;)

Contracting is really great, but at the end of the day you're tired, and by the end of a long week coding 8 hours at a desk in a skyscrapper, you just want to relax. I've known for a long time that I work better during the afternoon & evening, and if I can do some decent exercise in the morning then even better.

A few months ago I opted not to renew my rolling three-month contract - WWDC was coming up and I wanted to make a huge gesture to myself, to give myself some time to actually attempt the things I 'never had time' to do. Watch the WWDC videos the week they come out! Write some example apps based on the new stuff! Read through my 120+ Pocket'd programming articles. Finish Design For Hackers. Release my long-time-in-the-making-and-still-objc pet project app Working towards being an 'indie' developer with recurring income streams.

Keeping myself a strong and skilled developer involves investing in myself. So now I've got a big block of four weeks 'self self-employed' time. Amazing.

(I've started my Dutch class, too)

Airserver for WWDC

For some strange reason, Apple has so far only released the videos of their Tech Talks in the WWDC app (and on the Apple TV - which I don't have). What if you want to watch them from the comfort of your sofa? Your hands are occupied already right🍕🍺?

Presumably they'll be on the website sooner rather than later, but in the meantime you can easily stream the content to your Mac using the excellent third-party AirServer (conveniently free for seven days). Once it's running, play the WWDC app video on your phone and, via the magic of AirPlay, they'll show on your laptop screen. If you can plug that into the TV, all the better.

Pro-tip: if you use the Share Sheet in AirServer, you even get the direct URL of the talk and can use it directly, dispensing with AirPlay completely.

Introducing Tacks

There's an app that I've been working on in my spare time, which I've actually been using personally for several months, but which I've not managed to pat together into an App store release.

It's a simple app based on something I needed each time I found myself in a new city when I was travelling: when you arrive, you constantly see lots of places you'd like to return to, and it would be super handy if you could just drop a pin there, add a short title and thus remember it for later. After a while, you'll see a map studded with interesting places that you yourself have added, and it's simple to find your way back later on. When you go to the next city, you start a new map, etc.

Inspired by Sam Soffes talking passionately about developing Cheddar on the Founders Talk podcast, I'm going to open-source this app and blog about its development too. fix for Fastmail SMTP in Mavericks

I've been having intermittent issues with Fastmail's SMTP service in Mavericks, where will sometimes repeatedly reject the correct password (and thus refuse to send mail).

The fix is to force it to use port 587 for SMTP (it claims it'll try 25, 465 and 587 by default, but this doesn't seem to be reliable):

Preferences -> Accounts -> Fastmail -> Account Information -> Outgoing Mail Server -> Edit SMTP Server List -> Advanced -> Use custom port: 587

iOS8 beta7 NSNumberFormatter bug

I just submitted this bug to Radar, hopefully it's fixed before the imminent RC:

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
numberFormatter.minimumSignificantDigits = 2;
numberFormatter.maximumSignificantDigits = 2;

// on iOS7 this outputs "$123.12"
// but on iOS8 b7 this just outputs "$123"
NSLog(@"%@", [numberFormatter stringFromNumber:@(123.12)]);

I'll have to implement it manually for now, it's fairly nasty:

// bug in iOS8, see here:
+ (NSString *)iOS8CurrencyForAmount:(NSNumber*)number{
#warning remove this once iOS8 nsnumberformatter bug fixed

    NSString *numberString= [NSString stringWithFormat:@"€ %@", number.description];
    NSUInteger length= numberString.length;

    if ([numberString containsString:@"."]){
        // catch when only one significant digit, e.g. 1.2 -> 1.20:
        if ((length-2 > 0) && [[numberString substringFromIndex:length - 2] containsString:@"."]){
            return [NSString stringWithFormat:@"%@0", numberString];
        // no decimal place at all. Just append .00
        return [NSString stringWithFormat:@"%@.00", numberString];

    return numberString;


My bad - the minimumSignificantDigits and maximumSignificantDigits properties don't even need to be set, so if you strip them off then all is right again.

Remove iBook citations with a keyboard shortcut

Whilst reading @AshFurrow's excellent book on Functional Reactive Programming (do read it, it's an refreshingly different way of going about writing Obj-C), I was finding that I was required to copy/paste a lot of code snippets from the e-book into AppCode.

This is not a nice process: if you're reading it via the PDF, doesn't correctly OCR the line spaces and what you paste into your IDE is a horribly mangled form of the code which won't compile and has to be tediously repaired. (it also unnecessarily copies the line numbers).

If you're reading via the Kindle app, that flat-out prevents you from copying any text at all from the book (fuck you, Amazon).

So that leaves the iBooks for OS X app, which does a great job at copying the text, but encases it in a citation block like so:

“RAC(self.imageView, image) = [[RACObserve(self, photoModel.thumbnailData)  2     ignore:nil] map:^(NSData *data) { 3   return [UIImage imageWithData:data]; 4 }];”

Excerpt From: Ash Furrow. “Functional Reactive Programming on iOS.” iBooks.

This is a feature built into iBooks which cannot be turned off - doh, resulting in:

After a while of removing all that each time I wanted to paste a snippet, I relented and wrote an Automator script to strip this out whilst it's in the PasteBoard:

Here is the script:

After you have saved the Automator script shown in the screenshot, then you can hook it up to a keyboard shortcut in System Preferences:

Now when I paste, I get:

RAC(self.imageView, image) = [[RACObserve(self, photoModel.thumbnailData) 
    ignore:nil] map:^(NSData *data) {
    return [UIImage imageWithData:data];

Much better. It's:

  • removed the line numbers
  • removed the surrounding quotation marks
  • removed the citation text

Now it's clean enough to paste into your IDE.

Looking Back for Inspiration Part 1: Gigsniffr

Perhaps my fondest memory in all my time spent coding was the all-out dash to build a complex PHP web-app for my undergrad dissertation. It was the biggest project I'd ever attempted, and was the starting-gun I'd been waiting for, the opportunity to really dig into something.

Prototype Homepage

Man, I was so psyched about my idea - it was a web-scraper named Gigsniffr which aggregated a set of concert ticket websites. The killer feature was that when it saw a ticket come onsale for a user's favourite band, it alerted them via a tweet (back when Twitter was still conceived of as a computer-human API platform). At the time, nothing much like this yet existed (2007 was also when Songkick launched), and I knew for sure that it could be big if I could just get it launched.

This was before any of these music sites had a published API for me to use, so I had to really research how to put together a reliable web-scraping algorithm that could repeatedly spider the ticket sites.

The project was incredibly fun: I was developing into (for me) the complete unknown - I wasn't amazing at PHP, I had no experience of managing a long-running web-scraper service, I had no permission to scrape these sites, I had a hard deadline to hit, and nothing to distract me.

There were many problems to solve: how can you work out the names of a user's nearest cities, without Google's Map API; how do you build an engine to accurately scrape many different websites, abstracting away from the quirks of each (answer: invent own XPath tricks); how do you diff the data collected with that taken an hour previously?

I soon found that the first pass of data gathering was easy - but updating and correcting this dataset was actually much harder: I was attempting to keep track of gig cancellations, date changes, and variances in band names (Red Hot Chili Peppers vs RHCP etc), and it was a rathole without end. Much fun to solve!

I did manage to get a prototype working in time for the deadline - an achievement which to this day I'm proud of. At the presentation were two local entrepreneurs who took an interest in my idea and took me out for lunch to discuss it.

Alas - I ground to a halt somewhere between finishing the proof-of-concept and launching a user-ready product. After I'd delivered the proof-of-concept and completed the course, the pressure was off and it was time to relax - I'd hit the deadline and could now continue developing Gigsniffr at my leisure, right after I've been to these music festivals and learned Ruby and started a job and...

.. and it was gradually forgotten. The would-be investors were interested only in funding marketing, and only once the app was finished - they were not interested in financing even the peanuts I'd need to sit down and complete it. I was also messed up after a nasty breakup. I found myself in a job that absorbed 10 hours of coding stamina per day, which I then quit to take a Masters - without any real gap after the undergrad. If I'm honest, I'd got what I wanted from the project, and was moving on - so Gigsniffr was shelved.

I've a profound admiration for those running startups which actually launch, especially those who succeed longterm - it's an amazing feat. People say that ideas are cheap, and that building them is the hard bit. What they don't mention is that building the interesting parts of a project is pretty easy, but FINISHING it is nearly impossible in comparison. Finishing a product really is hard. But the burst of real energy and creativity I summoned for Gigsniffr is something I've been chasing ever since.

Prototype Admin panel

Prototype scraping control panel

'Exposing NSMutableArray' : worth a read

"let’s note that every Obj-C method is actually a C function with two additional parameters. The first one is self which is a pointer to the object being receiver of the method call. The second one is _cmd which represents the current selector."

Even as a fairly experienced Obj-c developer I did not realise this, (though had often wondered where _cmd came from in a method's scope - I assumed magic). This was a good read, and something a bit different, too (though I didn't understand much when it dipped down into assembly).

Bartosz Ciechanowski: Exposing NSMutableArray

Ruby IMDB script to order & rate a list of films

I should paste this short script that I've written for converting an unordered list of films into a list ordered by the IMDB score (and also tagged with the genres). It worked great for tidying up the 350+ list of "you must see this" films that people have recommended to me through the years..

It will take an unordered list (with optional bracketted year to improve matching accuracy), e.g.:

The East (2013)
Shutter island
Stephen Fry: The Secret Life of the Manic Depressive
The Departed
Alan Partridge: Alpha Papa
Only God Forgives
You've got mail
Withnail & I
The Draughtsman's Contract
The Deal
Winter's Bone
A World Apart (1988)
We need to talk about Kevin

and will return:

<<<< RESULTS >>>> 
The Departed:  8.5  #Crime #Drama #Thriller
Stephen Fry: The Secret Life of the Manic Depressive:  8.2  #Documentary
Shutter Island:  8.1  #Drama #Mystery #Thriller
We Need to Talk About Kevin:  7.5  #Drama #Thriller
The Draughtsman's Contract:  7.3  #Comedy #Drama #Mystery
Winter's Bone:  7.2  #Drama
A World Apart:  7.1  #Drama
Alan Partridge: Alpha Papa:  7.1  #Comedy
The East:  6.9  #Crime #Drama #Thriller
You've Got Mail:  6.5  #Comedy #Drama #Romance
Only God Forgives:  5.8  #Crime #Drama #Thriller
The Deal:  5.7  #Comedy #Romance

=== Not Found... ===
Withnail & I

You can then paste this list into something like Workflowy or TaskPaper and navigate via the hashtags to filter by genre.

It's available as a Gist. To install, clone the gist, run bundle install, add your films to the provided film_list file, and run ruby IMDB.rb.

iOS 7 Custom Transitions - basic example

There's really not much sample code knocking around for iOS 7 custom transitions yet (or else Google is broken..): I guess that NDA is still only freshly lifted.

I've put together a simple example of how to present a new UIModalPresentationCustom-style Modal UIViewController with a UIViewControllerTransitioningDelegate managing the show. Have a play with this, it's simple enough to be self explanatory and useful for experimenting with - I hope it helps.

View the source on GitHub

Useful resources:

Unable to find a specification for ...

If anyone else is getting:

Unable to find a specification for … (libPusher in my case)

or the following:

Could not find cocoapods-0.19.1 in any of the sources

or even:

Pod::DSLError - Invalid Facebook-iOS-SDK.podspec file: undefined method `prepare_command=' for #

definitely try adding:

gem "cocoapods", '~> 0.23.0'

to your Gemfile, and then running:

pod setup && bundle update && bundle install

I guess there was a recent CocoaPods update that broke something with RubyMotion and motion-cocoapods.. or something.

RubyMotion OSX NSTableView example

(using AutoLayout)

I struggled a little to get a basic NSTableView working in RubyMotion, coming from an iOS background, as I couldn't find any conclusive 'hello world'-esque examples. So, here's mine.

clone on github

It's also useful to see how to create your first window, as the difference between NSViewController and NSWindowController isn't immediately obvious either. There's a helpful explanation of this on StackOverflow.

Once I'd got it working, I converted it to use AutoLayout. Note the sequence that I use to setup AutoLayout:


I find this sequence helps categorise what can be a complicated setup (if it were a more complicated controller, at least).

To get started (note that RubyMotion 2 is required for OSX support):

bash $ cd motion-nstableview-example $ rake