Alamofire put request - alamofire

Try to get Alamofire put request to work, but system shows "Extra Argument in Call"
Alamofire.request(.PUT, apiUrl,params,ParameterEncoding.JSON)
.responseJOSN{ (request, response, products: [Product]?,error) in
println(request)
println(response)
println(data)
println(error)
}
Anyone can solve this problem?

You have multiple issues in your code sample. Here's a corrected version that should get you going:
let apiURLString = "whatever/your/url/is"
let parameters: [String: AnyObject] = [:] // fill in your params
let request = Alamofire.request(.PUT, apiURLString, parameters: parameters, encoding: .JSON)
request.responseJSON { request, response, json, error in
println(request)
println(response)
println(json)
println(error)
}
I would also encourage you to really read through the Alamofire README in depth. It has some great information and should make it much easier for you to get the basics working.

As 'alamofire' '~2.0' has changed the in number of parameters
You can try with the following block of code:
Alamofire.request(.PUT,apiUrl,params).responseJSON { request, response, result in
print(request)
print(response)
print(result.value)
if(result.isSuccess){
//Do in success block
}else{
//Do in failure block
}
}
Alamofire.request does not have error handler parameter available, hence it was showing you that "Extra Argument in Call"

Related

Decoding an Error Response using Alamofire 5 and the responseDecodable function

I'm writing an API Client for WooCommerce using Alamofire 5 (beta 1) which will allow me to get orders, coupons etc as well as create them. Note I am using the new .responseDecodable function.
I've set up my API client using the following performRequest function that looks like this:
#discardableResult
private static func performRequest<T:Decodable>(route: APIConfiguration,
decoder: JSONDecoder = JSONDecoder(),
completion: #escaping (Result<T>)->Void) -> DataRequest {
return AF.request(route)
.responseDecodable(decoder: decoder) { (response: DataResponse<T>) in
completion(response.result)
}
}
This works well, since I can, for instance, call a function getCouponForId(_ id: Int) which will execute this function and have the response returned through the completion handler.
The only downfall is that, say the user tries to access a coupon that does not exist, they will receive an error (404 from the server). I can switch on the result to determine either a success or failure case, but Alamofire attempts to decode the body of the error response into the Coupon model I have created.
Going forward, I have created an error model which I intend to have the error decoded using. But with that said, I'm having trouble implementing it into this function.
Does anyone have any ideas on how I could handle this?
(I have created this function through following this guide - hopefully, it might provide a bit more context to what I'm doing. https://github.com/AladinWay/NetworkingExample)
Similiar login function from the article you mentioned, updated for current beta of Alamofire 5 and dealing with 404, 401 etc. (via the guard statement)
static func login(email: String, password: String, completion:#escaping (Result<UserCredentials>)->Void) {
performRequest(router: Router.login(email: email, password: password), completion: completion)
AF.request(Router.login(email: email, password: password))
.validate(statusCode: 200..<300)
.responseDecodable { (response: DataResponse<UserCredentials>) in
guard response.result.isSuccess else {
print("🥶 Error on login: \(String(describing: response.error))")
return
}
completion(response.result)
}
}
Just update
request.responseDecodable(decoder: decoder, completionHandler: { (response: AFDataResponse<T>) in
to
request.responseDecodable(decoder: decoder, completionHandler: { (response: DataResponse<T>) in

How to use Alamofire with JSONDecoder?

I am try to parsing google Direction API as below.
https://developers.google.com/maps/documentation/directions/start
but unable to get any result from JSONDecoder , it always return Error block
I am using Alamofire code as below for parsing .
let decoder = JSONDecoder()
do {
let userDictionary = try decoder.decode(DirectionParser.self, from: response.data!)
print("The Parser \(userDictionary)")
} catch {
print("Error")
}
I think you are doing right. Just make sure you are trying to parse what you want. You can do this by printing out
print(response.anythingYouWant)
Can you show us DirectionParser.
Make sure it is like below code
struct DirectionParse: Decodable {
//things you want to fetch
}
P.S I would have commented if I had reputation 50+.

Cannot call value of non-function type 'HTTPURLResponse?

It is giving me the Error: Cannot call value of non-function type 'HTTPURLResponse?'
It should be caused by #escaping but I cannot make it work in the sentence below. Please help, Swift 3.0, AlamofireImage.
There are other similar answers but cannot make them work with my code below.
func getNetworkImage(_ urlString: String, completion: #escaping ((UIImage) -> Void)) -> (ImageRequest) {
let queue = decoder.queue.underlyingQueue
let request = Alamofire.request(urlString)
let imageRequest = ImageRequest(request: request)
imageRequest.request.response(
queue: queue,
responseSerializer: Request.imageResponseSerializer(),
completionHandler: { response in
guard let image = response.result.value else {
return
}
let decodeOperation = self.decodeImage(image) { image in
completion(image)
self.cacheImage(image, urlString: urlString)
}
imageRequest.decodeOperation = decodeOperation
}
)
return imageRequest
}
The error message: Cannot call value of non-function type 'HTTPURLResponse?' is telling you that the instance variable value can not be accessed. The bad thing is that it is telling you this in the wrong line of code. That may be the reason why it was so difficult to find.
The structure of the response object has changed. You code:
guard let image = response.result.value else {
return
}
Won't work anymore because the response object is of type DefaultDataResponse not HTTPResponse...
In order to access the data/image you need to go with response.response. depending on what you want to access:
response.response?.value(forKey: "")
Check the other method calls and properties. I believe you will find the data you are looking for.

How to use NSURLConnection completionHandler with swift

Does anybody know how handlers (blocks) work in swift? I am trying to get this code running but i can't find any documentation of the right syntax for the completionHandler.
let url:NSURL = NSURL(string:"some url")
let request:NSURLRequest = NSURLRequest(URL:url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request:request, queue:queue, completionHandler handler:((NSURLResponse!, NSData!, NSError!) -> Void)!)
Like this:
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ response, data, error in /* Your code */ })
Or more verbose variant.
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
/* Your code */
})
You need to use this code:
NSURLConnection.sendAsynchronousRequest(request,queue:queue,completionHandler:{response,data,error in /* code goes here */ })
For more info, you can refer to this tutorial, or or check the answers to How to parse a JSON file in swift?.
sendAsynchronousRequest has been deprecated in newer versions of Swift. Move to dataTaskWithRequest, luckily it is used pretty much the same way
let request:NSURLRequest = NSURLRequest(URL:NSURL(string:"http://YOUR_DESIRED_URL.com")!)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
});
task.resume()
The right term you are looking for here is Closure. Closures in Swift are similar to blocks in C and Objective-C. In addition to Tomáš's answer there is another short version to use the completion handler here:
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler: {$0; $1; $2})
Here I have used Shorthand Argument Names. I am accessing response as $0, data as $1 and error as $3. I find this syntax more easy to read and write unless the parameters are large in number otherwise the code will become unreadable.

Extjs4.1, Retrieve response message after store sync

How to retrieve response message in failure function?
store.sync({
success : function(){},
failure : function(response, options){
console.log(response.responseText); //it does not work, because there is responseText attr in response
}
});
Response Text is like this,
{"success":false,"message":"Test Error"}
Anybody know, please advice me.
Thanks
[EDIT]
console.log(response);
then,
I'm not sure if you ever figured this out, but the suggestions above I'm pretty sure are wrong. You need to look at the request exception of the store proxy.
Here is some code to call before you do the store sync.
Ext.Ajax.on('requestexception', function (conn, response, options) {
if (response.status != 200) {
var errorData = Ext.JSON.decode(response.responseText);
Ext.Msg.alert('Creating User Failed',errorData.message);
}
});
Sorry for digging this old post up but it just hurt to see the answers above since I just went through the same struggle.
HTH's.
Here's what you need:
store.sync({
success: function(batch) {
Ext.Msg.alert('Success!', 'Changes saved successfully.');
},
failure: function(batch) {
Ext.Msg.alert("Failed", batch.operations[0].request.scope.reader.jsonData["message"]);
}
});
The long and short of it all of these answers are incorrect or inefficient.
Ext.Ajax.on can be used, but you will have to worry about race conditions for requests. Do not use this solution because it can trap you easily. The Ext.Ajax.on might get fired for something other than the sync. See exhibit a.
batch.operations[0].response.responseText can be used too, but this is not reliable way of obtaining the response as the "response" object will not always be populated (It depends on the request and if there are exceptions, 404, 500, success: false, etc.)
Exhibit a
// This picked up my autocomplete comboboxes load - not what I wanted!
Ext.Ajax.on({
requestcomplete: {
fn: callback,
scope: this,
single: true
},
requestexecption: {
fn: callback,
scope: this,
single: true
}
});
Current solution
This still does not have the response I am looking for, but meh.
store.sync({
failure: function (batch, eOpts) {
// 'this' is the Ext.data.proxy.Ajax object
// or whatever proxy you are using
var data = this.getReader().jsonData,
raw_data = this.getReader().rawData;
}
});
I am not sure how this handles my full exception stack of cases, but I will amend my post based on the server-side exceptions I discover (404, 500, etc.)