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.
Related
In the postman in the body section in the form-data part when I pass a mobile number as a key and mobile number as Int value I get a response. But when I did it in the code I will not get the response as expected.
my code is
func fetchRegisterData(){
let url = registerApi
var mobileNumber = mobilenumberTextfield.text
let parameters = ["mobile" : mobileNumber] as [String : Any]
AF.request(url,method: .post, parameters: parameters, encoding:JSONEncoding.default).responseJSON
{ response in switch response.result {
case .success(let JSON):
print("response is :\(response)")
case .failure(_):
print("fail")
}
}
}
If you're trying to pass parameters as multipart/form-data you have to use the upload method in Alamofire:
func fetchRegisterData() {
let parameters = ["mobile": mobilenumberTextfield.text!]
AF.upload(multipartFormData: { (multiFormData) in
for (key, value) in parameters {
multiFormData.append(Data(value.utf8), withName: key)
}
}, to: registerApi).responseJSON { response in
switch response.result {
case .success(let JSON):
print("response is :\(response)")
case .failure(_):
print("fail")
}
}
}
For normal Alamofire request -
While passing values as a parameter in Alamofire Request. You need to know about the data type of the request type values which is valid for API.
At API end, these values are getting parsed based on some data types. There must be some validations on the data type at the API side.
for mobileNumber, it can be either Int or String
1 - let parameters = ["mobile" : mobileNumber] as [String : Int]
2 - let parameters = ["mobile" : mobileNumber] as [String : String]
For multipart form data request use have to use something like below. However, if you are not uploading anything you should not use it. Ask API team to make changes in the API and normal parameters request
Alamofire.upload(multipartFormData: { (multipartFormData) in
//Try this
multipartFormData.append(mobileNumber, withName: "mobile")
//or this
multipartFormData.append("\(String(describing: mobileNumber))".data(using: .utf8)!, withName: "mobile")
}, usingThreshold: 10 * 1024 * 1024, to: apiUrl, method: .post, headers: [:], encodingCompletion: { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
case .failure( _):
}
})
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.
I have an array with strings
let languages = ["en", "fr", "es"]
let type = ["cat", "dog"]
and I want to get all data in foreach loop with Alamofire 4.8
languages.forEach {
Alamofire.request(Endpoints.langList, method: .get, parameters: parameters, headers: headers).validate().responseJSON { response in
switch response.result {
case .success:
let result = try? JSONDecoder().decode(Langs.self, from: response.data!)
completionHandler(.success(result!))
case let .failure(error):
completionHandler(.failure(error))
}
}
}
type.forEach {
Alamofire.request(Endpoints.typeList, method: .get, parameters: parameters, headers: headers).validate().responseJSON { response in
switch response.result {
case .success:
let result = try? JSONDecoder().decode(Types.self, from: response.data!)
completionHandler(.success(result!))
case let .failure(error):
completionHandler(.failure(error))
}
}
}
and I'm getting errors
finished with error - code: -1001
HTTP load failed (error code: -999 [1:89])
and all requests starts twice.
I realized that when I remove forEach loop all works without any errors and multiply requests.
I've tried using Alamofire.SessionManager and DispatchQueue but it didn't help me.
How can I avoid Alamofire multiply requests inside forEach loops?
I am using Alamofire version 3.1.5 with my xCode version 7.3. I tried it on many apps of mine. But I do not get any result. No error is seen before the execution. My code is like this:
var apiUrl : String
var alamoFireManager:Manager!
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
init(apiUrl : String){
self.apiUrl = apiUrl
configuration.timeoutIntervalForRequest = 30.0
alamoFireManager = Alamofire.Manager(configuration: configuration)
}
print(apiUrl)
alamoFireManager.request(.GET, apiUrl, encoding: .JSON).validate(contentType: ["application/json"]) .responseJSON { response in
print(response.result.value)
switch response.result{
case .Success:
if let value = response.result.value{
let json = JSON(value)
print (json)
callback.onResponse(value) // this is where my value is sent
}
case .Failure(let error):
print(error.localizedDescription)
}
}
I checked using breakpoint and the app directly reaches this last braces frm the alamofire line.
I think the issue is you are not calling resume(). From the Alamofire doc
If the owning manager does not have startRequestsImmediately set to
true, the request must call resume() in order to start.
try this
alamoFireManager.request(.GET, apiUrl, encoding: .json).validate(contentType: ["application/json"]).resume().responseJSON { response in
print(response.result.value)
switch response.result{
case .Success:
if let value = response.result.value{
let json = JSON(value)
print (json)
callback.onResponse(value) // this is where my value is sent
}
case .Failure(let error):
print(error.localizedDescription)
}
}
every one,
I'm having an issue with Alamofire 3.0, when I post data, it seems the data is being sent twice.
I looked up on the web, found that a bug about special caratères was fixed, but I still get the error.
Anyone has an idea. I'm using a parameter in the header called X-Authorization.
Here is an extract of the code i'm using:
static func postData (url: String,token: String,params :Dictionary<String,AnyObject>){
print("POSTINGGGGGG")
Alamofire.request(.POST, url, parameters: params,headers: ["X-Authorization": token])
.responseJSON { response in
switch response.result {
case .Success(let data): break
//let resultJSON = JSON(data).dictionaryValue
// print(data)
case .Failure(let error):
print(error)
}
}
}
Thank you in advance,
Morgan