I'm having difficulties to get responseString when server failed to send a valid JSON response (fe. php echos some temp variable or something went wrong). I am using AFJSONRequestOperation from AFNetwoking like this:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id responseObject) {
NSLog(#"object: %#", responseObject);
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id responseString) {
NSLog(#"failure: %#", responseString);
}
];
responseString is case of failure is always nil. When I tried to read the documentation (http://cocoadocs.org/docsets/AFNetworking/1.3.1/Classes/AFJSONRequestOperation.html#//api/name/JSONRequestOperationWithRequest:success:failure:) I've found that there is written that failure gets three arguments (but in reality four, the fourth being always nil). Is there any simple way to get the response as a string in that case?
If responseString is nil, then you either didn't receive any data from the server, or the data could not be used to create a valid NSString object.
By the sound of your Cocoa error 3840, which corresponds to an NSJSONSerialization error, my guess is that the server was indeed sending back an empty response.
Related
I am developing app which require to use OAuth1.0 for call API.
I am able to Authenticate with OAuth1 and call GET method API.
But when I try to call POST method with passing JSON object. It give me "oauth_problem=signature_invalid"
Code for request :
NSMutableURLRequest *request = [self.twitterClient requestWithMethod:#"POST" path:apiURL parameters:jsonObj];
AFJSONRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"Success: %#", JSON);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Error: %#", error);
}];
[jsonOperation start];
I am struggling with this. Any help will be appreciated. Thanks in advance.
I finally solve problem.
In my case problem was with signature_method
I set..
self.twitterClient.signatureMethod = AFPlainTextSignatureMethod;
before call request. And it works.
This is my code for requesting a JSON:
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
NSArray *jsonArray =[JSON valueForKey:#"posts"];
[self postsToAnnotations:[self jsonToPosts:jsonArray] andUserLocationLat:lat Lon:lon];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){
NSLog(#"response %#",JSON);
NSLog(#"Failed %#",error);
[_activityView removeFromSuperview];
}];
[operation start];
}
It's working fine on simulator for iPhone 5 and in my device (iphone 4) I am getting this error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x208b9a80 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
The problem was with the reply of the server which I was not able to see because I was using AFJSONRequestOperation. After sending the same request AFHTTPRequestOperation I was able to see the reply of the server using "result" string.
I'm doing a request to the server and the server returns a JSON. AFNetworking framework returns a wrong formatted JSON.
This is what the server sends:
{"email":"XXXXXXX","firstName":"XXXXXX","lastName":"XXXXXXX","gender":"male","userToken":"XXXXXXXXXXX"}
This is what AFNetworking receives:
{
email = "XXXXXXX";
firstName = XXXXXX;
gender = male;
lastName = XXXXXXX;
token = XXXXXXXXXXXX;
}
My code:
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:server_ip]];
NSURLRequest *request = [client requestWithMethod:#"POST" path:path parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"%#", JSON);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
The object you are printing out is the NSDictionary representation of the JSON received from the server.
If you want to see the raw JSON returned from the server, you should look at the responseString of the operation:
NSLog(#"%#", operation.responseString);
When i request data from server with AFHHTPClient this way:
[[NetworkHelper sharedHelper] postPath:path parameters:parameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", [operation class]);
NSLog(#"%#", [responseObject class]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", [error localizedDescription]);
}];
I got this:
2012-10-10 13:24:36.881 MyApp[4635:c07] AFHTTPRequestOperation
2012-10-10 13:24:36.881 MyApp[4635:c07] NSConcreteData
I tried to force application/json content-type in server's response, but i still got AFHTTPRequestOperation.
But if i use this:
[[AFJSONRequestOperation JSONRequestOperationWithRequest:[NSURLRequest requestWithURL:myURL] success:^(NSURLRequest *request, NSURLResponse *response, id JSON) {
NSLog(#"%#", JSON);
} failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON) {
NSLog(#"%#", [error localizedDescription]);
}] start];
I got JSON responce i need.
What should i do to get JSON response with AFHTTPClient?
UPDATE:
I add NSLog(#"%#",[self.response MIMEType]); in - (BOOL)hasAcceptableContentType method in AFHTTPRequestOperation class and i recieve
2012-10-11 09:48:25.052 MyApp[3339:3803] application/json
but i still get AFHTTPRequestOperation class.
Try to set AFHTTPRequestOperation:acceptableContentTypes:
+ (NSSet *)acceptableContentTypes {
return [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript", nil];
}
I've had the same problem that I suspect may have something to do with the way AFJSONRequestOperation handles responses.
I've dispatched the exact same request using AFJSONRequestOperation using the NSMutableURLRequest returned from [AFHTTPClient clientRequestWithMethod] and constructing my own NSMutableURLRequest and each has a response with a different mime type — the one from [AFHTTPClient clientRequestWithMethod] indicates text/plain; the one from NSMutableURLRequest constructed "by hand" is text/json.
I've mentioned this here in this question:
AFNetworking with AFHTTPClient with AFJSONRequestOperation // MIME-Type Issues
I have the following code for JSON Parsing:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.dropbox.com/s/qz16qyi3julygl9/facebook.json"]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#"Request Success %#",[JSON class]);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failure Because %#",[error userInfo]);
}];
[operation start];
but I have Request Failure with the following error message:
NSErrorFailingURLKey = "https://www.dropbox.com/s/qz16qyi3julygl9/facebook.json";
NSLocalizedDescription = "Expected content type {(\n \"text/json\",\n \"application/json\",\n \"text/javascript\"\n)}, got text/html";
can somebody help me?
In my errorlog it prints "got text/html". So just add
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]]
It works.
[AFJSONRequestOperation addAcceptableContentTypes:#"text/plain"]
The above is deprecated from AFNetworking 2.x. Instead you can call the following on the instance of the AFHTTPRequestOperation as follows
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
Where manager is your instance of AFHTTPRequestOperation.
Source: https://github.com/AFNetworking/AFNetworking/issues/1381
Because the link you provide doesn't hotlink the file. It links to an HTML page to download the file. Try going there in a browser...
Try this link instead: https://dl.dropbox.com/s/qz16qyi3julygl9/facebook.json?dl=1 No guarantees it will work though. A lot of companies frown on directly linking to files in this way.