I've been trying to resolve this error when I call Alamofire by fixing parameter types, changing the response-type from responseString to responseJSON and force-unwrapping variables. I've checked out the following answers and haven't had any luck:
Alamofire, Extra argument 'method' in call
Extra argument 'method' in call of Alamofire
Swift - Extra Argument in call
Swift 3.0, Alamofire 4.0 Extra argument 'method' in call
Here's my code:
func checkServerForLogin(email: String, password: String) {
let parameters = [
"email": email,
"password": password
] as [String : Any]
Alamofire.request(URL_CHECK_LOGIN, method: .post, parameters: parameters).responseString { (response) in
if response.result.error == nil {
guard let data = response.data else {
return
}
do {
print("LOGIN_RESULT")
print(response)
} catch {
print("ERROR: \(error)")
}
} else {
debugPrint(response.result.error as Any)
}
}
}
Then I call it...
AuthService.instance.checkServerForLogin(email: email_input, password: password_input) { response, error in
if ((response) != nil){
}
}
I keep receiving Extra argument 'password' in call. Any help in resolving this would be greatly appreciated.
you have create simple method.you need to create completion block parameter
try this code
class func checkServerForLogin(_ url:String,email: String, password: String,success:#escaping (JSON) -> Void, failure:#escaping (Error) -> Void) {
let parameters = [
"email": email,
"password": password
] as [String : Any]
Alamofire.request(url, method: .post, parameters: parameters).responseString { (response) in
if response.result.isSuccess {
let resJson = JSON(response.result.value!)
success(resJson)
}
if response.result.isFailure {
let error : Error = response.result.error!
failure(error)
}
}
}
AuthService.checkServerForLogin(URL_CHECK_LOGIN, email: email_input, password: password_input, success: { (responseObject) in
print(responseObject)
}) { (error) in
print(error.localizedDescription)
}
Related
This question already has answers here:
Returning data from async call in Swift function
(13 answers)
Closed 4 years ago.
I'm trying to verify a login and return a boolean value from my function accordingly, but my return statement keeps getting executed before the web service function is completed, even if I use an async method. I am using both Alamofire and SwiftyJSON.
I'm attaching my code below. Any help would be appreciated!
Thanks.
func checkUs (name: String, password: String) -> Bool
{
bool authen = false
DispatchQueue.global(qos: .userInitiated).async {
let jsonDic : [String: String] = ["email": name, "pass": password]
Alamofire.request("enter URL here", method: .post, parameters: jsonDic, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
switch(response.result) {
case .success(let sentJSON):
let gotJSON = JSON (sentJSON)
print (gotJSON[0]["status"].boolValue)
authen = gotJSON[0]["status"].boolValue
case .failure(let err):
print(err)
}
print ("First ", authen)
}
}
print ("Second", authen)
return authen
//return true
Log Output:
Second false
true
First true
You need completion , also Alamfire runs asynchronously no need for global queue
func checkUs (name: String, password: String,completion: #escaping (_ status: Bool,_ err:Error?) -> Void) {
bool authen = false
let jsonDic : [String: String] = ["email": name, "pass": password]
Alamofire.request("enter URL here", method: .post, parameters: jsonDic, encoding: JSONEncoding.default, headers: nil).responseJSON { (response) in
switch(response.result) {
case .success(let sentJSON):
let gotJSON = JSON (sentJSON)
print (gotJSON[0]["status"].boolValue)
authen = gotJSON[0]["status"].boolValue
completion(authen,nil)
case .failure(let err):
print(err)
completion(authen,err)
}
print ("First ", authen)
}
print ("Second", authen)
}
//
call it like this
self.checkUs(name: "endedName", password: "sendedPassword") { (status, error) in
if let err = error {
}
else
{
}
}
Trying to figure out the reason as i tried removing the whole onError block, it resulted in the error for the onCompleted block.
public static func register(phone_number: String, password: String) -> Observable<(HTTPURLResponse, NSDictionary)> {
/*
Registers a user using their phone number and password
*/
let parameters: Parameters = ["phone_number": phone_number, "password": password]
return Observable.create({ (observer) -> Disposable in
Alamofire.request(Router.register(parameters: parameters))
.rx
.responseJSON()
.subscribe(onNext: { (response, json) in
if let data = json as? NSDictionary {
if let returned_phone_number = data["phone_number"] as? String
{
if returned_phone_number == phone_number {
print("success")
} else {
print(returned_phone_number)
}
}
observer.on(.next(response, data))
}
}, onError: { (error) in \\ error here 'extra argument "onError" calls'
observer.on(.error(error))
}, onCompleted: { (response) in
observer.on(.completed)
}, onDisposed: nil)
})
}
The problem is in your onCompleted closure. It must not have any parameters whereas in your code it has one (response). You may change it to
onCompleted: {
observer.on(.completed)
}
I am very new to swift. I have a method like this.
public func prepareUrl (appendString:String,bindedParams:String,isAuthorized:Bool,isGet:Bool,jsonBody:[String:String],completion:#escaping(String)->Void)
{
let baseUrl=Bundle.main.value(forKey: "GlobalURL")
let urlString=baseUrl as! String+appendString as String+bindedParams as String
Alamofire.request(urlString, method: .get, parameters: nil, encoding: JSONEncoding.default)
.downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
print("Progress: \(progress.fractionCompleted)")
}
.validate { request, response, data in
// Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
return .success
}
.responseJSON { response in
debugPrint(response)
}
}
I have no idea how to call this method since it's having a completion handler part too. How can I call this method. Please help me.
Thanks
To call method like this:
self.prepareUrl(appendString: "www.some.com/api/likeLogin", bindedParams: "name=lee", isAuthorized: false, isGet: true, jsonBody: ["key":"value"]) { (returnString) in
if returnString == "someValue" {
//do something
}
else{
}
}
And in the method, you should call the completion to return value, like:
.responseJSON { response in
completion("aReturnString")
}
Although the method name is prepareUrl, it actually requests the WebApi, so it's better to rename it to request.
Try this :
NOTE :This answer is for example . You need to change as per your needs
func getResponse(url: String, method : HTTPMethod, parameter : [String : AnyObject], Alert : Bool, callback: #escaping responseHandler) -> Void{
Alamofire.request(API_PREFIX + url, method: method, parameters: parameter).validate().responseJSON { response in
switch response.result {
case .success:
if let result = response.result.value {
let JSON = result as! [String : AnyObject]
print("\(JSON as AnyObject)")
callback(JSON as AnyObject, true)
}
case .failure(let error):
print(error)
callback({} as AnyObject, false)
}
}
}
Calling of method using closure
self.getResponse(url: "", method: .post, parameter: ["Email" : "" as AnyObject, "Password" : "" as AnyObject], Alert: true) { (responseObject, success) in
if success{
}
}
I'm currently trying to call a prepareForSegue method in an AlamoFire completion handler but it's not being called. Here is my code:
func loginMember (username: String, password: String, completionHandler: (String?, ErrorType?) -> ()) {
let headers = [
"Cache-Control": "no-cache",
"Content-Type": "application/json"
]
let parameters: [String: AnyObject] = [
"grant_type" : "password",
"username" : username,
"password" : password,
]
Alamofire.request(.POST, "\(baseURL)/oauth2/token", parameters: parameters, encoding: .JSON, headers: headers)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
guard let value = response.result.value else {
completionHandler(nil, response.result.error)
return
}
let swiftyJsonVar = JSON(value)
accessToken = swiftyJsonVar["access_token"].stringValue
print("This is the login response:\(swiftyJsonVar)")
case .Failure(let error):
print("Sorry there was an error: \(error)")
return
}
}
}
This is what it looks like when called:
loginMember(username, password: password, completionHandler: { error in
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("loginToHomeSegue", sender: self)
}
}
)
Any ideas as to why the performSegueWithIdentifier isn't being called?
You're only calling your completion handler in the case where you enter your guard statement. You need to add calls for the case where you get your access token and your error case.
Alamofire.request(.POST, "\(baseURL)/oauth2/token", parameters: parameters, encoding: .JSON, headers: headers)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
guard let value = response.result.value else {
completionHandler(nil, response.result.error)
return
}
let swiftyJsonVar = JSON(value)
accessToken = swiftyJsonVar["access_token"].stringValue
print("This is the login response:\(swiftyJsonVar)")
// Got the token, call handler
completonHandler(accessToken, nil)
case .Failure(let error):
print("Sorry there was an error: \(error)")
// Got an error, call handler
completionHandler(nil, error)
return
}
}
I have this class for authenticating a user against my backend.
class BackendService {
class func performLogin(#email: String, password: String, success:((res: NSHTTPURLResponse, json: JSON, statusCode: HTTPStatus))->(), failure: (NSError)->()) {
let loginURL = baseURL + "/login"
let parameters = ["email": email, "password": password]
Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { (req, res, json, err) in
if(err != nil) {
let response = (error: err!)
failure(response)
}
else {
if let httpStatus = HTTPStatus(rawValue: res!.statusCode) {
let response = (res: res, json: JSON(json!) , statusCode: httpStatus)
success(response)
}
}
}
}
In success(response) I am getting Type of expression is ambiguous without more context. Any ideas?
Is there a better, more Swifty way, to write this class?
The reason it wasn't compiling was that you had an extra set of parentheses around the success tuple declaration. If you remove them, then it will compile. Here's an updated version of your function with as few of changes as possible that compiles.
You need to make sure you have baseURL defined somewhere.
class func performLogin(#email: String, password: String, success:(res: NSHTTPURLResponse, json: JSON, statusCode: HTTPStatus)->(), failure: (NSError)->()) {
let loginURL = baseURL + "/login"
let parameters = ["email": email, "password": password]
Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { (req, res, json, err) in
if (err != nil) {
let response = (error: err!)
failure(response)
}
else {
if let httpStatus = HTTPStatus(rawValue: res!.statusCode) {
let response = (res: res!, json: JSON(json!), statusCode: httpStatus)
success(response)
}
}
}
}
Here's an updated version of your original function that is certainly cleaner, but isn't entirely safe yet. A good rule of thumb is the more exclamation marks, the more risk.
typealias LoginSuccessHandler = (NSHTTPURLResponse, JSON, HTTPStatus) -> Void
typealias LoginFailureHandler = (NSError) -> Void
class func performLogin(#email: String, password: String, success: LoginSuccessHandler?, failure: LoginFailureHandler?) {
let loginURL = baseURL + "/login"
let parameters = ["email": email, "password": password]
Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { request, response, json, error in
if let error = error {
failure?(error)
} else {
if let httpStatus = HTTPStatus(rawValue: response!.statusCode) {
success?(response!, JSON(json!), httpStatus)
}
}
}
}
You should really take a look at #mattt's awesome validation logic built into the Alamofire.Request class. That way you could remove the need for the HTTPStatus enumeration altogether.
public func validate() -> Self
public func validate(contentType array: [String]) -> Self
public func validate(statusCode array: [Int]) -> Self
public func validate(statusCode range: Range<Int>) -> Self
public func validate(validation: Validation) -> Self