New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extra argument 'method' in call #1508

Closed
matthiasp42 opened this Issue Sep 11, 2016 · 21 comments

Comments

Projects
None yet
@matthiasp42

matthiasp42 commented Sep 11, 2016

This line doesn't work on 4.0.0:

Alamofire.request("https://httpbin.org/post", method: .post, parameters: [], encoding: JSONEncoding.default)

I get "Extra argument 'method' in call" error.
I'm using XCode8 GM and your latest version.

@thebluepotato

This comment has been minimized.

Show comment
Hide comment
@thebluepotato

thebluepotato Sep 11, 2016

First of all : don't post this here, post it on Stack Overflow and tag it with Alamofire (I'm also monitoring those so you'd get the same answer but others could see it). As stated in the README, Github is for bugs and this isn't one.
Anyhow : parameters is of type Parameters? aka [String : Any]? and therefore giving it [] aka an empty Array is wrong (I'll admit that the error message is very misleading). You can write parameters: [:] (empty Dictionary), write nil or leave the whole parameters part out.

thebluepotato commented Sep 11, 2016

First of all : don't post this here, post it on Stack Overflow and tag it with Alamofire (I'm also monitoring those so you'd get the same answer but others could see it). As stated in the README, Github is for bugs and this isn't one.
Anyhow : parameters is of type Parameters? aka [String : Any]? and therefore giving it [] aka an empty Array is wrong (I'll admit that the error message is very misleading). You can write parameters: [:] (empty Dictionary), write nil or leave the whole parameters part out.

@otherbuns

This comment has been minimized.

Show comment
Hide comment
@otherbuns

otherbuns Sep 11, 2016

I'm getting the same issue, with the same error message ("Extra argument 'method' in call"), with correct parameters: syntax. The exact same argument structure worked before the latest project update. Are you sure this shouldn't be noted as a bug?

Alamofire.request("https://servername.org/post", method: .post, parameters: [:], encoding: JSONEncoding.default)

otherbuns commented Sep 11, 2016

I'm getting the same issue, with the same error message ("Extra argument 'method' in call"), with correct parameters: syntax. The exact same argument structure worked before the latest project update. Are you sure this shouldn't be noted as a bug?

Alamofire.request("https://servername.org/post", method: .post, parameters: [:], encoding: JSONEncoding.default)

@thebluepotato

This comment has been minimized.

Show comment
Hide comment
@thebluepotato

thebluepotato Sep 11, 2016

I'm quite sure, because I'm able to reproduce the issue and fix it with all three options I presented. Nevertheless, I'm happy to help you out if you could post the surrounding code to reproduce the issue with parameters: [:]. And truthfully, I believe leaving out the parameters: part is the most elegant way IMO. Are you using the Alamofire 4.0.0 release?

thebluepotato commented Sep 11, 2016

I'm quite sure, because I'm able to reproduce the issue and fix it with all three options I presented. Nevertheless, I'm happy to help you out if you could post the surrounding code to reproduce the issue with parameters: [:]. And truthfully, I believe leaving out the parameters: part is the most elegant way IMO. Are you using the Alamofire 4.0.0 release?

@matthiasp42

This comment has been minimized.

Show comment
Hide comment
@matthiasp42

matthiasp42 Sep 11, 2016

@thebluepotato Thanks for clarifying when to use Stackoverflow and when to use GitHub.

Turns out my original error was that I was trying to pass a URLRequest and not a URLConvertible. While reproducing I ended up with the string i presented when creating this topic which only led to more confusion. But now it works for me. Thank you.

matthiasp42 commented Sep 11, 2016

@thebluepotato Thanks for clarifying when to use Stackoverflow and when to use GitHub.

Turns out my original error was that I was trying to pass a URLRequest and not a URLConvertible. While reproducing I ended up with the string i presented when creating this topic which only led to more confusion. But now it works for me. Thank you.

@otherbuns

This comment has been minimized.

Show comment
Hide comment
@otherbuns

otherbuns Sep 11, 2016

If you can give a hand even though the issue belongs on Stackoverflow, I truly appreciate it - here's the code I'm running (using Alamofire 4.0.0):

Alamofire.request("http://\(ipAddr)/YamahaRemoteControl/ctrl", method: .post, parameters: [:], encoding: .custom({ (convertible, params) in var mutableRequest = convertible.urlRequest as URLRequest mutableRequest.httpBody = "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>\(input)</Input_Sel></Input></Main_Zone></YAMAHA_AV>".data(using: String.Encoding.utf8, allowLossyConversion: false) return (mutableRequest, nil) } ))

The request sends a UTF8 string to an AV receiver to control the input, volume etc, depending on the content of the string. The code above results in the "Extra argument 'method' in call" error whether I include the parameters: [:] argument or not.

I used the exact same code successfully yesterday, using the swift3 branch via Cocoapods.

otherbuns commented Sep 11, 2016

If you can give a hand even though the issue belongs on Stackoverflow, I truly appreciate it - here's the code I'm running (using Alamofire 4.0.0):

Alamofire.request("http://\(ipAddr)/YamahaRemoteControl/ctrl", method: .post, parameters: [:], encoding: .custom({ (convertible, params) in var mutableRequest = convertible.urlRequest as URLRequest mutableRequest.httpBody = "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>\(input)</Input_Sel></Input></Main_Zone></YAMAHA_AV>".data(using: String.Encoding.utf8, allowLossyConversion: false) return (mutableRequest, nil) } ))

The request sends a UTF8 string to an AV receiver to control the input, volume etc, depending on the content of the string. The code above results in the "Extra argument 'method' in call" error whether I include the parameters: [:] argument or not.

I used the exact same code successfully yesterday, using the swift3 branch via Cocoapods.

@jshier

This comment has been minimized.

Show comment
Hide comment
@jshier

jshier Sep 11, 2016

Contributor

@otherbuns Take a look at our migration guide you'll see that our parameter encoding methods have radically changed for Alamofire 4. You no longer need to use the ugly .custom syntax. Instead you can wrap your encoding logic in a type conforming to ParameterEncoding.

Contributor

jshier commented Sep 11, 2016

@otherbuns Take a look at our migration guide you'll see that our parameter encoding methods have radically changed for Alamofire 4. You no longer need to use the ugly .custom syntax. Instead you can wrap your encoding logic in a type conforming to ParameterEncoding.

@jshier jshier closed this Sep 11, 2016

@jshier jshier added the support label Sep 11, 2016

@thebluepotato

This comment has been minimized.

Show comment
Hide comment
@thebluepotato

thebluepotato Sep 11, 2016

@otherbuns Any time one argument is of the wrong type, the Swift interpreter here believes that you're wrongly using request(urlRequest:URLRequestConvertible) and therefore believes there's an extra method: argument.
What you should have done is read the release notes. Because one of the very last-minute and very nice additions to 4.0.0 is the ParameterEncoding protocol. More info here #1465 and here https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol and mostly here https://github.com/Alamofire/Alamofire/#custom-encoding. Basically, you have to write your own struct conforming to ParameterEncoding with a function returning the encoded parameters.
EDIT: Oh well, I'm too slow to type 😅, already closed!

thebluepotato commented Sep 11, 2016

@otherbuns Any time one argument is of the wrong type, the Swift interpreter here believes that you're wrongly using request(urlRequest:URLRequestConvertible) and therefore believes there's an extra method: argument.
What you should have done is read the release notes. Because one of the very last-minute and very nice additions to 4.0.0 is the ParameterEncoding protocol. More info here #1465 and here https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol and mostly here https://github.com/Alamofire/Alamofire/#custom-encoding. Basically, you have to write your own struct conforming to ParameterEncoding with a function returning the encoded parameters.
EDIT: Oh well, I'm too slow to type 😅, already closed!

@otherbuns

This comment has been minimized.

Show comment
Hide comment
@otherbuns

otherbuns Sep 11, 2016

Now that you point it out, I really wonder how I managed to miss it. Thanks a lot for your help, even if the answer was right before my nose!

otherbuns commented Sep 11, 2016

Now that you point it out, I really wonder how I managed to miss it. Thanks a lot for your help, even if the answer was right before my nose!

@fulldecent

This comment has been minimized.

Show comment
Hide comment
@fulldecent

fulldecent Sep 20, 2016

Contributor

@thebluepotato Thank you for clarifying about Swift's non helpful response.

My issue was that Alamofire will not accept parameters which are arrays of the form [1,2,3], they have to be dictionaries like ["list": [1,2,3]].

Contributor

fulldecent commented Sep 20, 2016

@thebluepotato Thank you for clarifying about Swift's non helpful response.

My issue was that Alamofire will not accept parameters which are arrays of the form [1,2,3], they have to be dictionaries like ["list": [1,2,3]].

@jinthreek89

This comment has been minimized.

Show comment
Hide comment
@jinthreek89

jinthreek89 Oct 17, 2016

Hi, guys. I should must use array value([Int]) for parameter. How to solve my problem?
Please help me.

jinthreek89 commented Oct 17, 2016

Hi, guys. I should must use array value([Int]) for parameter. How to solve my problem?
Please help me.

@kevinlee85

This comment has been minimized.

Show comment
Hide comment
@kevinlee85

kevinlee85 Nov 20, 2016

Hi Guys:
I also meet Extra argument 'method' in call, still cannot find one solution.

kevinlee85 commented Nov 20, 2016

Hi Guys:
I also meet Extra argument 'method' in call, still cannot find one solution.

@cnoon

This comment has been minimized.

Show comment
Hide comment
@cnoon

cnoon Nov 20, 2016

Member

Hey @kevinlee85, the easiest way to fix your issue is to comment the code out and rebuild it with auto-complete. The error is usually pretty obvious when you do it that way.

Member

cnoon commented Nov 20, 2016

Hey @kevinlee85, the easiest way to fix your issue is to comment the code out and rebuild it with auto-complete. The error is usually pretty obvious when you do it that way.

@Kandhal

This comment has been minimized.

Show comment
Hide comment
@Kandhal

Kandhal Nov 21, 2016

This one worked for me.
No need to remove encoding parameter

Swift 3.0

Alamofire.request("https://yourServiceURL.com", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse) in

    switch(response.result) {
    case .success(_):
        if let data = response.result.value{
            print(response.result.value)
        }
        break

    case .failure(_):
        print(response.result.error)
        break

    }
}

and make sure that the parameters are of type

[String:Any]?
In case of Get

Alamofire.request("https://yourGetURL.com", method: .get, parameters: ["":""], encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse) in

    switch(response.result) {
    case .success(_):
        if let data = response.result.value{
            print(response.result.value)
        }
        break

    case .failure(_):
        print(response.result.error)
        break

    }
}

Even works with

JSONEncoding.default
For Headers

If you are passing headers, make sure their type should be [String:String]

Go through the Parameter Encoding Link https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol

Kandhal commented Nov 21, 2016

This one worked for me.
No need to remove encoding parameter

Swift 3.0

Alamofire.request("https://yourServiceURL.com", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse) in

    switch(response.result) {
    case .success(_):
        if let data = response.result.value{
            print(response.result.value)
        }
        break

    case .failure(_):
        print(response.result.error)
        break

    }
}

and make sure that the parameters are of type

[String:Any]?
In case of Get

Alamofire.request("https://yourGetURL.com", method: .get, parameters: ["":""], encoding: URLEncoding.default, headers: nil).responseJSON { (response:DataResponse) in

    switch(response.result) {
    case .success(_):
        if let data = response.result.value{
            print(response.result.value)
        }
        break

    case .failure(_):
        print(response.result.error)
        break

    }
}

Even works with

JSONEncoding.default
For Headers

If you are passing headers, make sure their type should be [String:String]

Go through the Parameter Encoding Link https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#parameter-encoding-protocol

@maningyt

This comment has been minimized.

Show comment
Hide comment
@maningyt

maningyt Apr 2, 2017

@cnoon I'm having the same problem. I read the doc and added extra struct as suggested in the readingMe.
//Add below two struct for data upload efficiency test
struct JSONDocumentArrayEncoding: ParameterEncoding {
private let array: [Document]
init(array:[Document]) {
self.array = array
}
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = urlRequest.urlRequest

    let data = try JSONSerialization.data(withJSONObject: array, options: [])
    
    if urlRequest!.value(forHTTPHeaderField: "Content-Type") == nil {
        urlRequest!.setValue("application/json", forHTTPHeaderField: "Content-Type")
    }
    
    urlRequest!.httpBody = data
    
    return urlRequest!
}

}
Then use this method for request using Alamofire.SessionManager as custom manager, parameter is an array of document object. The purpose of this custom encoding is to encode the array of objects.

request = customAlamofireManager.request(
ServerURL,
method: .post,
parameters: [documents],
encoding: JSONDocumentArrayEncoding,
headers: headers
)
request!.validate{ request, response, data in
return .success
}
.responseJSON {

Same error, because param is not a dictionary. However there need a way to pass in this array param. I'm also having another Struct to make Gzip array of objects. I get the same error as this one. There must be a way to pass in body data for encode.
Thanks

maningyt commented Apr 2, 2017

@cnoon I'm having the same problem. I read the doc and added extra struct as suggested in the readingMe.
//Add below two struct for data upload efficiency test
struct JSONDocumentArrayEncoding: ParameterEncoding {
private let array: [Document]
init(array:[Document]) {
self.array = array
}
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = urlRequest.urlRequest

    let data = try JSONSerialization.data(withJSONObject: array, options: [])
    
    if urlRequest!.value(forHTTPHeaderField: "Content-Type") == nil {
        urlRequest!.setValue("application/json", forHTTPHeaderField: "Content-Type")
    }
    
    urlRequest!.httpBody = data
    
    return urlRequest!
}

}
Then use this method for request using Alamofire.SessionManager as custom manager, parameter is an array of document object. The purpose of this custom encoding is to encode the array of objects.

request = customAlamofireManager.request(
ServerURL,
method: .post,
parameters: [documents],
encoding: JSONDocumentArrayEncoding,
headers: headers
)
request!.validate{ request, response, data in
return .success
}
.responseJSON {

Same error, because param is not a dictionary. However there need a way to pass in this array param. I'm also having another Struct to make Gzip array of objects. I get the same error as this one. There must be a way to pass in body data for encode.
Thanks

@maningyt

This comment has been minimized.

Show comment
Hide comment
@maningyt

maningyt Apr 2, 2017

@thebluepotato Did as same as the instruction suggested, but how to pass in the array parameter? Thanks

maningyt commented Apr 2, 2017

@thebluepotato Did as same as the instruction suggested, but how to pass in the array parameter? Thanks

@maningyt

This comment has been minimized.

Show comment
Hide comment
@maningyt

maningyt Apr 3, 2017

Answer my own question here, find a way to pass in custom encoded request to Alamofire.DataRequest to escape the above mentioned method with parameters, which is not used anyway.
func uploadBatchDocumentsWithDocs(_ documents: [Any]) {
let headers = NetworkManager.sharedInstance.headers
var urlRequest = URLRequest(url: URL(string: (ServerURL + Api))!)
urlRequest.httpMethod = "post"
urlRequest.allHTTPHeaderFields = headers
let jsonArrayencoding = JSONDocumentArrayEncoding(array: documents)
let jsonAryEncodedRequest = try? jsonArrayencoding.encode(urlRequest, with: nil)

    var request: Alamofire.DataRequest? = customAlamofireManager.request(jsonAryEncodedRequest!)
    request?.validate{request, response, data in
        return .success
        }
        .responseJSON {

...
}

maningyt commented Apr 3, 2017

Answer my own question here, find a way to pass in custom encoded request to Alamofire.DataRequest to escape the above mentioned method with parameters, which is not used anyway.
func uploadBatchDocumentsWithDocs(_ documents: [Any]) {
let headers = NetworkManager.sharedInstance.headers
var urlRequest = URLRequest(url: URL(string: (ServerURL + Api))!)
urlRequest.httpMethod = "post"
urlRequest.allHTTPHeaderFields = headers
let jsonArrayencoding = JSONDocumentArrayEncoding(array: documents)
let jsonAryEncodedRequest = try? jsonArrayencoding.encode(urlRequest, with: nil)

    var request: Alamofire.DataRequest? = customAlamofireManager.request(jsonAryEncodedRequest!)
    request?.validate{request, response, data in
        return .success
        }
        .responseJSON {

...
}

@popsware

This comment has been minimized.

Show comment
Hide comment
@popsware

popsware Jun 30, 2017

FTR, this happened to me when i was using an optional variable in the parameters attribute
variable?.toJSON()

popsware commented Jun 30, 2017

FTR, this happened to me when i was using an optional variable in the parameters attribute
variable?.toJSON()

@maningyt

This comment has been minimized.

Show comment
Hide comment
@maningyt

maningyt Jun 30, 2017

@popsware You can use the method I mentioned above to avoid that. It works.

maningyt commented Jun 30, 2017

@popsware You can use the method I mentioned above to avoid that. It works.

@Innolabdev

This comment has been minimized.

Show comment
Hide comment
@Innolabdev

Innolabdev Feb 20, 2018

if you use headers you must define let headers : [String : String] = not just let headers =

Innolabdev commented Feb 20, 2018

if you use headers you must define let headers : [String : String] = not just let headers =

@pinoy4

This comment has been minimized.

Show comment
Hide comment
@pinoy4

pinoy4 Mar 17, 2018

As @Innolabdev mentioned, HTTPHeaders is not of type [String: Any]? but rather public typealias HTTPHeaders = [String: String] ...that's why it wasn't working for me

pinoy4 commented Mar 17, 2018

As @Innolabdev mentioned, HTTPHeaders is not of type [String: Any]? but rather public typealias HTTPHeaders = [String: String] ...that's why it wasn't working for me

@ExplosiveBattery

This comment has been minimized.

Show comment
Hide comment
@ExplosiveBattery

ExplosiveBattery Apr 6, 2018

Okay, I find a interesting problem: ( I use swift4 and Alamofire4.7)
Alamofire.request(Constraint.PIC_STAR_URL, method: .post, parameters: params, encoding:.httpBody, headers:nil) will touch the error
Alamofire.request(Constraint.PIC_STAR_URL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers:nil) will touch no error
So, don't use the abbreviation of swift.

ExplosiveBattery commented Apr 6, 2018

Okay, I find a interesting problem: ( I use swift4 and Alamofire4.7)
Alamofire.request(Constraint.PIC_STAR_URL, method: .post, parameters: params, encoding:.httpBody, headers:nil) will touch the error
Alamofire.request(Constraint.PIC_STAR_URL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers:nil) will touch no error
So, don't use the abbreviation of swift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment