Finding remote freelance work: Toptal?

I'm trying to set myself up as a 100% remote developer, which - as someone who's traveled around a lot in the last few years, - is in some ways very easy (I'm already very mobile, I'm disciplined about working on my own), but in other ways is quite hard (I don't have an established network of existing remote-okay clients who I can plunder for ongoing work). My clients in Amsterdam have been great, but they've had the expectations of hiring a contractor, rather than a freelancer - that is to say they expected 9-5pm working from the office - of course fine if you live close-by, but not so good if you want to work flexibly and remotely.

As a result, I'm putting some work into getting listed as a Toptal developer, though it's quite tricky - you have to complete a challenging timed algorithm test before you take the serious interview. I attempted it a few years ago, completely unprepared for how hard it was, and totally failed (bummer). I'm going to retake it (they let you resit it after 6 months), and this time I'll be ready πŸ’ͺ🏻.

So, I've been practising the lessons on the Codality site (the programmer-testing website that Toptal uses to pre-screen candidates) as a sort of warm up. Though I feel this style of programming challenge doesn't necessarily correlate with someone's ability to build a good and stable iPhone app (it emphasises abstract problem solving), probably they're skills worth honing anyway. And it's pretty fun - like being set coursework back at Uni again.

Codality Lesson solutions: I'm posting on Github my solutions so far.

Tacks: Design: Conjuring a Style-Guide

Or: how to get started designing when you're a developer.

I recently [investigated, a, bunch, of, prototyping, tools] and, man were they all super involved. Great tools, but personally too much. What I was looking for was something akin to "Interface Builder on steroids" - some app with more design tools available for composing the UI (blur, border-radius, vector drawing etc), without dropping down to code, and yet still dragging-and-dropping live iOS native components.

Background

My strategy with Tacks thus far (version 1.x) has been "build the app, get the base functionality working, use all-native components, ship it, then circle back later to address the UI". Not ideal, but I had I not done it this way, the momentum required to build the functionality (in my spare time, between full-time office hours as well as travelling), would have evaporated away long before the app ever saw the light of day. Particularly so given I was building Tacks fully in the Functional Reactive paradigm using ReactiveKit, increasing the complexity (and also the awesomeness) quite a bit.

Solid Red colour scheme πŸ˜‚

Solid Red colour scheme πŸ˜‚

Now that the basic version is now in the App Store - and v2 is really gathering speed - it's become time to apply a decent design. The problem is, I'm no designer.

This guide is mostly aimed at developers who are working on their own apps. Here are some tips for getting started, based on what I did.

N.B. I still plan to stump up some cash to hire a freelance designer further down the line, but for now (whilst I'm still working on core functionality), I just want to keep following my vision for how it should look and work, and see how far I get.

--

v1.0. Well, it was a start..

v1.0. Well, it was a start..

Tacks UI: Version 2.0

The most daunting aspect of attempting UI design is establishing the overall "Look and Feel" of the app. It's quite a scary undertaking.

I suppose I did give up with the UI design of Tacks v1 - as you can see to the right, I arbitrarily chose a not-generally-respected "Solid Primary Red" colour scheme and just shipped it like that.

But now I needed to work out what my screens should look like for v2. They needed still to be native (a lone developer likes an easy life), but slick enough to be a recognisable iOS10 app, not easily mistaken for an iOS5-era app.

I came across this post at ThoughtBot advising designers to prototype directly in Interface Builder, which I initially disregarded but it gave me pause. Interface Builder? Hmm, maybe that could actually work.

Plan of attack

Colours

The first step is to choose a color scheme. There are tonnes of tools online to assist you with this: my favourite is ColourCode, but Coolors is also great. Pick a few colours, and then choose some different shades within that set to use for emphasis, selected-states, etc.

These are the colours that Apple use in iOS (presumably since the iOS7 flat-design refresh)

These are the colours that Apple use in iOS (presumably since the iOS7 flat-design refresh)

Side-note: I'm pretty excited for this:

Style Guide

Next, create for yourself a style guide. This will be your reference point when you're developing your app, and for all decisions about "what should this bit look like", you can relax and refer back to this document that you made for yourself at the start.

Our document will be a simple Storyboard, created in a separate "TacksStyleGuide" project.

Protip: even if you haven't ported your main project to Xcode 8 yet, the new beta does have a more powerful Interface Builder with extra (live) UI features such as blur effects, vibrancy etc, as well as editing at any zoom level. So, perfect for simply creating a Style Guide at least.

Open a new Storyboard StyleGuide.storyboard, add a new ViewController and just go to town. Create every control that you will need in your app, samples of text in the fonts you will use, buttons in different states, icons, etc. Just keep tweaking until it looks good. If you get to a certain point on the first attempt and decide (like I did) that you're heading in the wrong direction, duplicate the ViewController and start again - you can then compare your attempts later. Likewise, experiment using different colour swatches. After you've created a few of these, get some feedback from people you respect.

An early version of mine. When I asked around, the righthand colour scheme was much more popular.Β It's handy to create a colour swatch in Interface Builder as a reference point for each attempt - it's just a short View Controller with a horizontal UIStackView and a bunch of coloured UIViews.

An early version of mine. When I asked around, the righthand colour scheme was much more popular. It's handy to create a colour swatch in Interface Builder as a reference point for each attempt - it's just a short View Controller with a horizontal UIStackView and a bunch of coloured UIViews.

Doing it in this abstract way takes the pressure off. You're not even going to use this storyboard in the app, so it allows you to think about the app more generally rather obsessing specifically about one screen.

Preview as any simulated device

Preview as any simulated device

You can also preview any effects live on a simulated device in Interface Builder using the Preview Assistant Editor. Just add a device (by default it shows Localizations, but we want live effects).

You should also run this Style Guide app on a device to preview how it looks - it can be quite surprising the difference between how you think it looks on a big screen and the reality on a small one (especially in terms of font sizes).

Now go ahead and use this design language to sketch out some components which will appear in the app. For Tacks, this will be TableView cells showing locations:

Still a rough attempt, but helping us form an idea of how the real app will look.

Still a rough attempt, but helping us form an idea of how the real app will look.

Great. So, we have a fairly precise idea of how we want the app to look. But now we should somehow automate the process of styling all the components to look the way we want.

I believe that, beyond the most basic app, Interface Builder should be used for mostly setting up AutoLayout constraints and adaptive layout behaviours, rather than minutely pinning down exact fonts and colours.

Automated styling

I believe that, beyond the most basic app, Interface Builder should be used for mostly setting up AutoLayout constraints and adaptive layout behaviours, rather than minutely pinning down exact fonts and colours. The reason being the tedium of having to manually update all your XIBs or Storyboards later if you change your mind.

The aim is really to transfer all the UI decisions you made in Interface Builder into code, and then to use that to style a plain version of your StyleGuide view controller. If you can do this, the theming code you created can be used to automate the styling of all standard controls throughout your app.

Use UIAppearance and tinting as a broad tool, and create custom extensions on UIKit controls for more precise control (UIAppearance only gets you so far).

You should also create some kind of Theme protocol for your project. This will define the typesetting, groups of colours etc, and will be passed (via dependancy injection) to your ViewControllers to allow them to style themselves.

Here's what I came up with:

Here's where I'm at after applying my new style.Β It's not perfect (or finished) yet, but is quite a leap forward compared to what I had before. Tacks v2 coming soon.. πŸ‹

Here's where I'm at after applying my new style. It's not perfect (or finished) yet, but is quite a leap forward compared to what I had before. Tacks v2 coming soon.. πŸ‹

Further

You could take this one step further and implement any @IBDesignable controls in this separate workspace too. I've basically been treating it like a playground for UI design, so this would be the next logical step.

I definitely recommend using a tool like Reveal.app to customize controls on-the-fly.

Swift Basics: reduce()

By the way, this post is also available as an interactive Swift Playground. πŸ€“

The reduce function is super useful for when you need to compute (or reduce 😏) a set of values down to a single value.

Let's take a look at a simple example. Say we wish to sum an array of numbers to find the total. Without the reduce function, we might use a foreach loop:

let valuesToReduce: [Int] = [1,2,3,4]
var total: Int = 0

valuesToReduce.forEach { value in
    total += value
}

total // total: 10

However, in Swift we try to avoid mutability.

Here is the same calculation written using reduce. Take a look then we'll break it down:

// use `reduce` to sum each Int in an array, resulting an Int:
let total = valuesToReduce.reduce(0) {
    (accumulation: Int, nextValue: Int) -> Int in
    return accumulation + nextValue
}

total // 10

or written more simply as:

let total = valuesToReduce.reduce(0) { $0 + $1}
total // 10

Note that the closure we to reduce is called once for every value of the array.

The zero that we pass in as a parameter is called the accumulator, that is: the starting value upon which successive calls of reduce function will be applied, effectively accumulating our final result. Actually, given that we're using value types and 0 is immutable, we will not be mutating the zero - we're really passing the return value from the first call (i.e. 0 + 1 = 1 - a new value) back in as the starting value (accumulator) of the next call.

We will see at the end that we can also use a mutable object as the accumulator and literally build up our object with each successive pass - which is sometimes useful for working with Cocoa.

Creating An Array from an Array:

The output of reduce can really be anything - even another Array. As a second example, let's use reduce to create a handy deduplication function which we can add as an extension on Array type.

The first thing to decide is what our starting value for this shall be. Our algorithm will be as follows: "start with an empty array and append each item, so long as that item isn't already present in the array". By this logic we shall finish with an array of distinct unique values.

Thus, we should start with an empty array of type <Element> (the Generic placeholder for the type of value the array can hold): [Element]():

extension Array where Element: Equatable{
    func deduplicate() -> [Element]{
        return reduce([Element]()) { (accumulation: [Element], find: Element) -> [Element] in
            guard accumulation.indexOf(find) == nil else {return accumulation}
            return accumulation + [find]
        }
    }
}

let result = ["Amsterdam", "Berlin", "Paris", "Amsterdam"].deduplicate() // -> ["Amsterdam", "Berlin", "Paris"]

Whoa whoa, slow down:

So:

extension Array where Element: Equatable - we should constrain this extension to be available only when the Array holds values that are equatable. Otherwise, how could we identify duplicates?

func deduplicate() -> [Element]{ - we're returning an Array of the elements of the same type that the starting array holds.

reduce([Element]()) { (accumulation: [Element], find: Element) -> [Element] in - [Element]() is what we start with - an empty array. This is the Accumulator that we'll be using. The signature of the closure we're passing to reduce has the accumulation that we're building up accumulation: [Element], and find: Element, the current element that we want to find.

guard accumulation.indexOf(find) == nil else {return accumulation} - if the element we wish to find is already in the accumulation, then exit early from this iteration, returning an unchanged accumulation value. This is the escense of deduplication.

return accumulation + [find] - otherwise, return the accumulation with find appended.

In the next example, we'll show that reduce can also be called on a Dictionary type, and that the accumulator can also be mutable if need-be:

Using a Mutable accumulator instead:

Say we want to take a Dictionary of type [String : NSURL], that is, a mapping of Town Name to Map URL, and turn it into an NSAttributedString of tappable (once added to a UILabel) linked text.

i.e. this:

let placeURLPairs: [String : NSURL] = [
    "Amsterdam" : NSURL(string: "https://www.google.nl/maps/place/Amsterdam/")!,
    "Newcastle" : NSURL(string: "https://www.google.nl/maps/place/Newcastle/")!,
    "Manchester" : NSURL(string: "https://www.google.nl/maps/place/Manchester/")!
]

to this:

We can, naturally, use a reduce function to acheive this. However, the API for building up NSAttributedStrings, is quite suited to using an NSMutableAttributedString and applying successive attributes and String values on it.

It's easy to tweak our reduce function to, instead of returning a new value each time, instead return a mutated version of the passed in accumulator, so this same object will be passed into each iteration and then will be the result by the end:

func attributedString(places placeURLPairs: [String: NSURL]) -> NSAttributedString{

    return placeURLPairs.reduce(NSMutableAttributedString()) {
        (accumulator: NSMutableAttributedString, placeURLPairs: (String, NSURL)) -> NSMutableAttributedString in

        // unpack the name and the URL:
        let (placeName, url) = placeURLPairs

        // Create the local attributed String which we'll append
        let localAttributedString = NSMutableAttributedString(string: placeName + " ")

        // Add a link to this name
        localAttributedString.addAttribute(
            NSLinkAttributeName, value: url, range: NSRange(location: 0, length: placeName.characters.count)
        )

        // Add this attributed string onto the mutable Accumulator
        accumulator.appendAttributedString(localAttributedString)

        // Pass the accumulator back out again
        return accumulator
    }
}


let placeURLPairs: [String : NSURL] = [
    "Amsterdam" : NSURL(string: "https://www.google.nl/maps/place/Amsterdam/")!,
    "Newcastle" : NSURL(string: "https://www.google.nl/maps/place/Newcastle/")!,
    "Manchester" : NSURL(string: "https://www.google.nl/maps/place/Manchester/")!
]

let attributedLinkedTownsString = attributedString(places: placeURLPairs)

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 1000, height: 200))
label.attributedText = attributedLinkedTownsString

Hopefully this was useful, do let me know in the comments if there's any feedback or comments.

By the way, this post is also available as an interactive Swift Playground. πŸ€“

Fixing Xcode CLI builds with broken plugin warnings

I'm a big fan of Carthage, but one issue that had been plaguing me for months was the command line warning messages about my Xcode plugnis not being "compatible".

It rather clutters up the Terminal.

It rather clutters up the Terminal.

PluginLoading: Required plug-in compatibility UUID ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Xcode_beginning_of_line.xcplugin' not present in DVTPlugInCompatibilityUUIDs

etc.

This post gives some good relief - you just pipe a script straight from the 'net straight to sh (πŸ™ƒ) - , allowing Xcode to now recognise all my plugins properly (which were actually working in the Xcode app, but apparently not at the command line) but it revealed that one plugin was broken, the excellent FuzzyAutocomplete:

WARNING: Failed to load plugin at path: "/Users/ian/Library/Application Support/Developer/Shared/Xcode/Plug-ins/FuzzyAutocomplete.xcplugin", skipping. Error: Error Domain=NSCocoaErrorDomain Code=3588 "dlopen(/Users/ian/Library/Application Support/Developer/Shared/Xcode/Plug-ins/FuzzyAutocomplete.xcplugin/Contents/MacOS/FuzzyAutocomplete, 265): Symbol not found: OBJC> CLASS_> $_DVTTextCompletionInlinePreviewController

I guess I hadn't noticed it was broken, so for now I'll just remove it.

Much better!

Much better!

Notes on ReactiveCocoa 3.0 RC

I'll be honest - I did have real problems getting back to grips with ReactiveCocoa 3.0 since their API overhaul (despite being reasonably familiar with v2 - I even gave a talk on it). I'm getting there now (tacks.cc is written extensively with ReactiveCocoa 3.0 RC), and I'll try to update this post with tidbits from what I've learned because, to-date - even though the RAC codebase is well documented, function to function - there's not enough examples out there for how you actually use this stuff as a whole. Most of the example code that exists is still in Objective-C and generally relates to previous versions of RAC. There are some great blog posts (linked at the bottom), which really helped me figure it out.

Creating a signal

We can create a "pipe" which returns a Tuple pair: the Signal itself, and an 'observer' which we can use to manually send events, - events which pop out of the created signal. They go together.

let (self.locationSignal, self.locationObserver) = Signal<CLLocation, NoError>.pipe()

Signal of empty Events:

If you want a Signal that sends empty Next events, create your signal like so: Signal<Void, NoError>, and just send it Voids: .Next(Void)

You don't always need a real Error type

Signals rarely fail, so it's usually easier just to model them using NoError.

let locationSignal: Signal<CLLocation, NoError>

Using next: to start a new signal after completion - this is gone

In RAC 2, we could use next: to start a new signal once another completes. We don't this anymore - instead we concatenate signals, for example: localFetchProducer |> concat(networkFetchProducer)

Create a SignalProducer from a value

let individualComicProducer = SignalProducer<Comic, NSError>(values:comics)

Resources:

Swift 2.0 - ReactiveCocoa API changes

|> -> .

Aside from converting all usages of |> to simply . ( - much better! we now have code completion! πŸŽ‰), a few other notable things tripped me up when switching to the Swift 2.0 api:

.Catch

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

.Start

Secondly, the compiler now seems to have problems identifying which default parameter it should use when you pass a closure to start:. Previously it was common to use the following shorthand:

producer.start { value in ... }`

Where we really meant was:

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

The method signature of start: is really:

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

The Swift 2.0 compiler (Xcode 7 b6, at least) now 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 seems to assume 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 ... }

.Put

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.

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.

.Catch()

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

.Start()

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 ... }

.Put()

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

Developing Tacks in the open

I have GitHub repo and am talking to myself publicly via GitHub issues, the primary purpose is an exercise in what an "ideal project" for me would feel like (when I'm running the show), as well as being able to demonstrate what my work style (and coding prowess πŸ˜›) is like to anyone and everyone who might be interested (I am a freelance developer, after all). Perhaps someone else might want to join the project too.

Swift learning: Integrating ReactiveCocoa into my canonical Swift app

Ok so I got this far without too many issues, so now to go back to my old favourite (or should that be nemesis?) ReactiveCocoa.

I abortively tried to begin learning Swift 2.0 with ReactiveCocoa 3.beta8 together from the get-go (because if it worked, that would be awesome right?): it didn't work because my Swift experience was too patchy, ReactiveCocoa 3 wasn't even finished and, particularly, wasn't ported to Swift 2 yet. (also I was still trying to get used to Xcode after three happy years using AppCode - which unfortunately is still lacking mature Swift support).

Now that the tears of frustration have dried, this time I'll go back somewhat less ambitiously (retreating to Swift 1.2 for my own sanity) and try ReactiveCocoa 3 again, it now being at RC1.

I've developed my ListViewController already with a ViewModel pattern, using callbacks (didChangeContent, didChangeSection etc) to notify the VC of FetchedResultsController changes. This is a perfect point to start and using Signals (or are they called SignalProducers now..?) instead.

Swift learning: writing a POC canonical Swift app

I'm taking some time off to rearrange my 4+ years of Obj-C knowledge into a Swift-shaped skillset instead. Retooling. There's some other things I want to try too (CloudKit, rspec-style testing with Quick), so this is a good chance to check them out.

Before I take on my next project, I want to have built a canonical POC Swift app which contains many of the usual features of an app and utilises the following implementation features:

  • showing basic data (e.g. a List) in a TableView
  • data is persisted in Core Data
  • data is shown with a FetchedResultsController
  • data is editable
  • UITableViewCell containing a textField
  • MVVM used

  • Unit tests written with Quick & Nimble

  • Convert to Swift 2.0

Once it's converted to Swift 2, then:

  • Xcode 7 User Interface tests written (Swift 2)

The app will be my "best practise" reference going forward, and should basically stay up to date with my own experience.

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 Tacks.io 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 Tacks.cc. 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.

Mail.app fix for Fastmail SMTP in Mavericks

I've been having intermittent issues with Fastmail's SMTP service in Mavericks, where Mail.app 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: http://www.iandundas.co.uk/blog/2014/09/04/ios8-b7-nsnumberformatter-bug/
+ (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];
        }
    }
    else{
        // no decimal place at all. Just append .00
        return [NSString stringWithFormat:@"%@.00", numberString];
    }

    return numberString;
}

EDIT

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, Preview.app 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: https://gist.github.com/iandundas/7863c6c248f76e14a3a8

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