Getting error while calling Alamofire request method in the latest version(4.0.0).
The syntax is:
Alamofire.request(urlString,method: .post, parameters: requestParams, encoding: .JSON, headers: [:])
the type of requestParam is [String:Any]
I got the issue, I have to use JSONEncoding.default instead of .JSON, so the new syntax is
Alamofire.request(urlString,method: .post, parameters: requestParams, encoding: JSONEncoding.default, headers: [:])
I can only refer you to: https://github.com/Alamofire/Alamofire/issues/1508#issuecomment-246207682
Basically, if one of your parameters is of the wrong type, the swift compiler will assume you're using request(urlRequest:URLRequestConvertible) and then, the method is an extra argument
Go over that parameters again and make sure all is of correct type (Parameters?, ParameterEncoding, and HTTPHeaders)
I was having the same issue, the problem is at parameters type, it should be of type [String: Any]. After I made this change, it worked for me.
Alamofire.request(youUrl, method: .post, parameters: param as? [String: Any], encoding: JSONEncoding.default, headers: [:])
.responseJSON { response in
It means that some of the parameters type are wrong, check that you are sending these values:
url: String
method: HTTPMethod (E.g: .post)
parameters: [String:Any]
encoding: ParameterEncoding (E.g: JSONEncoding.default)
headers: [String: String]
Updated for Swift 3:
let requestString = "https://thawing-inlet-46474.herokuapp.com/charge.php"
let params = ["stripeToken": token.tokenId, "amount": "200", "currency": "usd", "description": "testRun"]
Alamofire.request(requestString,method: .post, parameters: params, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print("response : \(response.result.value)")
}
break
case .failure(_):
print("Failure : \(response.result.error)")
break
}
}
Make sure your parameters is [String: Any]
i.e
let parameters = ["foo": "bar"]
Not:
let parameters : Parameter = ["foo": "bar"]
You are getting that error because of the wrong data types.
Parameters Type should be [String : Any] and parameters type shouldn't be an optional.
Header Type should be [String : String] or nil and header type shouldn't be an optional as well.
Hope it helps. :-)
I fixed this by ensuring my requestUrls are strings, and not URL types. Also I removed parameter arguments for when parameter was nil.
E.g.
Alamofire.request(requestUrl, method: .get, encoding: URLEncoding.default)
Almofire methods changed in Swift 3 as the following:
Reorder parameters (url then method type).
Change Encoding Enum to be "JSONEncoding.default" for example.
This is a family of functions that are very similar, which makes the compiler think you're trying to use a different function. Double check that ALL of the arguments you're supplying are the CORRECT TYPE that is expected. For example I was passing [String:Any] for the variant with headers, which expected [String:String] and got the same error.
It is always because im using optional variables in any of the parameters
I was facing same problem And try with all answer as previously post here, And then I got the solution and reason of this problem .
This is happened due to pass the wrong object parse in the request, and finally the solution --
theJSONText -- JSON string
urlStr -- URL string
let urlEncoadedJson = theJSONText.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
let urls = NSURL(string:"urlStr\(urlEncoadedJson ?? "")")
let method: HTTPMethod = .get
Alamofire.request(urls! as URL, method: method, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil
{
// write your code here
}
break
case .failure(_):
if response.result.error != nil
{
print(response.result.error!)
}
break
}
}
Note - There is no param in my URL .
My problem was in optional parameters in the headers that were not unwrapped.
Alamofire.request(url, method: .post, parameters: parameters, encoding:
JSONEncoding.default, headers: [:]).responseJSON
{ response in
switch (response.result) {
case .success:
print(response)
break
case .failure:
print(Error.self)
}
}
just make sure all the parameters are in the correct format , most importantly the parameters must be in [String:Any] type array.
Related
I'm using NodeJS as a server:
res.send("Hello World")
When I try to call this in Alamofire:
AF.request(" ~myIP~ :3000/").response{ response in
print(response.value!)
}
It returns:
Optional(11 bytes)
What can I do so that it prints "Hello World" instead of "Optional(19 bytes)"? Thanks
Also thought I would add that .responseString will make my program not compile.
Alamofire has a built in response handler to parse response bodies as Strings: responseString.
AF.request(...).responseString { response in
print(response.value ?? "Request failed.")
}
Solved:
AF.request("~myIP~:3000/", method:.get).response{ response in
let responseString = String(decoding:response.value!!, as: UTF8.self)
print(responseString)
}
I wrote a simple mock that checks if a specific header exists then return a specif response based on that, but karate doesn't understand dashes(-) in my headers for an example Client-ID gives an error of ReferenceError: "ID" is not defined in <eval> at line number 1 but header Accept work fine. i'm passing this header through postman.
and this how the code looks
* def fun = function(){ var test = requestHeaders; for(i in test) if(test.Client-ID) return true}
When you have characters like - part of the JSON key, you need to use quotes.
* def foo = { 'Content-Type': 'application/json' }
* match foo['Content-Type'] == 'application/json'
Also try if this works for you, it may be simpler:
Scenario: pathMatches('/v1/headers') && karate.get("requestHeaders['Client-ID']")
And in case you are testing a value, headerContains() can be used: https://github.com/intuit/karate/tree/master/karate-netty#headercontains
Hi I am new to swift please spare me.
I need to post to particular API but the api is not a fan of key value pair the api expect raw json as post data
I use this library here to make post request.
this is my code
func postItem(itemname: String, itemnumber: Int, itemcode:String, url:String, baseURL:String, completion: (result: Dictionary<String, AnyObject>) -> ()){
var dict: Dictionary<String, AnyObject>!
var params: Dictionary<String,AnyObject> = ["parentItem": ["itemname":itemname,"itemnumber":itemnumber,"itemcode":code]]
let data = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
let string = NSString(data: data!, encoding: NSUTF8StringEncoding)
var request = HTTPTask()
request.requestSerializer = JSONRequestSerializer()
request.requestSerializer.headers[headerKey] = getToken() //example of adding a header value
request.POST(url, parameters: params, success: {(response: HTTPResponse) in
if response.responseObject != nil {
let data = response.responseObject as NSData
var error: NSError?
dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as Dictionary<String, AnyObject>;
completion(result: dict)
}
},failure: {(error: NSError, response: HTTPResponse?) in
dict = ["error" : "error" ]
completion(result: dict)
})
}
i need to pass this kind of raw json in api
eg. {"parentItem": {"itemname":"Cocoa","itemnumber":123,"itemcode":"cocoa-12-A"}}
but when I println my params because it is dictionary it generate something like
["parentItem": ["itemname"="Cocoa"; "itemnumber"=123; "itemcode"="cocoa-12-A"]]
I just couldn't convert the params to JSON because the library I'm using is expecting dictionary and I'm having a hard time creating my own class.
could anyone help me? any comments and suggestion would do. Thanks in advance.
Why don't use Alamofire framework ? It's pretty good and sends standard json
I am trying the following API using Alamofire, but this API has multiple "to" fields. I tried to pass an array of "to" emails as parameters. It shows no error but did not send to all emails. API is correct, I tested that from terminal. Any suggestions will be cordially welcomed.
http -a email:pass -f POST 'sampleUrl' from="email#email.com" to="ongkur.cse#gmail.com" to="emailgmail#email.com" subject="test_sub" bodyText="testing hello"
I am giving my code:
class func sendMessage(message:MessageModel, delegate:RestAPIManagerDelegate?) {
let urlString = "http://localhost:8080/app/user/messages"
var parameters = [String:AnyObject]()
parameters = [
"from": message.messageFrom.emailAddress
]
var array = [String]()
for to in message.messageTO {
array.append(to)
}
parameters["to"] = array
for cc in message.messageCC {
parameters["cc"] = cc.emailAddress;
}
for bcc in message.messageBCC {
parameters["bcc"] = bcc.emailAddress;
}
parameters["subject"] = message.messageSubject;
parameters["bodyText"] = message.bodyText;
Alamofire.request(.POST, urlString, parameters: parameters)
.authenticate(user: MessageManager.sharedInstance().primaryUserName, password: MessageManager.sharedInstance().primaryPassword)
.validate(statusCode: 200..<201)
.validate(contentType: ["application/json"])
.responseJSON {
(_, _, jsonData, error) in
if(error != nil) {
println("\n sendMessage attempt json response:")
println(error!)
delegate?.messageSent?(false)
return
}
println("Server response during message sending:\n")
let swiftyJSONData = JSON(jsonData!)
println(swiftyJSONData)
delegate?.messageSent?(true)
}
}
First of all if you created the API yourself you should consider changing the API to expect an array of 'to' receivers instead of multiple times the same parameter name.
As back2dos states it in this answer: https://stackoverflow.com/a/1898078/672989
Although POST may be having multiple values for the same key, I'd be cautious using it, since some servers can't even properly handle that, which is probably why this isn't supported ... if you convert "duplicate" parameters to a list, the whole thing might start to choke, if a parameter comes in only once, and suddendly you wind up having a string or something ...
And I think he's right.
In this case I guess this is not possible with Alamofire, just as it is not possible with AFNetworking: https://github.com/AFNetworking/AFNetworking/issues/21
Alamofire probably store's its POST parameter in a Dictionary which doesn't allow duplicate keys.
Can anyone suggest some pointers for how to extend alamofire with headers, like Content-MD5 which need to be set right before it gets sent?
This is a bit old question, but I've had the same problem and I solved it using the following code:
Alamofire.request(.POST, "your-url", parameters: params, encoding: .Custom({(convertible, paramsOptinal) in
guard let params = paramsOptinal else {return (convertible.URLRequest, NSError(domain: "", code: -1, userInfo: nil))}
let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
let json = try! NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted)
let jsonMd5 = self.MD5(json).base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
mutableRequest.setValue(jsonMd5, forHTTPHeaderField: "Content-MD5")
let contentType = "application/json; charset=utf-8"
mutableRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
mutableRequest.HTTPBody = json
return (mutableRequest, nil)}
)).responseString {response in
print(response)
}
Hope you find this helpful.
Omer