Development

Using URLCache as an alternative to retaining network model objects

Oftentimes we request JSON data from the server, deserialise it into network model objects and then wonder where we can keep ahold of this data. We wish to put it somewhere handy in our architecture so that we don’t have to repeat the effort of hitting the server again for the same data in the future.

It’s not always obvious where we can put these objects to make them available between unrelated screens - they can’t necessarily be neatly passed around. There are many approaches to solving this architectural problem, and we could go as far as rolling our own data store (BlahDataManager), or even cramming what we get back from the network into Core Data - occasionally the correct call but usually a vast over-complication.

Whatever we choose, we’ll likely arrive at the following solution, with two separate APIs to query for each set of data that we might need:

  • Step 1: query our local data store (whatever it is) to see if we already have the data we need, or
  • Step 2: hit the network to retrieve the data.

This could be wrapped in a single public interface to hide this fiddliness, but what I wanted to show is that - for GET queries at least - there is already a Foundation API for doing this rather neatly: URLCache.

Background

In a client app I worked on recently, there was a situation where the server-side data we needed was scattered over many endpoints (there was an existing API, designed originally for a website, and it wasn’t adjustable for our purposes), and data had to be pieced together from different places, and at different times. Unfortunately the response times from the server were also rather lengthy, and the need to make multiple requests each time we needed certain data was resulting in a poor user experience.

It became pragmatic for the responses to be cached somewhere, but we wanted - for most endpoints, and in the MVP at least - to avoid the extra complexity of maintaining our own local model store representation of the server data, as this would need to be kept in sync across subsequent updates.

What would be nice is if we could skip that and just blithely make all queries for data to our Transport layer every time we needed it, without worrying about how frequently we do this, whether that query has already been fetched before, or how many requests are being made. The idea is that if we could cache at the network layer instead, we could get the benefit of using a single API, still have very quick data accesses, and not have to worry about having to store the result.

This use-case would not apply equally well to all apps out there, but for this app it was particularly suitable, as it was just a bunch of screens displaying fairly static data that only changed predictably and infrequently, yet which each an outsized number of calls to be made.

(NS)URLCache

Using URLCache allowed us to make our network requests efficiently repeatable and, for our simple use-cases, allowed us to completely sidestep the responsibility of implementing our own data storage in the Application layer.

It works like this:

  • If the data has never been retrieved before, the request will hit the server as normal & retrieve the data, and then asynchronously return the response.
  • If the data has previously been retrieved (and is still cached), it will be immediately (asynchronously) returned to us.

As the caller of this API, we don’t actually care about which path is executed - and the data is returned to us in the same way each time. This made it pretty fast to repeatedly traverse the various endpoints over which user and application data was scattered, without actually hitting the network more than necessary.

Configuration

URLCache is simply a component of the networking stack in Foundation which we can configure to suit this usage. We used URLCache with in-memory storage only (as disk storage is persisted across app launches, which we didn’t want). This should ideally be configured on app startup:

// Assign memory (but not disk space) for a URL network cache:
let cacheSizeMegabytes = 30
URLCache.shared = URLCache(
    memoryCapacity: cacheSizeMegabytes*1024*1024, 
    diskCapacity: 0, 
    diskPath: nil
)

That’s it! All that’s needed now is to configure your URLRequest with the appropriate cache policy. useProtocolCachePolicy is the default (which is the most respectful of the cache-related HTTP headers), but returnCacheDataElseLoad is what we will want to use for all our appropriate endpoints, as described below.

public enum CachePolicy : UInt {
    case useProtocolCachePolicy // the default
    case reloadIgnoringLocalCacheData
    case returnCacheDataElseLoad
    case returnCacheDataDontLoad
    //..  omitted other unimplemented cases
}

Note: Somewhat unintuitively, despite providing your cache policy as returnCacheDataElseLoad, URLRequest remains free to disregard your caching preference if the response contains HTTP headers indicating that stuff should not be cached (Cache-Control: no-cache). In our case, this was arbitrarily turned on for every single request (even for completely static shared data), and we wanted to work around it - I’ll write about how to do this in a follow-up post.

To clear a response from the cache (for example, because a user has triggered a UIRefreshControl), you just provide an appropriate request that matches up to (i.e. has the same characteristics - it doesn’t need to be exactly the same object) the response you wish to clear:

URLCache.shared.removeCachedResponse(for: fetchRequest)

Limitations

Naturally this approach has its limitations:

  • we must manually clear the cache (per-endpoint) if we wish to receive newer data.
  • if we fire the same request simultaneously (e.g. from two different parts of the code), two network requests for the same data will still be made (due to the race condition of neither having completed yet - i.e. there’s no cache hit).
  • the cache sits prior to deserialisation, so on each access there is some wasted effort deserialising the same JSON over and over again. In practise I have found this not to be a noticeable issue - the usual advice of not prematurely optimising applies here, but it’s something to be aware of.
  • the lack of a sophisticated persistence layer (such as Realm or Core Data) means that clearing the cache and refreshing the data does not automatically propagate this change across the app (to other screens, for example). Clearing the cache means that subsequent refreshes will now receive the latest response, but this is not automatically pushed across the app.

In summary, this approach is not suitable for every use case, but for many simple screens that are just showing basic data this can be a nice idea to keep in mind.

MVVM + Coordinator = 🍰

I've been using the god-mix of the MVVM pattern mixed with the Coordinator pattern to build Tacks - and I'm a huge fan of the approach.

Prior to adopting this, when I was using only MVVM, there was always the question of who was responsible for navigating between the screens - who makes the overarching decisions regarding what to do next? The implementation of which would float awkwardly somewhere between the ViewController (VC) having the presentation of the next screen hard-coded (which hurt reusability), or the ViewModel (VM) somehow nudging the VC and whispering "now go to the success screen" or whatever into it's ear. This really polluted the concept of "single responsibility" for both of these components.

It was also never super clear who should create the VM to be injected in to the VC either. The way I had been doing it, the ViewModel of the previous screen would create and configure a "Child View Model" to be injected into the ViewController that was being presented.. which was a bit messy, and unfortunately coupled the two screens together.

Enter stage: Coordinator 🎺

What the Coordinator pattern adds to this mix is the role of an overseeing "Coordinator" object (duh), responsible for a particular flow of your app, e.g. The Signup Flow.

It owns a canvas (a NavigationController, for example) onto which it can present ViewControllers as it wishes and, like a puppet master, sits high and mighty above the VC+VM layer pushing and pulling and popping screens into place, and responding to the output to decide what to do next. It is therefore the Coordinator's job to create both the VC and the VM, and to configure them as necessary.

Peeling away this responsibility from both the VC and the ViewModel really helps towards reaching the aims of the "Single Responsibility" principle.

In my opinion, the key benefits of MVVM boil down to the following:
- Separating the view model from the user interface makes it easier to test presentation logic.
- Separating the view controller from the presentation logic makes it easier to test the user interface.
— Ash Furrow, "MVVM in Swift"

So, in terms of what the Coordinator pattern adds to this, I'd say:

  • Separating the VM and the VC from the responsiblity of managing navigation makes their actual roles in the architecture clearer and more specific. The implementation becomes dumber and reusability improves. Awareness of flow between screens (i.e. how you got to this screen and where to go next) is completly delegated upwards to the Coordinator - making everything simpler.

--

One last thing to add is that if you allow the VC to communicate with Blah VM only through a BlahViewModelType protocol, you are then free to inject the VC with different implementations of the BlahViewModelType for different purposes, making the VC still further reusable. For example, the MapViewController in Tacks is currently used in three different situations (once full-screen and twice as a child VC on other screens), simply by changing the underlying ViewModel to adjust what is shown.

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.

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.

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