I want to display my instagram on iOS app. I'm using Alamofire and Swifty libraries for JSON with this tutorial http://myxcode.net/2015/07/12/getting-data-from-instagram-account/
However I'm getting error in this line:
Alamofire.request(.GET, url).responseJSON { (request, response, json, error) in
saying "Void expects 1 argument but 4 were used in closure body".
But if I use
Alamofire.request(.GET, url)
.responseJSON { response in
print(response)
}
It prints the result correctly.
If i use
Alamofire.request(.GET, url)
.responseJSON { response in
let data = response["data"].arrayValue as [JSON]?
that I got from https://github.com/Alamofire/Alamofire
I get error "Type 'Response' has no subscript members"
How can I use this?
As mentioned on the Almofire GitHub page you have to use following if you want to get 4 parameters directly
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.response { request, response, data, error in
print(request)
print(response)
print(data)
print(error)
}
You can't use 4 parameters with the responseJSON as it only has one parameter as you have written in the example
but you can get 4 value from the response like this
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
You can get everything from the response object
Related
In past version of Alamofire, for send method,header and parameter I used to do like this:
Alamofire.request(.GET, URLRequest, headers:headers, parameters: parameters)
but version 4 and swift 3 is different.
How can I set method, send header & parameter?
The migration guide at Alamofire github explains this very well.
Take a look here:
// Alamofire 3
let parameters: [String: AnyObject] = ["foo": "bar"]
Alamofire.request(.GET, urlString, parameters: parameters, encoding: .JSON)
.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print("Bytes: \(bytesRead), Total Bytes: \(totalBytesRead), Total Bytes Expected: \(totalBytesExpectedToRead)")
}
.validate { request, response in
// Custom evaluation closure (no access to server data)
return .success
}
.responseJSON { response in
debugPrint(response)
}
// Alamofire 4
let parameters: Parameters = ["foo": "bar"]
Alamofire.request(urlString, method: .get, parameters: parameters, encoding: JSONEncoding.default)
.downloadProgress(queue: DispatchQueue.utility) { progress in
print("Progress: \(progress.fractionCompleted)")
}
.validate { request, response, data in
// Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
return .success
}
.responseJSON { response in
debugPrint(response)
}
The migration guide explained well, but there are no headers in the example, just to avoid confusions, bellow I add the example of a GET request to add them.
Alamofire.request(URL, method: .get, parameters: parameters, headers: headers)
.validate { request, response, data in
return .success
}
.responseJSON { response in
switch response.result {
case .success:
// do something
break
case .failure(let error):
// handle error
break
}
}
I found this information in here so, go and check it there if you have question related with the headers in the request.
Having difficulty making a request in Alamofire 4.0. Previously I would use:
Code Snippet :
alamoManager.request(.GET, url, parameters: parameters, encoding: .url, headers: nil).responseObject { (response: Response<MyCustomResponse, NSError>) in
}
Where alamoManager is the old Manager object (now renamed SessionManager). However I can't see anything in the docs about how to pass a custom response (Conforms to Mappable). Has anybody achieved this? Any pointers would be really appreciated!
I used to type Alamofire 4.0 request like this:
import Alamofire
...
let parameters : Parameters = ["task":"setUser"]
Alamofire.request(url, parameters: parameters)
.validate()
.responseJSON { response in
//print(parameters), print(response.request), print(response.response), print(response.result)
switch response.result {
case .success:
let statusCode = (response.response?.statusCode)!
print("HTTP code #apiGetUser: \(statusCode)")
// ...
case .failure(let error):
// ...
}
}
How to call this kind of Web Service with alamofire.
http://www.example.com?abcrequest={"abc":"abc"}
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseSwiftyJSON({ (request, response, json, error) in
println(json)
println(error)
})
So what should I passed in URL and in parameter?
I'm new to swift and iOS and trying to use Alamofire and router for them, which returns NSMutableURLRequest, but my code didn't work. So I just made one NSURLRequest for test, and requested it but results was same.
Here is my code. I'm currently using Alamofire and SwiftyJSON.
let params = ["Id": "1234567", "Token": "something"]
let url = NSURL(string: "myurl")
var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = Alamofire.Method.POST.rawValue
let encoding = Alamofire.ParameterEncoding.JSON
(request, _) = encoding.encode(request, parameters: params)
Alamofire.request(request)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
let token = json["token"].stringValue
let error = json["error"].stringValue
print("token : \(token), error : \(error)")
}
case .Failure(let error):
// TODO:
print(error)
}
}
Above code sends request without parameters. Are there any errors on my code?
I've checked your code and before executing encode function your request.HTTPBody is empty, but after it has some data like
Optional<NSData>
- Some:<7b22546f 6b656e22 3a22736f 6d657468 696e6722 2c224964 223a2231 32333435 3637227d>
When I call print(response.request?.HTTPBody) in Alamofire response block, I get the parameters as NSData and the HTTPBody includes the same data as before sending the request so it works.
Try also change the response from responseJSON to responseString, because if your response can't be parsed to JSON you get Failure.
I think you should check on your URL site if you get correct data.
Instead of your solution I use
Alamofire.request(method, url, parameters: parameters, encoding: .JSON) .responseString{ response in}
is the same but shorter and everything is as parameters.
I have a pretty simple scenario that I'm struggling with. I'm using Alamofire to register a user on a rest API. The first call to register is successful and the user can log in. The second call, when trying to register with the same email address should result in a HTTP status code 409 from the server. Alamofire, however, returns a .Success with an empty request and response. I have tested this this API with postman and it correctly returns a 409.
Why is Alamofire not returning .Failure(error), where the error has status code info etc?
Here is the call I run with the same input each time.
Alamofire.request(.POST, "http://localhost:8883/api/0.1/parent", parameters: registrationModel.getParentCandidateDictionary(), encoding: .JSON).response(completionHandler: { (req, res, d, e) -> Void in
print(req, res, d, e)
})
From the Alamofire manual:
Validation
By default, Alamofire treats any completed request to be successful,
regardless of the content of the response. Calling validate before a
response handler causes an error to be generated if the response had
an unacceptable status code or MIME type.
You can manually validate the status code using the validate method, again, from the manual:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { response in
print(response)
}
Or you can semi-automatically validate the status code and content-type using the validate with no arguments:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.validate()
.responseJSON { response in
switch response.result {
case .success:
print("Validation Successful")
case .failure(let error):
print(error)
}
}
If using response, you can check the NSHTTPURLResponse parameter:
Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
.response { response in
if response.response?.statusCode == 409 {
// handle as appropriate
}
}
By default, 4xx status codes aren't treated as errors, but you can use validate to treat it as an such and then fold it into your broader error handling:
Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
.validate()
.response() { response in
guard response.error == nil else {
// handle error (including validate error) here, e.g.
if response.response?.statusCode == 409 {
// handle 409 here
}
return
}
// handle success here
}
Or, if using responseJSON:
Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
.validate()
.responseJSON() { response in
switch response.result {
case .failure:
// handle errors (including `validate` errors) here
if let statusCode = response.response?.statusCode {
if statusCode == 409 {
// handle 409 specific error here, if you want
}
}
case .success(let value):
// handle success here
print(value)
}
}
The above is Alamofire 4.x. See previous rendition of this answer for earlier versions of Alamofire.
if you use validate() you'll loose the error message from server, if you want to keep it, see this answer https://stackoverflow.com/a/36333378/1261547
Here is my code for AlamoFire error catching:
switch response.result {
case .success(let value):
completion(.success(value))
case .failure(var error):
var errorString: String?
if let data = response.data {
if let json = try? (JSONSerialization.jsonObject(with: data, options: []) as! [String: String]) {
errorString = json["error"]
}
}
let error = MyError(str: errorString!)
let x = error as Error
print(x.localizedDescription)
completion(.failure(x))
}
and the MyError class difinition:
class MyError: NSObject, LocalizedError {
var desc = ""
init(str: String) {
desc = str
}
override var description: String {
get {
return "MyError: \(desc)"
}
}
//You need to implement `errorDescription`, not `localizedDescription`.
var errorDescription: String? {
get {
return self.description
}
}
}