Archive for May 24, 2016

Tuesday, May 24, 2016

MVC-N: Isolating Network Calls From View Controllers

Marcus Zarra:

We have a network controller: it talks to the internet, your local network, or even be a flat file system. It then pushes data into your cache, into your persistence engine. Here comes the exciting part: your entire view layer talks to the cache only. It does not get data from the internet directly. The ViewController’s job is to display or update that data, not to do networking code. This design will serve you forever, and it has so many benefits that you’ll never want to use the anti-pattern ever again.

[…]

We can use the concurrent design of the NSOperation to do our network requests. In Swift, because we cannot access the property directly for finished, we have to do hacking (which I do have a radar for, and I am hoping they will fix this). The idea behind this overrided var is that we need to tell the queue that we are done. To do that, the queue is listening for “isFinished”. In Objective-C, isFinished translates into the variable Finished fine; in Swift, it only listens for “isFinished”, it does not listen for the actual property of Finish, you cannot change it.

Recursive Tail Calls and Trampolines in Swift

Umberto Raimondi (via Natasha Murashev):

In this post we’ll see how the lack of predictable tail call elimination in Swift could be overcome using trampolines and a few alternatives to recursion will be described.

[…]

A trampoline is not much more than a loop that executes iteratively functions that can either return the next function in the sequence (in form of a thunk or continuation, a data structure that contains the information needed to perform a specific function call) or another kind of value (in this case the content of the accumulator) to signal the end of the iteration.

[…]

And even if this implementation [is] slower than the original one for all the code needed to operate the trampoline that was added, this version solves our biggest issue related to stack exhaustion[…]

Swift Tuples Aren’t Equatable

Erica Sadun notes that Swift will let you create an array of tuples:

let a: [(Int, Int)] = [(1, 2), (3, 4)]

But you can’t use the contains() method:

a.contains((3, 4)) // no!

Its definition looks like:

extension SequenceType where Generator.Element : Equatable {
    /// Returns `true` iff `element` is in `self`.
    @warn_unused_result
    public func contains(element: Self.Generator.Element) -> Bool
}

The problem is that it requires the element to conform to the Equatable protocol. Equatable only includes one method:

func ==(lhs: Self, rhs: Self) -> Bool

And the tuple does implement ==. But the compiler can’t use that fact because Swift doesn’t allow tuples to conform to protocols. This is the sort of thing that annoys people about static languages. The workaround is to use a different version of contains():

extension SequenceType {
    /// Returns `true` iff an element in `self` satisfies `predicate`.
    @warn_unused_result
    public func contains(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool
}

to call == directly via a closure:

a.contains({ $0 == (3, 4) })