Print data from Alamofire request, swift - swift

I made this request:
func AlamofireGetCode()
{
let username: String = searchTextField.text!
var url:String!
url = "https:// ... "
AF.request(url, method: .get, encoding: JSONEncoding.default)
.responseJSON { response in
switch response.result {
case .success:
debugPrint(response)
case .failure(let error):
fatalError("\(error)")
}
}
}
And I'm getting this response with different fields:
[Result]: success({
"incomplete_results" = 0;
items = (
{
"username" = " ... "
...
How do I get some specific field like "username" in Swift?
I would like to have all the username of all the user and store them, could you help me?

You need to provide a type to parse the JSON response into. Using a site like quicktype.io can generate one from your JSON, but any Decodable type will do. Then you can use Alamofire's responseDecodable handler to parse your response.
AF.request(url).responseDecodable(of: TypeToParse.self) { response in
debugPrint(response)
}

Paste your response in https://jsonparseronline.com/ to see the structure of the object. It will show you all the keys and values that you can access using subscripts.

Related

Can't make post request using params as dictionary with Swift 4 & Alamofire

I'm trying to learn to call API with/without library. But the problem here confuses me.
I have params like this:
let parameters: [String:String] =
["key":"MY_KEY" ,
"q":sourceText,
"source": sourceLanguage),
"target": target)]
let headers: HTTPHeaders = [ "Content-type": "application/json"]
I make a post call like this:
Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, headers: headers)
.responseJSON{ response in
guard response.result.error == nil else {
print("error calling POST on /todos/1")
print(response.result.error!)
return
}
// make sure we got some JSON since that's what we expect
guard let json = response.result.value as? [String: Any] else {
print("didn't get todo object as JSON from API")
print("Error: \(response.result.error)")
return
}
By this I get an error 403, saying that I do not have a valid API key (I tested the key with postman, and it is okay).
After many efforts, I have to change the code like this
let stringparams = "key=MY_KEY&q=\(sourceText)&source=\(sourceLanguage)&target=\(target)"
request.httpBody = stringparams.data(using: String.Encoding.utf8)
and using this: Alamofire.request(request)
it works!
I'm using Google Cloud Translation api. And the web use a REST api as said here: https://cloud.google.com/translate/docs/reference/translate
So why can't I use params as dictionary, but using the string (like formdata) will work here?
My guess is Alamofire didn't make the right BODY for the request from the parameters because other arguments is okay. But I don't know why.
And I think Google should accept a json params as they mentioned, in stead of using form data? I did try the original method, but it didn't work with JSON.
From what actually works for you it looks like you need to encode the parameters in the same style as a query. Try this:
struct ParameterQueryEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try urlRequest.asURLRequest()
request.httpBody = parameters?
.map { "\($0)=\($1)" }
.joined(separator: "&")
.data(using: .utf8)
return request
}
}
You should then be able to perform the original call that you had before:
Alamofire.request(urlString,
method: HTTPMethod.post,
parameters: parameters,
encoding: ParameterQueryEncoding(),
headers: headers)
.responseJSON { response in
...
}
Try by using JSON encoding. Make sure you have removed ) from dictionary.
Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)

Pass an integer as a parameter in an Alamofire PUT request

So I am trying to do a PUT request using Alamofire and I need an integer parameter (not an object).
The request sends an id to the database and the query makes an update to an object with that id in the database.
The Parameters object in alamofire seems to take only objects:
var parameters: Parameters = ["key" : "value"]
is there any way to just send an integer without using the object?
The error I keep getting when I use that method above is:
nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of int out of START_OBJECT token
and I am assuming this means I am passing an object when I should be passing an int instead.
This is my request :
Alamofire.request(url, method: .put, parameters: parameters, encoding: JSONEncoding.default, headers: nil).response{ response in
if response.response?.statusCode == 200 {
// pass
}else{
// fail
}
completionHandler((response.response?.statusCode)!)
}
I can't seem to find any examples that have to do with us online.
If you give more information about where you are sending the request, then I can test my solution to see if it works. But you can try this.
let url = "YOUR_URL"
let yourData = "WHATEVER CUSTOM VAL YOU WANT TO PASS"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "PUT"
//request.setValue("application/json", forHTTPHeaderField: "Content-Type") //This is if you want to have headers. But it doesn't look like you need them.
request.httpBody = yourData
/*
do {
request.httpBody = try JSONSerialization.data(withJSONObject: yourData)
} catch {
print("JSON serialization failed: \(error)")
}
*/
Alamofire.request(request).responseJSON {(response) in
if response.response?.statusCode == 200 {
print ("pass")
}else{
print ("fail")
}
completionHandler((response.response?.statusCode)!)
/*
switch response.result {
case .success(let value):
print ("success: \(value)")
case .failure(let error):
print("error: \(error)")
}
*/
}

Thread 1 : signal SIGABRT alamofire

I'm very new to Swift 3, and i have to do a GET request on my API. I'm using Alamofire, which uses Asynchronous functions.
I do exactly the same on my Android App, and the GET returns JSON data
This is my code in swift :
func getValueJSON() -> JSON {
var res = JSON({})
let myGroup = DispatchGroup()
myGroup.enter()
Alamofire.request(url_).responseJSON { response in
res = response.result.value as! JSON
print("first result", res)
myGroup.leave()
}
myGroup.notify(queue: .main) {
print("Finished all requests.", res)
}
print("second result", res)
return res
}
But i have a problem with the line "res = response.result.value" wich gives me the error : Thread 1 : signal SIGABRT
I really don't understand where the problem comes from, it was pretty hard to do a "synchronous" function, maybe i'm doing it wrong.
My objective is to store the result of the request in a variable that i return. Anyone can help ?
I'd recommend you to use Alamofire together with SwiftyJSON because that way you'll be able to parse JSON easier a lot.
Here's a classical example:
Alamofire.request("http://example.net", method: .get).responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(json)")
case .failure(let error):
print(error)
}
}
If you need to pass parameters, or headers, just add it in the request method.
let headers: HTTPHeaders = [
"Content-Type:": "application/json"
]
let parameters: [String: Any] = [
"key": "value"
]
So your request will be something like this (this is POST request):
Alamofire.request("http://example.net", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in
switch response.result {
case .success(let value):
print(value)
case .failure(let error):
print(error)
}
}
I haven't tested it, but it should work. Also, you need to set allow arbitary load to yes (App Transport Security Settings in info.plist) if you want to allow requests over HTTP protocol.
This is NOT recommended, but it's fine for development.

Order parameters using Alamofire

We are needing to control the parameter order in an Alamofire request. The parameters are supplied to Alamofire as a dictionary, and as such are not ordered.
Have also tried using an adapter, but by that time the body is encoded data, not thinking I can change that.
We need to order because of oauth, our server is using the params as part of the key and expecting a specific order.
Just in case, here is our code:
let parameters: Parameters = ["id": "userID","service": "token"]
Alamofire.request("https://ourhost.com", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers)
.responseString { response in
print("Success: \(response.result.isSuccess)")
print("Response String: \(response.result.value)")
}
.responseJSON { response in
print(response.result)
switch response.result {
case .success:
print(response.result.value)
break;
default:
print(response.result.error!)
break
}
}
Would welcome a way to order these items.

Alamofire JSON response with strange characters in Swift

I'm using Alamofire 3.0 and swift 2 and get a strange response from the following request:
func requestURLwithHeadersAndParams(URLstr:String, connectionMethod: Alamofire.Method, header: [String : String], body:[String : AnyObject], completion: (reponse: String, statusCode: Int, error: String) -> Void) {
///Singleton Alamofire connection manager
let alamofireManager = Alamofire.Manager.sharedInstance
alamofireManager.request(connectionMethod, URLstr, parameters: body, encoding: ParameterEncoding.JSON, headers: header).responseJSON (){
response in
print("\nSuccess: \(response.result.isSuccess)")
switch response.result {
case .Success(let value):
print("Response Status code: \((response.response?.statusCode)!)\n")
print("\(value)")
completion(reponse: "\(value)" , statusCode: (response.response?.statusCode)! , error: "")
case .Failure(let error):
print("Error Code:\(error.code) - Description:\(error.localizedDescription)")
completion(reponse: "Error" , statusCode: (response.response?.statusCode)!, error: error.localizedDescription)
} } }
the value property contains:
"{\n \"auth_token\" = \"qcW-mQmyX8ototieJu7WK\";\n avatar = {\n standard = {\n url = \"<null>\";\n };\n url = \"<null>\";\n };\n birthdate = \"<null>\";\n \"created_at\" = \"2015-10-28T07:02:20.445Z\";\n email = \"elrope#abt.com\";\n \"first_name\" = El;\n id = 12;\n \"last_name\" = Perro;\n role = user;\n \"shooter_type\" = \"\";\n \"updated_at\" = \"2015-10-28T07:42:37.860Z\";\n}"
any idea how can I get rid of all the escape characters ('\' and '\n') since the JSON serialization using SwiftyJSON in the method calling this method can't recognize the string as a json string and fails when I do let json = JSON(reponse) with error:
Error Domain=SwiftyJSONErrorDomain Code=901 "Dictionary["auth_token"]
failure, It is not an dictionary" UserInfo=0x6030002d7c00
{NSLocalizedDescription=Dictionary["auth_token"] failure, It is not an
dictionary})
I found your JSON invalid itself.
e.g. avatar, standard are not strings, where are the quotes?
I belevie using , and : is better practice than using ; and =
I tested on SwiftyJSON and after above changes everything works fine. So maybe the issue is on your backend. Try to validate raw JSON using web browser.
Your JSON is invalid.
Actually, your value string is nothing else than the .description output of an NSDictionary!
Demonstration in a Playground:
Needless to say that this isn't JSON... so of course it fails when you try to give this to SwiftyJSON.
So, either you were confused somewhere and you're using your dictionary's description instead of its actual content...
...or this error comes from the server.