danutha danutha - 1 month ago 11
Objective-C Question

Alamofire 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