Swift Delays

Posted on Apr 27, 2015 in Code
james portrait
James Jacoby
Chief Technology Officer, Founder

Expressiveness in a programming language is incredibly important. Many of the systems Moby builds are intended to have long lifespans and therefore code maintainability is extremely important. More expressive code efficiently conveys the original code writer’s intent more clearly — making it easier for future developers to come up to speed quickly.

It is clear that the Apple engineers had expressiveness top-of-mind when they designed Swift. It borrows many aspects from languages like Ruby and Python, while at the same time “dealing” with its C past as best as possible. Once I learned the language, I was left with an insatiable desire to write the most expressive code possible in Xcode. My complacency with the impossibility of writing expressive objective-c code is gone and I’ve been seeking clever ways to bury the past as deep as possible.

In order to purge as much of the old way from our projects going forward, I’ve been systematically questioning all of the traditional techniques for even the most basic things. It’s almost too easy to just translate objective-c code into a Swift equivalent, because oftentimes you pass up an opportunity to do much better. A perfect example of this is the simple, but frequent task of introducing a delay between two pieces of code.

Here’s an example of a common technique for introducing a delay:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
  NSLog(@“2 seconds have passed!”);
});

If we translate this directly into Swift, it is certainly better, but we still end up with lot of extra words in our code that do not directly contribute to expressing our intent. In this example, our intent is to print the phrase “2 seconds have passed” after two seconds have passed. However, another developer reading this has a lot of other nonsense to parse through before determining this fact.

let delayInSeconds = 2.0
let popTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue(), {
  println("2 seconds have passed”)
})

By using the trailing closure syntax in Swift and by moving this code into a well-named function, we can abstract away some of the old C baggage and expose a very Switfy interface for performing delays.

func delaySeconds(seconds: Double, closure: ()->()) {
  dispatch_after(
    dispatch_time(
      DISPATCH_TIME_NOW,
      Int64(seconds * Double(NSEC_PER_SEC))
    ),
    dispatch_get_main_queue(),
    closure
  )
}

delaySeconds(2.0) {
  println(“2 seconds have passed”)
}

Much better! Now anyone can interpret those last three lines of code.

Checkout the Gist on Github

3D Printed Moby Whale Save Squarespace Forms to Salesforce