Skip to content

Instantly share code, notes, and snippets.

@gfontenot
Created February 5, 2015 19:25

Revisions

  1. gfontenot created this gist Feb 5, 2015.
    68 changes: 68 additions & 0 deletions requests.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    import Foundation

    infix operator >>- { associativity left precedence 150 }
    public func >>-<T, U>(a: T?, f: T -> U?) -> U? {
    return a.flatMap(f)
    }

    extension Optional {
    func flatMap<U>(f: T -> U?) -> U? {
    switch self {
    case let .Some(x): return f(x)
    default: return .None
    }
    }
    }

    protocol RequestType { }

    struct Request<T: RequestType> {
    let request: NSMutableURLRequest
    }

    struct GET: RequestType { }
    struct POST: RequestType { }
    struct Authenticated: RequestType { }
    struct Payload: RequestType { }

    func addPayload<T: RequestType>(json: AnyObject)(request: Request<T>) -> Request<Payload>? {
    let req = request.request
    req.setValue("application/json", forHTTPHeaderField: "Content-Type")
    req.HTTPBody = NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(0), error: nil)
    return Request(request: req)
    }

    func postRequest(request: Request<GET>) -> Request<POST>? {
    let req = request.request
    req.HTTPMethod = "POST"
    return Request(request: req)
    }

    func authenticateRequest<T: RequestType>(request: Request<T>) -> Request<Authenticated>? {
    if let token = getToken() {
    let req = request.request
    req.setValue("Token token=\(token)", forHTTPHeaderField: "Authorization")
    return Request(request: req)
    }

    return .None
    }

    func getToken() -> String? {
    return "foo"
    }


    func mutableRequestForPath(path: String) -> Request<GET>? {
    let url = NSURL(string: path)

    if let request = url.map({ NSMutableURLRequest(URL: $0) }) {
    request.setValue("application/vnd.circus+json; version=foobar", forHTTPHeaderField: "Accept")
    request.setValue("gzip;q=1.0,compress;q=0.5", forHTTPHeaderField: "Accept-Encoding")
    return Request(request: request)
    }

    return .None
    }

    let request = mutableRequestForPath("foo") >>- postRequest >>- addPayload([]) >>- authenticateRequest