AFNetworking unable to serialize gzipped response (response object is nil) - ios

I'm using AFNetworking to download a .gzip file, that when uncompressed should return a JSON string. I've made the get request via my browser, the .gzip file is downloaded and when unzipped, the appropriate JSON is retrieved.
I know AFNetworking is built on NSURLConnection, and from what I read NSURLConnection has gzip inflation in built into it. However, I'm unable to uncompress and parse the gzip file returned by the server into JSON. The response object from AFNetworking remains nil. My code is as follows:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"gzip" forHTTPHeaderField:#"Accept-Encoding"];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/plain", #"application/x-gzip", nil];
[manager GET:[NSString stringWithFormat:#"%#%#", BASE_URL, GET_CONTENTS_URL] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
if(responseObject == nil){
NSLog(#"Response is still nil");
}
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
I'm unsure why this does not work.
Note 1: However, if I replace the response serializer to AFHTTPResponse serializer, the response object is not nil. However, it is of class _NSInlineData, which is an undocumented class.

I had the same problem, Finally I get work with the help of AFgzipRequestSerializer.
You need to use "AFgzipRequestSerializer".
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFgzipRequestSerializer serializerWithSerializer:[AFJSONRequestSerializer serializer]];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

In my case, I use AFHTTPSessionManager and it worked fine without using AFgzipRequestSerializer to decode the response.

Related

AFNetworking response cache issue?

I am sending GET request to server to getting json response. When i first do it i get some response but then i make changes in the database but still i get the same josn which i was getting.But on browser the json is updated on app it is not updated.I have used below code to make it work but nothing works for me.
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:url]];
[manager.requestSerializer setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:api_key forHTTPHeaderField:#"Authorization"];
manager.requestSerializer = requestSerializer;
AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];
responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript", #"text/html", nil];
manager.responseSerializer = responseSerializer;
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"json is %#",responseObject);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
[self activityIndicator:#"hide"];
NSLog(#"Error: %#", operation.responseString);
}];
I have tried reloadignoringcachedata but this does not work.

how to make rest api call with afnetworking iOS

Firstly I tried the same web service with advanced rest client. it works fine. but i am having difficulty writing the equivalent in afnetworking.
here is the Webservice.
http://devmybartersite.pantheon.io/myrestapi/barter_user/create?str= {"email":"sahildgfdffdfduuy#gmail.com","pass":"hello"}
i am able to get the response in advanced rest client in chrome. Additionally need to set a X-CSRF-Token in the header.
Here is my code
- (IBAction)pressed:(id)sender {
NSLog(#"You entered %#",self.username.text);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//header fields
[manager.requestSerializer setValue:#"vZu-YUFWLzIdFIn7VDoA6hV9IhrYe-BimkC1ncRdojU" forHTTPHeaderField:#"X-CSRF-Token"];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSDictionary *params = # {#"user":#"kjhkhkjhmnbbnjhio#gmail.com", #"pwd":#"hello" };
[manager POST:#"http://dev-my-barter-site.pantheon.io/myrestapi/barter_user/create" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
Default requestSerializer will transform your parameters to the following format user=kjhkhkjhmnbbnjhio#gmail.com&pwd=hello. In order to get JSON formatted request body, use AFJSONRequestSerializer:
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"..." forHTTPHeaderField:#"..."];
[manager.requestSerializer setValue:#"..." forHTTPHeaderField:#"..."];
than you send request:
[manager POST:....]

I cant get rid of Request failed: bad request (400)

NSDictionary *parameters = #{
#"project_name": #"hasanProj",
#"project_desc" : #"testing...",
#"project_date" : #"2015-2-22"
};
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:#"http://serverIP"]];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:[HRUser sharedUser].userApiKey forHTTPHeaderField:#"Authorization"];
[manager POST:#"/rest/v1/project" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#",responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"error: %#",error.localizedDescription);
}];
This code is returning Request failed: bad request (400).
I checked parameter, url they are all correct. I called it from chrome extension postman and getting correct result.
And other requests are working perfectly, even get is working fine.
But why I am getting Request failed: bad request (400) on this?
I was also facing the same error and this worked for me..
manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndex:400];
or
You can directly parse the response object.
i think there will be problem with the request. your putting wrong type or wrong data.
acceptableContentTypes for request also matters.
second thing the parameters that your sending data to it. check tags correct are not
ask WEB service developer exact need of API.
Code:
NSDictionary *parameters = #{
#"project_name": #"hasanProj",
#"project_desc" : #"testing...",
#"project_date" : #"2015-2-22"
};
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]init];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:[HRUser sharedUser].userApiKey forHTTPHeaderField:#"Authorization"];
[manager.requestSerializer.acceptableContentTypes setByAddingObject:#"application/json"];
[manager.responseSerializer.acceptableContentTypes setByAddingObject:#"application/json"];
[manager POST:#"http://serverIP/rest/v1/project" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(#"%#",responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"error: %#",error.localizedDescription);
}];

AFNetworking 2.0: is it possible to put pure json in the body of a POST request?

I would like to make the following request from my app:
AFHTTPRequestOperationManager *requestManager = [[AFHTTPRequestOperationManager alloc] init];
requestManager.responseSerializer.acceptableContentTypes = [requestManager.responseSerializer.acceptableContentTypes setByAddingObject:#"application/json"];
requestManager.requestSerializer = [AFJSONRequestSerializer serializer];
[requestManager POST:urlString parameters:aParameters constructingBodyWithBlock:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"%#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"error: %#", error);
}];
Where aParameters is an NSDictionary with the following content:
NSDictionary *urlParams = #{#"username" : anUser.userName, #"password" : anUser.password};
When I make the request from my app with the user input of "anUsername" and "aPassword" I get the following log for the body in my servlet:
--Boundary+5738A89B2C391231
Content-Disposition: form-data; name="password"
aPassword
--Boundary+5738A89B2C391231
Content-Disposition: form-data; name="username"
anUsername
--Boundary+5738A89B2C391231--
multipart/form-data; boundary=Boundary+5738A89B2C391231
I was under the impression that using AFJSONRequestSerializer would send my request in the appropriate format, but as the log shows, it's multipart/form data. It is really hard (for me) to parse this kind of request (I'm parsing it in Java on the server side), so my question is: is it possible to send a json in the body of my request? Something like this:
{
"userName" : "anUsername",
"password" : "aPassword"
}
Any help would be appreciated.
For anyone concerned: Instead of using the POST:parameters:constructingBodyWithBlock:success:failure: method, you should use POST:parameters:success:failure:. The former performs a multipart form request, while the latter does url form encoding. Additionally, to send the params in JSON, the requestSerializer property of the AFHTTPRequestOperationManager instance should be an instance of AFJSONRequestSerializer (by default it is set to AFHTTPRequestSerializer)
It is really helpful to browse the implementation file of AFHTTPRequestOperationManager for details, it helped me sort this error out.
You don't need to send pure JSON in POST request, just send Parameters dictionary. Here is the sample code that is working for POST Request.
+ (void)login:(BOUser *)user responseBlock:(APIRequestResponseBlock)responseBlock {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"parse-application-id-removed" forHTTPHeaderField:#"X-Parse-Application-Id"];
[manager.requestSerializer setValue:#"parse-rest-api-key-removed" forHTTPHeaderField:#"X-Parse-REST-API-Key"];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.securityPolicy.allowInvalidCertificates = YES;
NSString *URLString = [NSString stringWithFormat:#"%#login", BASE_URL_STRING];
NSDictionary *params = #{#"email": user.username,
#"password": user.password};
[manager POST:URLString parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
responseBlock(nil, FALSE, error);
}];
}
I hope it helps.

AFNetworking image download without using AFImageRequestOperation

I want to download a image from url and get NSData in response object.
This is how I set up the operation:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"image/jpeg"];
manager.responseSerializer = responseSerializer;
AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer];
[requestSerializer setValue:#"image/jpeg" forHTTPHeaderField:#"Accept"];
[requestSerializer setValue:#"image/jpeg" forHTTPHeaderField:#"Content-Type"];
manager.requestSerializer = requestSerializer;
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *data = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Response object is always nil, url is correct, when openned in browser it shows up the image, the operation descriptions shows content-length and content type(image/jpeg), but response object doesn't seem to pick it up.
Thank you
Answer: instead of responseObject, operation.reponseData need to be used.
You will need to tell AFNetworking that you expect image data and that to should be deserialized as that.
manager.responseSerializer = [AFImageResponseSerializer serializer];
AFImageResponseSerializer Class Reference
By default, AFImageSerializer accepts the following MIME types, which
correspond to the image formats supported by UIImage or NSImage:
image/tiff
image/jpeg
image/gif
image/png
image/ico
image/x-icon
image/bmp
image/x-bmp
image/x-xbitmap
image/x-win-bitmap
Answer: instead of responseObject, operation.reponseData need to be used.
if you would user proper serialization, it would be responseObject, transformed into a object you can immediately use. operation.reponseData contains the raw data sent from the server. usually it is not what you need.

Resources