I am hitting a API for push notification and it is giving me error.
I am passing parameter as a string in API like this:
NSString * jsonString= [NSString stringWithFormat:#"{\"device_id\":%#,\"device_type\":I,\"regId\":%#}",[AppDelegate getMacAddress],deviceToken];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager POST:kNotificationURL
parameters:jsonString
progress:nil
success:^(NSURLSessionTask *task, id responseObject) {
NSLog(#"notification JSON: %#", responseObject);
NSDictionary *json = [Utility cleanJsonToObject:responseObject];
NSError * err;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:json
options:0
error:&err];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData
options:kNilOptions
error:&err];
NSLog(#"the data is %#",dict);
}
failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#" notification Error: %#", error);
}];
The error I am getting:
Response :Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
please let me know, what have i do wrong
A quick and dirty fix would be to try this, although building your own JSON string isn't a good idea. Look at using JSONSerialization
[NSString stringWithFormat:#"{\"device_id\":\"%#\",\"device_type\":\"I\",\"regId\":\"%#\"}",[AppDelegate getMacAddress],deviceToken];
Related
I am getting response data from a server using AFHTTPRequestOperation in AfNetworking 2.0
NSURLRequest *request = [[ServiceHelper instance] getRequestData:postDict :[ServicesConfiguration GET_DOCUMENTS_URL]];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFHTTPRequestOperation *requestOperation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *returnData = [[ServiceHelper instance] getReturnDictionary:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
The getReturnDictionary method called on the responseObject is a simple JSON Serializer..
- (NSDictionary *) getReturnDictionary : (NSData *) data {
if ( data == nil ) {
return [NSDictionary dictionary];
}
NSError * error = nil;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error != nil) {
NSLog(#"Error parsing JSON: %#",error);
return [NSDictionary dictionary];
}
else
return jsonDict;
}
This works fine for smaller amounts of data. But when the response object is like 100mb, the app hangs on
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
And then about 15 seconds later, the app crashes due to a memory error.
I think its pretty self explanatory that its the massive size of the data, but shouldn't it be able to handle it?
If I get the data directly from an [ NSURLConnection sendSynchronousRequest:]; - it works without hanging or crashing. As this is what I was doing originally - but switching to AFNetworking to display a progress bar more easily.
Any thoughts or tips are appreciated.
Update:
So You have 2 options to solve this:
Blockquote
Use NSJSONReadingMutableContainers as options
Blockquote
If previous does not work you are facing a known issue like below:
iOS Download & Parsing Large JSON responses is causing CFData (store) leaks
So now you have 2 options:
Use native JSON Serialization
First downloading the JSON files to disk without using AFNetworking and than parse.
I am trying to figure out how to make use of AFNetworking 2.0. I am trying to POST a login with a username and password.
This is my current attempt but something is not working as it does not get sent.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"loginName": #"password"};
[manager POST:#"http://xxxx.com/login" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSLog(#"Data saved");
MainViewController *mainView = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
mainView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController: mainView animated:YES completion:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
NSString *error_msg = (NSString *) error;
[self alertStatus:error_msg :#"Sign in Failed!" :0];
}];
}
} #catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self alertStatus:#"Sign in Failed." :#"Error!" :0];
}
However nothing is happening, just keep getting this printout:
2014-04-16 20:14:09.903 Slidedrawer[9279:60b] 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=0x8e78bd0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
The response will be in JSON. Anyone know what I need to edit in the code or how to fix it?
JSON: {
"_id" = 533cb1c453769a02008c2d55;
name = dddd;
picture = "/img/users/default.jpg";
}
How do I access the above returned JSON, trying to pick apart each returned property to a string or integer etc...
Try this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"userName": username, #"password": password};
manager.responseSerializer = [AFJSONResponseSerializer serializer]; // if response JSON format
[manager POST:#"http://asd.com/login.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", error);
}];
For parsing the response use this the responseObject as NSDictionary:
NSString *userName = [responseObject objectForKey:#"userName"];
NSString *password = [responseObject objectForKey:#"password"];
Hope this helps.. :)
You may find Send Nested JSON using AFNetworking for the answer.
The error Error Domain=NSCocoaErrorDomain Code=3840 is received invalid JSON object from the server. It is probably caused by the server's improper handling your missing parameters . Your parameters dictionary has only one key object loginName.
I have tried several option setting responseSerializer to JSON but i am unable to convert responseObject to NSDictionary. The problem is response i am getting is NSData
NSString *baseURLString = #"Your URL?";
NSString *str = #"adult=false&gender=male";
NSString *url = [NSString stringWithFormat:#"%#%#",baseURLString,str];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// do whatever you'd like here; for example, if you want to convert
// it to a string and log it, you might do something like:
NSLog(#"responseObject %#",responseObject);
NSString *jsonString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"%#", jsonString);
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseObject
options:NSJSONReadingMutableContainers
error:&error];
NSLog(#"json %#",json);
if (error) {
NSLog(#"%#",[error description]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
This NSLog(#"%#",[error description]); gives error as follows:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed.
(Cocoa error 3840.)" (Garbage at end.)
UserInfo=0xa7c5440 {NSDebugDescription=Garbage at end.}
Your JSON is coming back with garbage at the end.
You should fix your webservice to not embed timestamp and language at the end of your JSON. If you can not change your webservice, then use following to remove trailing garbage from your json before parsing it with NSJSONSerialization again.
NSRange range = [jsonString rangeOfString:#"}" options:NSBackwardsSearch];
jsonString = [jsonString substringToIndex:range.location + 1];
Then parse this cleaned up jsonString to NSDictionary:
NSData *newJSONData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:newJSONData
options:NSJSONReadingMutableContainers
error:&error];
NSLog(#"json %#",json);
It should work just fine.
Your data is not a valid JSON you can check in this JSON Formatter provide the url or copy paste the JSON data and hit process you will see that its not a valid JSON.
The reason it not valid is it contains This page was created in 0.0048439502716064 seconds this message at the end of its response. If have control in the server side than try to stop sending this line in the end or try to remove this line and the convert it to NSDictionary. Hope this helps .. :)
I am using AFNetworking framework in my app, I am able to make HTTP request and able to get response from server but i am not able to parse the JSON.
The following is my code:
I have created a singleton class called WebServices and have created a method, which makes HTTP request.
+(void)getCompaniesc:(NSString *)companyID onSucess:(PSACompletionBlock2)onSucess
{
NSDictionary *params = #{#"companyId": companyID};
[[[WebServices sharedInstance] operationQueue] cancelAllOperations];
[[WebServices sharedInstance] postPath:#"GetCompany?" parameters:params success:^(AFHTTPRequestOperation *operation, id response)
{
NSString *st = [NSString stringWithFormat:#"%#",response];
NSLog(#"st=%#",st);
if (onSucess)
{
onSucess(YES, response);
}
}failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(#"%s: AFHTTPRequestOperation error: %#", __FUNCTION__, error);
}];
}
and from my ViewController I am calling the above function using the following code:
[WebServicesClass getCompaniesc:companyID onSucess:^(BOOL success, id jsonresponse) {
}];
I'm getting the response from the server which is type id.
And the following is my response from Server:
[{"ExistsInDB":"False","CanSave":"True","EntityName":"ACCOUNT","TypeDescription":"Company","TypePluralDescription":"Companies","RequiredProperties":"Chiever.Data.SAQueryFieldSet","MetaData":"","ReadOnly":"False","ACCTNAME":"","AREA_ID": "","ACCT_TYPE_ID":"","ADDR1":"","ADDR2":"","ADDR3":"","TOWN”:””,”COUNTY":"","POSTCODE":"","COUNTRY":"","TEL":"","FAX":"","EMAILORWEB":"","BUYGRP_ID": "","STATUS":"","SIC_CODE_ID”:””,”CURRENCY_ID":"","CALL_FREQ": "0","DORMANT":"False","CREATOR_ID": "","CREATED_ON":"01/01/0001 00:00:00","LAST_EDITOR_ID":"","LAST_EDITED":"01/01/0001 00:00:00","LAST_ACTION_BY":"","LAST_ACTION":"01/01/0001 00:00:00","NEXT_ACTION_BY":"","NEXT_ACTION":"01/01/0001 00:00:00","LOCALE_ID":"","BusinessUnits": "System.Collections.Generic.List`1[chiever.Platform.LookupIdValuePair]","ACCT_ID":"0000000320"}]
Can any one help me out with this?
Just do this check:
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData: jsonresponse options:NSJSONReadingMutableContainers error:&error];
if your return is an array, use this:
NSArray *arr = [NSJSONSerialization JSONObjectWithData: jsonresponse options:NSJSONReadingMutableContainers error:&error];
A.) If you're using AFHTTPRequestOperation make sure you're setting the responseSerializer:
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
operation.responseSerializer = [AFJSONParserResponseSerializer serializer];
Also, make sure that you're setting request "Content-Type" to be "text/json". Now, if you're getting JSON response from the server, then you probably should get a dictionary responseObject.
B.) If you're still getting an NSData, you can convert the NSData to NSString to see/debug what you're getting from the server:
NSString *stringResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // Use appropriate encoding
NSLog(#"String Response: %#", stringResponse);
C.) If you're sure that you're getting json response from the server, you can always convert the raw NSData response to NSDictionary using json serialization:
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"JSON: %#", json);
Hope this helps.
If your server returns the "Content-Type: application/json" header, you will get a NSDictionary with the json response from AFNetworking. Or in your case, a NSArray with NSDictionaries included.
In PHP, the headers can be modified by adding
header('Content-Type: application/json');
to the top of your script.
I have this call with AFNetworking 1.0 that returns a responseObject with the data from the API that I want:
[[AFDiffbotClient sharedClient] postPath:#"http://diffbot.com/api/batch" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
However, I have no idea how to process responseObject.
If I check [responseObject class] I get NSData.
If I NSLog(#"%#", responseObject) I get a bunch of numbers (memory addresses I assume):
<5b0a7b22 68656164 65727322 3a5b7b22 6e616d65 223a6e75 6c6c2c22 76616c75 65223a22 48545450 2f312e31 20323030 204f4b22 7d2c7b22 6e616d65 223a2244 61746522 2c227661 ...
If I do:
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"%#", responseString);
I get the output that I want! But, it's an NSString.
If I do:
NSError *error;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"%#", responseDictionary);
I get an NSDictionary, but it's missing the vast majority of the response (i.e.: I don't get what's included with the NSString method).
How should I be processing this object?
This is how I do it..
- (void) requestDataFinish:(NSData *)data withError:(NSError *)networkError
{
NSDictionary *responseData;
NSError *error = nil;
if (data != nil) {
responseData = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
}
...