Skip to content

Instantly share code, notes, and snippets.

@ulrikdamm
Created November 2, 2014 12:55
Show Gist options
  • Save ulrikdamm/68c4f019abcc885247b5 to your computer and use it in GitHub Desktop.
Save ulrikdamm/68c4f019abcc885247b5 to your computer and use it in GitHub Desktop.
Operations.swift
class Promise<T> {
var value : T? {
didSet {
if let value = value {
notifyListeners(value)
}
}
}
init(value : T? = nil) {
self.value = value
}
func getValue() -> T {
let sem = dispatch_semaphore_create(0)
waitForValue { _ in }
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER)
return value!
}
var listeners : [T -> Void] = []
func waitForValue(completion : T -> Void) {
listeners.append(completion)
}
func notifyListeners(value : T) {
for listener in listeners {
listener(value)
}
}
}
protocol Operation {
typealias Input
typealias Output
var input : Promise<Input>? { get set }
var output : Promise<Output> { get }
}
infix operator >>> {
associativity left
}
func >>><T : Operation, U : Operation where T.Output == U.Input>(lhs : T, rhs : U) -> CompositeOperation<T.Output> {
return CompositeOperation(input: lhs.output, output: rhs.input!)
}
func >>><T, U : Operation where T == U.Input>(lhs : Promise<T>, rhs : U) -> CompositeOperation<T> {
return CompositeOperation(input: lhs, output: rhs.input!)
}
class CompositeOperation<T> : Operation {
typealias Input = T
typealias Output = T
var input : Promise<Input>? {
didSet {
if let input = input?.getValue() {
output.value = input
}
}
}
var output = Promise<Output>()
init(input : Promise<T>, output : Promise<T>) {
self.input = input
self.output = output
}
}
@objc protocol NetworkOperationDelegate {
func didMakeProgress(progess : CGFloat)
}
class NetworkOperation : Operation {
typealias Input = NSURL
typealias Output = NSData
var input : Promise<Input>? {
didSet {
if let input = input?.getValue() {
begin(input)
}
}
}
var output = Promise<Output>()
weak var delegate : NetworkOperationDelegate? = nil
init(delegate : NetworkOperationDelegate? = nil) {
self.delegate = delegate
}
func begin(input : Input) {
self.delegate?.didMakeProgress(0)
let request = NSURLRequest(URL: input)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in
self.delegate?.didMakeProgress(100)
if let data = data {
self.output.value = data
}
}
}
}
class JSONParseOperation : Operation {
typealias Input = NSData
typealias Output = AnyObject
var input : Promise<Input>? {
didSet {
if let input = input?.getValue() {
begin(input)
}
}
}
var output = Promise<Output>()
func begin(input : Input) {
let json : AnyObject = NSJSONSerialization.JSONObjectWithData(input, options: nil, error: nil)!
output.value = json
}
}
let url = NSURL(string: "http://ufd.dk")
let operation = Promise(value: url) >>> NetworkOperation(delegate: nil) >>> JSONParseOperation()
operation.output.waitForValue { value in
println("json: \(value)")
}
let netop = Promise(value: url) >>> NetworkOperation()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment