Swiftpack.co - Package - JoeyBodnar/WhiteFlowerFactory

Unit tests

WhiteFlowerFactory is a simple URLSession wrapper with support for both concurrent and serial request queues.

Installation with Cocoapods

pod 'WhiteFlowerFactory'

Installation with Carthage (preferred)

Add the following to your cartfile:

github "JoeyBodnar/WhiteFlowerFactory" == 0.4.0


Right now all callbacks are completed on the main queue, though this is subject to change in the near future.

Get requests

To make a simple GET request:

WhiteFlower.shared.get(urlString: "") { response in
    switch response.result {
    case .success(let data): // do something with data
    case .failure(let error): // do something with network error

Serialize response using Codable

If you have a type and want to serialize the response using Codable:

WhiteFlower.shared.get(urlString: "") { response in
    switch response.serializeTo(type: MyClass.self) {
        case .success(let myClassInstance): // do something with myClassInstance
        case .failure(let error): // do something with network error  

Test if OK

sometimes you just want to make sure an object was created, and expect a response with an empty body. For that, use isOK():

WhiteFlower.shared.post(urlString: "https://www.facebook.com/postSomething", params: ["key": "value"], headers: nil, completion: { (response) in
    switch response.isOk() {
    case .success: // success
    case .failure(let error)

POST requests

A sample POST request:

WhiteFlower.shared.post(urlString: "urlHere", params: ["testParam" : "param1"], headers: [HTTPHeader(field: HTTPHeaderField.authentication.rawValue, value: "Bearer xxxx")]) { (response) in

Providers - Type safe routing

To provide type-safe routing with WhiteFlowerFactory, it is recommended that you create an enum that adopts to the Provider protocol. Ideally, you will have 1 enum conform to the Provider protocol for each baseURL endpoint your app has. For example, suppose your app needs to connect to the Stripe API and the Facebook API. You would create an enum that conforms to the Provider protocol, like so:

enum Facebook: Provider {
    case login
    case getFriends
    var path: String {
        switch self {
        case .login: return "\(baseURL)/login"
        case .getFriends: return "\(baseURL)/me/friends"

    var baseURL: String { return "https://facebook.com" }

    static var name: String { return String(describing: Facebook.self) // this returns "Facebook" }

Then, likewise for Stripe:

enum Stripe: Provider {
    case chargeCard
    var path: String {
        switch self {
        case .chargeCard: return "\(baseURL)/charge"         

    var baseURL: String { return "https://api.stripe.com" }

    static var name: String { return String(describing: Stripe.self)  }

Now, you can make use of type safe routing:

WhiteFlower.shared.post(endPoint: Stripe.chargeCard, params: ["":""], headers: []) { (response) in

Serial network operations

To make requests serially (one after another, waiting until the previous request is finshed before starting the next request), just create an array of WhiteFlowerRequest objects and create a WhiteFlowerSerialQueue:

  let requests = [WhiteFlowerRequest(method: .get, urlString: "https://facebook.com"), WhiteFlowerRequest(method: .get, urlString: "https://google.com"), WhiteFlowerRequest(method: .get, urlString: "https://reddit.com/r/iosprogramming")]
  let queue = WhiteFlowerSerialQueue(operationQueue: OperationQueue())
  queue.start(requests: requests, operationCompletion: { (response) in
      // this completion is called after every indiviudal request is finished
      // so in this examlple, it will be called 3 times
  }) { (allResponses) in
      // this is called at the very end and gives an array of APIResponse objects

Concurrent network operations

To make multiple requests concurrently and then receive a callback only once all requests have completed, use the WhiteFlowerConcurrentQueue class:

let requests = [WhiteFlowerRequest(method: .get, urlString: "https://facebook.com"), WhiteFlowerRequest(method: .get, urlString: "https://google.com"), WhiteFlowerRequest(method: .get, urlString: "https://reddit.com/r/iosprogramming")]

let queue = WhiteFlowerConcurrentQueue(requests: [], queue: DispatchQueue.main)
queue.execute { responses in
    // `responses` is an array of APIResponse objects

The responses array will return the responses in the same order that they were originally executed. So for the example above, the response object for the https://facebook.com request would be first, google would be second, and reddit.com/r/iosprogramming would be last


Stars: 0


Used By

Total: 0


SPM support - 2020-09-05 09:46:03

  • add support for swift package manager

URLSessionProtocol - 2020-08-01 11:59:38

  • WhiteFlower's session instance is now an instance of an object conforming to URLSessionProtocol, not only URLSession

HTTPHeader properties public - 2020-07-27 13:46:01

  • make field and value on HTTPHeader public properties

Concurrent queue and Dispatch queue - 2020-04-29 15:23:57

  • Add concurrent queue
  • Can choose dispatch queue for callbacks
  • APIResponse error type is now Error

Add Mac support - 2020-04-06 17:51:44

  • Add Mac support starting at macOS 10.13 (High Sierra)
  • add convenience function for data serialization with codable
  • set minimum iOS deployment target to 11.0
  • add custom headers to GET request convenience function

Fix decoding - 2020-03-08 00:53:07

Fix parsing/decoding issue for Codable integration

Fix HTTP body error on WhiteFlowerRequest - 2020-02-20 22:19:34

Fix bug where HTTP body was not assigned to WhiteFlowerRequest if there were no HTTPHeader fields present in request

Change authentication HTTP header to be authorization

Carthage support - 2020-01-28 14:36:30

Add Carthage support

URLEncoded support - 2019-08-18 08:34:27

v 0.3.0 brings these changes:

  • post, put, patch, and delete requests can now be URLEncoded. Note, this only works for flat dictionaries now, not nested dictionaries/arrays
  • Added Result extension to get string value from result data

New access level controls - 2019-08-17 17:15:52

Changing access level protections for APIResponse, DataTaskResponse, AsynchronousOperation, and NetworkOperation.

Properties for APIResponse and DataTaskResponse are now public. Properties and methods for AsynchronousOperation and NetworkOperation are now internal.

New file structure, Data in Result is optional - 2019-08-17 16:42:23

First release - 2019-08-17 11:22:20

first release