danutha danutha - 1 month ago 12
Objective-C Question

Alamorefire singleton webservercall class error

Im working on a project in swift 3.0 along with the support of Alamofire framework as to interline my webservercalls. Basically I wants to use a singleton class that I previously used in swift 2.3 where I declare the method, and then in whatever the viewcontroller I wants to execute it I call the method as bellow.

APIManager.sharedInstance.login(username, password: password, completion: { (user,success) in

if success {

}

}) { (error) in


}

My requirement is to get this code work in swift 3.0 so I could carry on the work. Help on this would much appreciate. The code of My singleton class as bellow (this code is in swift 2.3, I want this in 3.0).

import UIKit
import Alamofire
import SwiftyJSON

struct Singleton {
static let instance : APIManager = APIManager()
}

public class APIManager: NSObject {
public class var sharedInstance: APIManager {
return Singleton.instance
}

let manager = Manager()

override init() {

}

//MARK:====Login====

//MARK: methods

func login(username: String, password: String, completion: (user: User, success: Bool) -> (), failed:(error: NSError) -> ()) -> Request {
let urlRequest // Create a URLRequest and pass to the method

return manager.request(urlRequest)
.validate()
.responseJSON { response in
if let error = response.result.error {
failed(error: error)
print(error)
return;
}
let ok = ((response.result.value as! JSONDictionary)["success"] as? Bool)!
let userJson = JSON((response.result.value as! JSONDictionary)["user"]!)

let token = ((response.result.value as! JSONDictionary)["token"] as? String)!
NSUserDefaults.standardUserDefaults().setValue(token, forKey: UserDefaultKey.Token)
NSUserDefaults.standardUserDefaults().synchronize()
let user = User(json: userJson)
completion(user: user,success: ok)

print ("Auth is : \(token)")


}
}
}

Answer

This is my manager in Swift 3.x with Alamofire 4.x and SwiftyJSON. I prefer class methods in place of Singletons.

import UIKit
import Alamofire
import SwiftyJSON

class APIManager: NSObject {

class func apiGet(serviceName:String,parameters: [String:Any]?, completionHandler: @escaping (JSON?, NSError?) -> ()) {

    Alamofire.request(serviceName, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

        switch(response.result) {
        case .success(_):
            if let data = response.result.value{
                let json = JSON(data)
                completionHandler(json,nil)
            }
            break

        case .failure(_):
            completionHandler(nil,response.result.error as NSError?)
            break

        }
    }
}

class func apiPost(serviceName:String,parameters: [String:Any]?, completionHandler: @escaping (JSON?, NSError?) -> ()) {

    Alamofire.request(serviceName, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in

        switch(response.result) {
        case .success(_):
            if let data = response.result.value{
                let json = JSON(data)
                completionHandler(json,nil)
            }
            break

        case .failure(_):
            completionHandler(nil,response.result.error as NSError?)
            break

        }
    }
}

}

Better to provide the name or url of service in controller itself with the apiGet and apiPost methods

How to use it.
In your controller class or button event

First import SwiftyJSON in your controller

import SwiftyJSON

Then call your login service wherever you want

let params = [
        "userName":"abc",
        "password":"abc"
    ]

APIManager.apiPost(serviceName: "yourLoginURL", parameters: params) { (json:JSON?, error:NSError?) in
        if error != nil {
            print(error?.localizedDescription)
            return
        }
        print(json!)
    }
Comments