0

How can I make a function to call RESTful api through NSURLSESSION that can be used on every controller in swift iOS i.e. singleton object for everywhere in app This is the Code I came up with. But as soon as i call the method it crashes cause till return statement the jsonresponse is empty.

func apicall (mainurl : String, method :String,params :String ) -> NSDictionary{

    var jsonresponse = NSDictionary()
    let url:NSURL = NSURL(string: mainurl)!
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = method
    //        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let paramString = params
    request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.dataTaskWithRequest(request) {
        (
        let data, let response, let error) in
        enum JSONError: String, ErrorType {
            case NoData = "ERROR: no data"
            case ConversionFailed = "ERROR: conversion from JSON failed"
        }
        do{
            guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
                print("error")
                throw JSONError.NoData
            }
            print("data = \(data), response = \(response) , error = \(error)")


            guard let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary else {
                throw JSONError.ConversionFailed
            }
            jsonresponse = json

        }
        catch let error as JSONError {
            print(error.rawValue)
        } catch let error as NSError {
            print(error.debugDescription)
        }
    }
    task.resume()

    return jsonresponse
}

}

Arun kumar
  • 55
  • 1
  • 9
  • `guard let _:NSData, let _:NSURLResponse = response` I see this nonsense piece of code regularly. I don't know from what "popular" tutorial or answer it comes from, but I strongly suggest you never use this again and use proper unwrapping of values instead. Don't trust random tutorials on the Web, most are simply mediocre, others are just wrong. – Eric Aya Jun 27 '16 at 08:19
  • @EricD I guess this code checks whether I got data or response back from the url and if there is any error or not. please provide me with a more nicer code if available. TIA – Arun kumar Jun 27 '16 at 09:28
  • Better example [here](http://stackoverflow.com/a/31808605/2227743). See how we actually *use* the result of `guard` instead of ignoring it. – Eric Aya Jun 27 '16 at 10:54
  • @EricD visited the link you've provided but i couldn't spot the difference as I'm also using the custom error type for guard and the only difference was that you was initializing the variable to check if it was nil or not. Please do tell the difference so that i can understand the concept well – Arun kumar Jun 27 '16 at 11:21
  • That's my point. Instead of doing `guard let _:NSData = data` then `data!`, you should safely unwrap with `guard let data = data`. Same idea applies for `response`. There's also the problem of declaring the `enum JSONError` inside the task - it should be outside. Etc. In short: this tutorial code is full of mistakes, don't use it as an example of good code, that was my whole point. :) – Eric Aya Jun 27 '16 at 11:24
  • @EricD Thanks so much for elaborating it for me. Now i understood your point :D – Arun kumar Jun 27 '16 at 11:31

1 Answers1

0

NSUrlSession Reference

1.Shared seesion return default session which singleton object. if you want to use own session then create a method for return singleton of the session.

func restAPICall(requestUrl:NSURL, httpMethod:String, params:NSDictionary)
        {
            let session = NSURLSession.sharedSession()
            var dataTask: NSURLSessionDataTask;
            do
            {
                let httpData = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
                let request = NSMutableURLRequest.init(URL: requestUrl)
                request.addValue("application/json", forHTTPHeaderField: "Content-Type");
                request.HTTPBody = httpData
                request.HTTPMethod = "POST"

                dataTask = session.dataTaskWithRequest(request){(data, response, error) in

                    do
                    {
                        let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves)
                        print("\(ViewController.count)----------\n" + jsonData.description + "\n--------------\n");
                        ViewController.count = ViewController.count + 1

                    }
                    catch
                    {
                        print(error)
                    }
                }


                dataTask.resume();
            }
            catch
            {
                print(error)
            }
        }
Raj Aggrawal
  • 761
  • 1
  • 6
  • 21
  • Can modify the session configuration as per your requirements but it is recommended to use singleton object for the session – Raj Aggrawal Jun 24 '16 at 10:53
  • How will I get the response? I can not see any callback – Amit Singh Jun 25 '16 at 05:30
  • @RajAggrawal hey there sorry for my late response. Actually i have implemented this but the main problem is how do i get the response back where i have called the function – Arun kumar Jun 27 '16 at 06:02