Rahul Rahul - 3 months ago 20
iOS Question

Swift REST API call in singleton class and use of protocol

I am calling rest api using

singleton
class as I need to call this api from 3-4 view controllers. To pass the data, I implemented one protocol method also.
I am not sure this is the right way of passing data and use of singleton class. Could anyone please guide me in this? Please guide me if I am missing or doing wrong in the code. I appreciate your time and suggestions.

//This is my NetworkService class

protocol NetworkServicesDelegate {
// protocol method
func serviceData(arrayData:NSArray)
}

class NetworkServices:NSObject{

static let sharedInstance = NetworkServices()

var delegate: NetworkServicesDelegate?
var dataArray: NSArray?

func getData(paramValue : String,apiName:String)
{
let configURL = NSBundle.mainBundle().objectForInfoDictionaryKey("ConfigURL") as! String
guard let url = NSURL(string: configURL+"/"+apiName) else {
print("Error: cannot create URL")
return
}

let request = NSMutableURLRequest(URL:url)
let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())

request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let params = ["myKey":paramValue]
let valid = NSJSONSerialization.isValidJSONObject(params)
print(valid)

request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(params, options: [])

let task = defaultSession.dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in

if let HTTPResponse = response as? NSHTTPURLResponse {
let statusCode = HTTPResponse.statusCode

if statusCode == 200 {

self.dataArray = try! NSJSONSerialization.JSONObjectWithData(data!, options: [] ) as! NSArray
self.serviceData(self.dataArray!)
}
}

})
task.resume()
}

private func serviceData(serviceDataArray: NSArray){
guard self.delegate != nil else {
return
}
delegate?.serviceData(serviceDataArray)
print("serviceDataArray : \(serviceDataArray)")
}

}

Answer

You can follow the following approach:

  • Make a static or class function and take the delegate as an additional parameter
  • Call the delegate function after the data is download from the api in competition handler.
  • And from any of the view controller call this function like this:

    NetworkServices.getData("yourparam", apiName: "yourAPINAME", delegate: self)

Modified NetworkServices class code below.:

class NetworkServices:NSObject{
class func getData(paramValue : String,apiName:String, delegate:NetworkServicesDelegate?)
{
    let configURL = NSBundle.mainBundle().objectForInfoDictionaryKey("ConfigURL") as! String
    guard let url = NSURL(string: configURL+"/"+apiName) else {
        print("Error: cannot create URL")
        return
    }

    let request = NSMutableURLRequest(URL:url)
    let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())

    request.HTTPMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let params = ["myKey":paramValue]
    let valid = NSJSONSerialization.isValidJSONObject(params)
    print(valid)

    request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(params, options: [])

    let task = defaultSession.dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in

        if let HTTPResponse = response as? NSHTTPURLResponse {
            let statusCode = HTTPResponse.statusCode

            if statusCode == 200 {

                let dataArray:NSArray = try! NSJSONSerialization.JSONObjectWithData(data!, options: [] ) as! NSArray

                delegate?.serviceData(dataArray)
            }
        }

    })
    task.resume()
}   }