Search code examples
cocoarestswiftphilips-hue

Example of Swift and a Put request for a RESTful API


I'm trying to learn Swift by creating an OSX app for the Phillips Hue light API. However, and I feel silly here, I can't even get a simple example working. I'm using this library in X Code 6.1: https://github.com/hallas/agent

Here's the code I'm using:

import Foundation



let done = { (response: NSHTTPURLResponse!, data: Agent.Data!, error: NSError!) -> Void in
    // react to the result of your request
};
Agent.put("/api/[username]/lights/2/state", headers: [ "Header": "Value" ],
    data: [ "hue": 35000 ], done: done)

Needless to say its not doing anything. What am I doing wrong?


Solution

  • This is a sample of a PUT operation, using a simple class to wrap the HTTP functionality:

        let url = NSURL(string:"http://example.com")
        let text = "Text to PUT"
        var myData: NSData? = text.dataUsingEncoding(NSUTF8StringEncoding)
        var headers = Dictionary<String, String>()
    
        Http().put(url!, headers: headers, data:myData!) { (result) in           
            if result.success {
                if let jsonObject: AnyObject = result.jsonObject {
                    println(jsonObject)
                }
            }
        }
    
    class Http {
    
    func put(url: NSURL, headers: Dictionary<String, String>, data: NSData, completionHandler: ((result: HttpResult) -> Void)!) {
        action("PUT", url: url, headers: headers, data: data ) { (result) in
            completionHandler(result: result)
        }
    }
    
    func action(verb: String, url: NSURL, headers: Dictionary<String, String>, data: NSData, completionHandler: ((result: HttpResult) -> Void)!) {
        let httpRequest = NSMutableURLRequest(URL: url)
        httpRequest.HTTPMethod = verb
    
        for (headerKey, headerValue) in headers {
            httpRequest.setValue(headerValue, forHTTPHeaderField: headerKey)
        }
        let task = NSURLSession.sharedSession().uploadTaskWithRequest(httpRequest, fromData: data) { (data, response, error) in
            completionHandler(result: HttpResult(data: data, request: httpRequest, response: response, error: error))
        }
        task.resume()
    }
    }
    
    class HttpResult {
    
    var request: NSURLRequest
    var response: NSHTTPURLResponse?
    var data: NSData?
    var error: NSError?
    var statusCode: Int = 0
    var success: Bool = false
    var headers : Dictionary<String, String> {
        get {
            if let responseValue = response {
                return responseValue.allHeaderFields as Dictionary<String,String>
            }
            else {
                return Dictionary<String, String>()
            }
        }
    }
    
    init(data: NSData?, request: NSURLRequest, response: NSURLResponse?, error : NSError?) {
        self.data = data
        self.request = request
        self.response = response as NSHTTPURLResponse?
        self.error = error
        self.success = false
    
        if error != nil {
            println("Http.\(request.HTTPMethod!): \(request.URL)")
            println("Error: \(error!.localizedDescription)")
        }
        else {
            if let responseValue = self.response {
                statusCode = responseValue.statusCode
                if statusCode >= 200 && statusCode < 300 {
                    success = true
                }
                else {
                    println("Http.\(request.HTTPMethod!) \(request.URL)")
                    println("Status: \(statusCode)")
                    if let jsonError: AnyObject = jsonObject {
                        var err: NSError?
                        var errData = NSJSONSerialization.dataWithJSONObject(jsonError, options:NSJSONWritingOptions.PrettyPrinted, error: &err)
                        var errMessage = NSString(data: errData!, encoding: NSUTF8StringEncoding)                     
                        println("Error: \(errMessage)")
                    }
                }
            }
        }
    }
    
    var jsonObject: AnyObject? {
        var resultJsonObject: AnyObject?
        var jsonError: NSError?
        if let contentType = headers["Content-Type"] {
            if contentType.contains("application/json") {
                resultJsonObject = NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments, error: &jsonError) as AnyObject?
            }
        }
        return resultJsonObject
    }    
    }