Web dev

REST API Calls using SWIFT


One of the cool features of the brand-new SWIFT language is that you can use Objective-C objects inside Swift. Yes, everything from Objective-C works on Swift.

We made a RESTManager in Objective-C and now we have to migrate it to Swift. If you use things in Swift like Tuples or Dictionaries, then it will not work the way it is used to. We realized that we could use a NSMutableDictionary in our parameters, thus making it easier and faster.

In Swift we will only use one file (.swift) type and we are going to forget about the headers.

Note:
var is used to declare mutable objects, let is used to declare constant objects (immutable). We are also going to see the differences between Swift and Objective-C. Let’s check the following example, then break it apart and explain how it works.


import UIKit

class RESTManager
{
class var SERVER_URL : String {
    return "http://YourURL/api"
}

class func sendData (data:NSMutableDictionary, service:String, method:String, accessToken:String, accessTokenInHeader:Bool, callback: (AnyObject) -> ())
{
    var url:NSURL?
    var request:NSMutableURLRequest?
    if method != "GET"
    {
        url = NSURL(string: self.SERVER_URL + "/" + service)
    }
    else
    {
        url = NSURL(string: self.SERVER_URL + "/" + service + ".json?access_token=" + accessToken)
    }
    request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 25)
    if method != "GET"
    {
        var jsonError: NSError?
        let jsonData = NSJSONSerialization.dataWithJSONObject(data, options: nil, error: &jsonError)
        var jsonLength = String(format:"%ld", jsonData!.length)
        request?.setValue(jsonLength, forHTTPHeaderField: "Content-Length")
        request?.setValue("json", forHTTPHeaderField: "Data-Type")
        request?.HTTPBody = jsonData
    }
    request?.HTTPMethod = method
    request?.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request?.setValue("application/json", forHTTPHeaderField: "Accept")

    let queue:NSOperationQueue = NSOperationQueue()
    NSURLConnection.sendAsynchronousRequest(request!, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        var err: NSError?
        if err?.localizedDescription != nil
        {
            callback(false)
        }
        else
        {
            var jsonResult:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
            callback(jsonResult)
        }
    })
}

Ok, let’s check how each part works:

  • First, be sure to import the Foundation Framework (It implicitly calls all NS objects to be used in our class).
  • Define our SERVER_URL as class var. It was used as a #define in Objective-C
  • Define our class func named sendData. It was used as + class in Objective-C.
  • Check if our Method will be other than “GET” and assign the right URL
  • Then, add the request values, such as “Content-Length”, “Data Type”, “Content-Type”, etc (These are just the header vars that our server will accept)
  • Create a queue operation and send an async request to our server (I really prefer async to make sure I’m waiting for the response).
  • Check if there are no errors.
  • Send a closure function with a value. It was Block in Objective-C. It could be a bool object or a dictionary for further use.

How to use:

In a new class, usually a ViewController, we can use our Class Method without any import statement, just call it for example:


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    var dictUser:NSMutableDictionary = NSMutableDictionary()
    dictUser.setObject("user@example.com", forKey: "email")
    dictUser.setObject("passExample", forKey: "password")
    var dictToSend:NSMutableDictionary = NSMutableDictionary()
    dictToSend.setObject(dictUser, forKey: "login_user")
    RESTManager.sendData(dictToSend, service: "login", method: "POST", accessToken: "", accessTokenInHeader: false) { (result) -> () in
        println("login with result: \(result)")
    }
}

Here we create our JSON structure to be sent to our server, make the call, attach parameters and receive a result in bool or Dictionary format. At this point, we can have some more validations, but this is the generic way.

Give it a try and let me know your comments.

Thanks for reading!

Best Practices
8 Tips For Bootstrap
Beginner
Administrate review
Javascript
De Código, Café y Cervezas 05 – ReactJS + AngularJS (Parte 3)