Swift 异步编程库:Wyrd
Wyrd 是 Swift 异步编程的库,目标是简洁和简单,灵感来源于Promises/A+。包括Swift和Cocoa Touch都没有提供任何帮助类对于异步编程,除了标准除采取回调success / failure标准函数。 Wyrd试图用相当简单的API来解决此问题。
如何安装
At the moment the most convenient way is to add Wyrd repository as a git submodule to your main repository:
git add submodule add https://github.com/explicitcall/Wyrd.git wyrd
Then add Wyrd.swift
file to your project.
CocoaPods package will be added as soon as CocoaPods will support source code in Swift.
如何使用
Essentially, Wyrd instance is a promise, which can be chained with other promises using closures and chaining operators. Wyrd library provides a few wrapper extensions for standard asynchronous Cocoa Touch functions. These extended functions return a promise instead of taking a success/error callback, giving you much clearer code and saving you from a Pyramid of Doom.
Obligatory example (getURLData
and FullResponse
typealias are provided to you by Wyrd):
let s = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) let u1 = NSURL(string: "https://api/endpoint1") let u2 = NSURL(string: "https://api/endpoint2") (s.getURLData(u1) => { (full: FullResponse) -> Wyrd<FullResponse> in switch full { case let (data, response): println("data1 length is \(data.length)") } return s.getURLData(u2) }).success { (full: FullResponse) in switch full { case let (data, response): println("data2 length is \(data.length)") } }
This code issues two API calls in serial, the second will fail if the first fails.
Wrapping typical asynchronous Cocoa Touch code is fairly easy, just define a method/function which will return a Wyrd instance, which you will be able to chain. You will need to fulfil or reject the promise in the raw callbacks code to indicate when the promise will be able to chain further:
typealias FullResponse = (NSData!, NSURLResponse!) extension NSURLSession { func getURLData(url: NSURL) -> Wyrd<FullResponse> { let result = Wyrd<FullResponse>() let task = dataTaskWithURL(url) { data, response, error in if let e = error { result.reject(e) } else { let tuple = (data, response) result.fulfil(tuple) } } task.resume() return result } }