While doing research for my next Swift article, I implemented a very simple future class, which might be of interest:

import Foundation

func PerformOnMain(work: () -> Void) {
	CFRunLoopPerformBlock(NSRunLoop.mainRunLoop().getCFRunLoop(), kCFRunLoopCommonModes, work)
}

func PerformAsync(work: () -> Void) {
	dispatch_async(dispatch_get_global_queue(0, 0), work)
}

class Future <T> {
	let lock = NSCondition()
	var result: [T] = []
	
	func _run(work: () -> T) {
		PerformAsync {
			let value = work()
			self.lock.lock()
			self.result = [ value ]
			self.lock.broadcast()
			self.lock.unlock()
		}
	}
	
	init(work: () -> T) {
		_run(work)
	}
	
	init(_ work: @auto_closure ()-> T) {
		_run(work)
	}
	
	var value: T {
		lock.lock()
		while result.isEmpty {
			lock.wait()
		}
		let r = result[0]
		lock.unlock()
		return r
	}
}

It’s used as follows:

let futureString: Future<String?> = Future {
	// ... protracted action that may return a string
	return didItWork ? aString : nil
}

// alternatively, if you just have a function call or expression:
let anotherString: Future<String> = Future(SomeFunctionThatTakesALongTime())
// ... do other things, then when you need the future's value:
let theString = futureString.value

In other words, the closure will be executed asynchronously, then when you need the result, getting value will block until it’s ready. The result of the closure can be of any type and even (as in the first example) be optional (that is, may be nil). Once the result is ready, getting value will not block.

My interest in futures began with Mike Ash’s excellent article about an Objective-C implementation of the concept. Mike’s implementation (MAFuture) is of an implicit future; that is, it returns a proxy object which transparently stands in for the future value and doesn’t block when operations like retain/release are performed; therefore, you can add the future to an NSArray or NSDictionary while it’s still being computed. The downside is that, because of the intricacies of message forwarding in Objective-C, the future can’t return a nil value.

MAFuture has grown to be rather complex, now catering to iOS memory triggers, archiving and whatnot, so I made a very bare-bones variation for my own projects, where it has been very useful.

Swift has no proxy objects (yet?), so implicit futures can’t be done; I tried to code the proxy in Objective-C and subclass in Swift, but ran into too many compiler/runtime bugs — it’s a beta, after all. However, the explicit implementation above has the advantage that the future can return any Swift type, including optional.

An additional Future property that might be useful in some places:

var resolved: Bool {
	lock.lock()
	let r = !result.isEmpty
	lock.unlock()
	return r
}

you can use this to test if the result is available without blocking.

There are more complex futures available already. I looked at Swiftz (by Maxwell Swadling) and BrightFutures (by Thomas Visser), which also implement other constructs. If you have a functional programming background you should examine them, too.

Update: Mike Ash suggested a small change in my code above (have to broadcast before unlock), and confirmed that everything should work properly. Thanks Mike!

Update#2: some more small changes, added the autoclosure form and a PerformOnMain function that fills in for the Objective-C performSelectorOnMainThread: method – useful for updating UI at the conclusion of a future’s closure.

Update#3: final form, in line with the published sample app on github. There are extensive comments on details.

Update#4: slight change for the new Array declaration syntax in Xcode 6.0b3.