How do I show response as string? - alamofire

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)
}

Related

Get HTTP StatusCode in WebException

I am wondering how can I get the HTTP Status returned after a WebException was thrown. I am calling for example a RestAPI to get a token and the Server returns a 401 and a Body in json Format telling me that access is denied. I would like to get the 401 but have not found a way to only get 401.
Catch ex As WebException
Dim resp = New StreamReader(ex.Response.GetResponseStream()).ReadToEnd()
Dim errorNumber As Integer = CInt(ex.Status)
Console.WriteLine(ex.Message & " " & errorNumber)
Console.WriteLine(resp & " ")
Return resp
Below is the console output I have for my code:
CInt(ex.Status) = "7" and the
ex.message = "The remote server returned an error: (401) Unauthorized."
What I am looking for is to get the 401 or whatever the Server sends which would be equal to response.StatusCode
I actually found a way to access the 401 directly
Dim ExResponse = TryCast(ex.Response, HttpWebResponse)
Console.WriteLine(ExResponse.StatusCode)
I have the same problem and I realise a few things while I search for a solution.
WebExceptionStatus enum is not equivalent to http status code that the API you call returned. Instead it is a enum of possible error that may occour during a http call.
The WebExceptionStatus error code that will be returned when you receive an error (400 to 599) from your API is WebExceptionStatus.ProtocolError aka number 7 as int.
When you need to get the response body or the real http status code returned from the api, first you need to check if WebExceptionStatus.Status is WebExceptionStatus.ProtocolError. Then you can get the real response from WebExceptionStatus.Response and read its content.
This is a C# code but you folow the same logic in VB.Net
try
{
...
}
catch (WebException webException)
{
if (webException.Status == WebExceptionStatus.ProtocolError)
{
var httpResponse = (HttpWebResponse)webException.Response;
var responseText = "";
using (var content = new StreamReader(httpResponse.GetResponseStream()))
{
responseText = content.ReadToEnd(); // Get response body as text
}
int statusCode = (int)httpResponse.StatusCode; // Get the status code
}
// Handle other webException.Status errors
}

GDAX Post Call returns invalid signature

I am trying to make a post request on GDAX.
But I always receive a "invalid signature" message.
GDAX API Docs for creating request + signing: https://docs.gdax.com/#creating-a-request
Preshash string returns the following:
1500627733POST/orders{"price":"1000.0","size":"0.02","type":"limit","side":"sell","product_id":"BTC-EUR"}
My signature method:
public String generateSignature(String requestPath, String method, String body, String timestamp) {
try {
String prehash = timestamp + method.toUpperCase() + requestPath + body;
byte[] secretDecoded = Base64.getDecoder().decode(secretKey);
SecretKeySpec keyspec = new SecretKeySpec(secretDecoded, "HmacSHA256");
Mac sha256 = (Mac) Mac.getInstance("HmacSHA256").clone();
sha256.init(keyspec);
return Base64.getEncoder().encodeToString(sha256.doFinal(prehash.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
My request method:
private boolean placeLimitOrder(String currencyPair, String side, String price, String size)
throws UnirestException {
String timestamp = Instant.now().getEpochSecond() + "";
String api_method = "/orders";
String path = base_url + api_method; //base_url = https://api.gdax.com
String method = "POST";
String b = "{\"price\":\"1000.0\",\"size\":\"0.02\",\"type\":\"limit\",\"side\":\"sell\",\"product_id\":\"BTC-EUR\"}";
JsonNode n = new JsonNode(b);
String sig = generateSignature(api_method, method,b, timestamp);
HttpResponse<JsonNode> rep = Unirest.post(path).header("accept", "application/json")
.header("content-type", "application/json")
.header("CB-ACCESS-KEY", publicKey)
.header("CB-ACCESS-PASSPHRASE", passphrase)
.header("CB-ACCESS-SIGN", sig)
.header("CB-ACCESS-TIMESTAMP", timestamp)
.body(n)
.asJson();
System.out.println(rep.getStatusText()); //Bad Request
System.out.println(rep.getBody().toString()); //invalid signature
System.out.println(sig); //returns something
return false;
}
I also tried to make a API Request Call with Insomnia but it returns the same message ("invalid signature").
Any clues?
Thank you very much in advance!
Looks like you are signing the price order data which is a string, but for the body in the post you are turning it into a json node. Which may not match when gdax decodes the signing and compares the payload data to the decrypted(signed body) when they receive it.
Why not just send the string as the body and remove the ".asJson"?
.body(b)
I was stuck on a similar issue when I was testing the API in C#. After 3 afternoons of trying. I tested sending the data as a string and I was able to get pass the invalid signature error.
I had the same problem.
I used http:
but the right one httpS:
Problem solved.

Extra argument 'method' in call

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.

how to Pass Raw Json to post request in Swift?

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

Why messages are not added in Json response like error messages

If I use 'web-send-json-response="true"' while calling any service, it returns json response using sendJsonResponse(Object responseObj) method of WebFacadeImpl.groovy.
Where It adds 'errors' to json response if 'eci.getMessage().hasError()' true. But, Is there any reason why messages are not added in Json Response?
As I am willing to have messages in json response, I added few lines in sendJsonResponse() method.
The code block where I added few lines to add messages to json response:
} else if (responseObj != null) {
responseObj.put("messages", eci.message.messages)
JsonBuilder jb = new JsonBuilder()
jb.call(responseObj)
jsonStr = jb.toString()
response.setStatus(HttpServletResponse.SC_OK)
} else {
jsonStr = ""
if (eci.message.messages) {
responseObj.put("messages", eci.message.messages)
JsonBuilder jb = new JsonBuilder()
jb.call(responseObj)
jsonStr = jb.toString()
}
response.setStatus(HttpServletResponse.SC_OK)
}
It works fine and I am getting messages in json response.