Created
November 2, 2014 12:55
-
-
Save ulrikdamm/68c4f019abcc885247b5 to your computer and use it in GitHub Desktop.
Operations.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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