I am getting this error while posting json to url :
Invalid top-level type in JSON write'
I am even sending perfect JSON using afnetworking post request code But it keeps giving me error.
My code :
NSString * serviceType = #"xyz";
NSString * remarks =#"project deadline is near ";
NSString * emailId = #"xyx.live.com";
NSDictionary *params =
# {
#"serviceType" :serviceType,
#"remarks" :remarks,
#"emailId" :emailId
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
options:0
error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *manager2 = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
manager2.requestSerializer = serializer;
[manager2 POST:#"http://xyx.com" parameters:jsonString success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON_post_fzzlogin: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//here is place for code executed in success case
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error while sending POST"
message:#"Sorry, try again."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
NSLog(#"Error: %#", error);
}];
Please help me out this regard .thanks in advance
You are trying to encode request twice because you set request serializer for AFHTTPRequestOperationManager and provide parameters as encoded JSON string. So you need to provide raw parameters if you want to use request serializer or don't use it and encode to JSON manually.
This is how you post JSON or rather NSDictionary by AFNetworking
NSDictionary *dict = #{#"Key":#"Value"};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:[Util urlAppend:kListOfArticleCatagory] parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *responseObj = (NSDictionary *)responseObject;//casting to NSDictionary from id
NSLog(#"%#",responseObj);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Something went wrong :%#",operation.responseString);
}];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
}
You dont post JSON through AFNetworking, rather the NSDictionary as the parameters, it will get converted to JSON as you post it.
Related
Hii I am using afnetworking from post array data to sent server side here is my code ...
NSMutableDictionary *dict1=[[NSMutableDictionary alloc]initWithObjectsAndKeys:#"online_status",#"option_name",dict[#"option_value"],#"option_value", nil];
NSArray *arr1=[[NSMutableArray alloc]initWithObjects:dict1, nil];
NSMutableDictionary *dict2=[[NSMutableDictionary alloc]initWithObjectsAndKeys:[UserDefaults valueForKey:#"user_id"],#"user_id",arr1,#"option_array", nil];
NSError *error = nil;
NSString *createJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dict2
options:NSJSONWritingPrettyPrinted
error:&error]
encoding:NSUTF8StringEncoding];
NSDictionary *pardsams = #{#"data": createJSON};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSLog(#"Dict %#",pardsams[#"data"]);
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
[manager POST:[NSString stringWithFormat:#"%#set_user_multiple_options",K_APP_URL] parameters: pardsams[#"data"] success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
and getting server responce is :
message = "Required parameters missing.";
status = 0;
i will hit the request to rest client but where getting correct responce saved data bt trying to do in code it not working polease... help me
i need to convert an array into json and send it as a parameter in a url along with other parameters. I am using jsonKit for json conversion and AFNetworking for network communication.But it always gives exception in the json at the server.
Here is the code used for son conversion:
NSString *jsonData = [self.finalArray JSONString];
NSString *data = [NSString stringWithFormat:#"%s",[jsonData UTF8String] ];
This data is finally send as a parameter in the url.
code for network communication :
postData=[postData stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSURL *requestUrl = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#%#",url,postData]];
NSURLRequest *request =[[NSURLRequest alloc] initWithURL:requestUrl];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
[operation setCompletionBlockWithSuccess:success failure:failure];
[operation start];
Also used following for escape characters:
[postData stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Error received :
Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSUnderlyingError=0x7d51e9a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL}}, NSLocalizedDescription=unsupported URL}
I think you should use it like this
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *strURL = [NSString stringWithFormat:#"%#/add-product.php", apiPrefix];
[manager POST:strURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictData options:0 error:&error]; // dictData is your dictionary
NSAssert(jsonData, #"Failure building JSON: %#", error);
NSDictionary *jsonHeaders = #{#"Content-Disposition" : #"form-data; name=\"data\""}; // data is your parameter name in which you have to pass the json
[formData appendPartWithHeaders:jsonHeaders body:jsonData];
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
Hope this will help....
Following code is to submit images through an operationQueue. The requests are all fired one by one correctly, the server response contains the image file name which client needs to get hold of. The problem is that the reponseObject for the success/failure block is not expected parsed JSON but type of NSInLineData shown in debugger. Now I suspect the code to construct the operation from the NSMutableURLRequest caused the issue. Please help.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSMutableURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:#"POST"
URLString:podURLString parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSError *error;
BOOL success =[formData appendPartWithFileURL:imgURL name:#"images" fileName:img.path
mimeType:#"image/jpg" error:nil];
if (!success)
NSLog(#"appendPartWithFileURL error: %#", error);} error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Image Success: %#", [responseObject description]);
NSString *imagePath = [response objectForKey:#"imageFileName"];
[self.delegate networkManager:self didSubmitDeliveryImageForImageID:imagePath];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image Error: %#", error);
NSLog(#"image error: %#", [operation.responseObject description]);
NSString *imageFilePath = [operation.responseObject objectForKey:#"imageFileName"];
[self.delegate networkManager:self didFailSubmitDeliveryImageForImageID:imageFilePath];
}];
[manager.operationQueue addOperation:operation];
When you get the response as NSInLineData. It's good to go now. You can write below single line of code to get NSDictionary if it supports json format.
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObjec options:0 error:nil];
Just add this line of code before your AFHTTPRequestOperation block
**operation.responseSerializer = [AFJSONResponseSerializer serializer];**
I am implementing following paypal REST API:
curl -v https://api.sandbox.paypal.com/v1/vault/credit-card \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {accessToken}' \
-d '{
"payer_id":"user12345",
"type":"visa",
"number":"4417119669820331",
"expire_month":"11",
"expire_year":"2018",
"first_name":"Joe",
"last_name":"Shopper"
}'
I have successfully implement this api in AFNetworking 1.3.3 with following Code. Where PPWebService is subclass of AFHTTPClient
[[PPWebService sharedClient] setParameterEncoding:AFJSONParameterEncoding];
[[PPWebService sharedClient] setDefaultHeader:#"Content-Type" value:#"application/json"];
[[PPWebService sharedClient] setDefaultHeader:#"Authorization" value:[NSString stringWithFormat:#"Bearer %#", accessToken]];
[[PPWebService sharedClient] postPath:#"vault/credit-card"
parameters:creditCard
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *response = [self JSONToObject:operation.responseString];
creditCardId = response[#"id"];
if(creditCardId)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Credit card" message:#"Saved !!" delegate:nil cancelButtonTitle:#"on" otherButtonTitles:nil];
[alert show];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Credit card" message:error.description delegate:nil cancelButtonTitle:#"on" otherButtonTitles:nil];
[alert show];
}];
I want to use AFNetworking 2.x.x in my project. But I am not able to do it with this new version.
I have subclass AFHTTPRequestOperationManager. I search internet and people suggest me to use AFJSONRequestSerializer. All other code is very similar. But than also I am getting bad request error.
So how can I send raw JSON string in with POST method in AFNetworking 2.x.x?
EDIT
Code for AFNetworking 2.X.X
Error Status : 404 Bad Request
Response :
{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/docs/api/#MALFORMED_REQUEST","debug_id":"ab3c1dd874a07"}
I am getting proper response by using Postman as shown in following screenshot.
So finally I got answer. I use subclass of AFHTTPSessionManager to implement API in my project. And use it with singleton object. So this is my singleton method.
+ (MASWebService *)APIClient
{
static MASWebService *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
NSURL *baseURL = [NSURL URLWithString:BaseURL];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_sharedClient = [[MASWebService alloc] initWithBaseURL:baseURL sessionConfiguration:config];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
_sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];
[_sharedClient.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
});
return _sharedClient;
}
The main key line is setting Request Serializer HTTP Header "Content-Type" to "application/json"
If you are not subclassing AFHTTPSessionManager and using AFHTTPRequestOperationManager for single request than also it will work because AFHTTPRequestOperationManager is also conform to AFURLRequestSerialization protocol as property of AFHTTPRequestSerializer. I have not done it but it should look like this.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
I hope this will work. Inform me in comment if I am wrong somewhere.
Source : AFNetworking 2.0 POST request working example code snippet
So how can I send raw JSON string in with POST method in AFNetworking 2.x.x?
I had the same issue when trying to use SOAP+XML data with AFHTTPRequestOperationManager. Apparently the request serializer should be subclassed to make provision for your special serialisation needs, but this way seems easier:
NSError *error = nil;
NSData *envelopeData = [NSJSONSerialization dataWithJSONObject:params options:options error:nil];
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:#"POST"
URLString:path
parameters:nil
error:&error];
// In my case, I also needed the following:
// [request setValue:action forHTTPHeaderField:#"SOAPAction"];
[request setHTTPBody:envelopeData];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] init];
operation = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
// parse response here
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// parse response here
}];
It hijacks the request serialiser that is created by AFHTTPRequestOperationManager, inserts the parameter data into the HTTP body, and then passes this new request into the AFHTTPRequestOperation.
I
ve been using AFNetworking 2 with success for some time, but I stumbled upon case where I don't know where to turn my head to. I have to make POST request in order to log in, send credentials alongside and receive JSON back with operation status. For some weird reason sending it via AFNetworking like this:
NSDictionary *params = #{#"login": self.loginField.text, #"password" : self.passField.text};
NSDictionary *data = #{#"data": params};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
//manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:server parameters:#{#"data" : params} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);
}];
I have to pack dictionary with parameters as a single "data" parameter. I do get back OK 200, but if I take a look in server logs I see that no data was transferred, which ended up as user not recognized.
But if send with curl this:
curl -d 'data={"login":"xx", "password":"yy"}' http://someurl/api/login/
I got perfectly fine response and in logs I see some actual data. Does anyone know how to deal with such a case?
If it helps, I'm doing it in iPhone simulator, not tested on actual device.
If you have a look at the AFNetworking source code, namely the class AFJSONRequestSerializer, you will see that the serialise function for that serialiser puts the parameters you hand over into the body - and not as an HTTP parameter as you expect.
You should use an AFHTTPRequestSerializer in your case - that will add the parameters as (URL-encoded) HTTP parameters to your URL.
Something like that should work in your case:
// build the JSON parameter string
NSDictionary *params = #{#"login": self.loginField.text, #"password" : self.passField.text};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
options:0
error:&error];
NSString *jsonString = [[NSString alloc] initWithBytes:[jsonData bytes]
length:[jsonData length]
encoding:NSUTF8StringEncoding];
// and now send the JSON parameter string as HTTP parameter
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager POST:server
parameters:#{#"data" : jsonString}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);
}];