AFHTTPRequestOperationManager JSON data to Array - ios

I'm using AFNetworking 2.0 to make a POST request to my web service that returns JSON data.
{
post = {
"first_name" = Joe;
"last_name" = Blogs;
"user_id" = 1;
};
},
{
post = {
"first_name" = Bill;
"last_name" = Gates;
"user_id" = 2;
};
}
Im able to print out responseObject to the console fine which displays my JSON data.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"user": #"root"};
[manager POST:#"http://192.168.0.100/webservice.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSString *responseString = [operation responseString];
NSError *error;
NSArray *json = [NSJSONSerialization
JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding]
options:kNilOptions
error:&error];
for (NSDictionary *dictionary in json)
{
NSString *firstName = [[dictionary objectForKey:#"post"] valueForKey:#"first_name"];
NSLog(#"%#", firstName);
NSString *lastName = [[dictionary objectForKey:#"post"] valueForKey:#"last_name"];
NSLog(#"%#", lastName);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
Each "post" is going to be used for a table cell on my View Controller. Im struggling to understand how to make each post an object in an array. Any help appriciated.

UPDATE
You can use this code snipped to perform your desired functionality:
NSString *responseString = [operation responseString];
NSData *data= [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSArray* results = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
for (int i=0; i<results.count; i++)
{
NSDictionary *res=[results objectAtIndex:i];
NSDictionary *res2=[res objectForKey:#"post"];
[self.storesArray addObject:res2];
}
[self.tableView reloadData];
and in your CellForRowAtIndexPath method, use this code snipped to show data on your cell:
NSDictionary *res=[self.storesArray objectAtIndex:indexPath.row];
cell.firstName.text=[res objectForKey:#"first_name"];
cell.lastName.text=[res objectForKey:#"last_name"];
This NSDictionary works in key values pair style, so you can get the value of any key by just mentioning the key name and get the values of that key.

Related

Objective C JSON parse from NSMutableArray

I have a JSON like below (getting from an URL)-
{
action :getAllJournal;
data :{
journalList :[{
cancelled : F;
"cust_code" : "700-T022";
"journal_amount" : 2216;
"journal_code" : "JV1603/001";
"journal_date" : "2016-03-15 00:00:00";
"journal_id" : 1;
outstanding : 0;
},
{
cancelled : F;
"cust_code" : "700-0380";
"journal_amount" : 120;
"journal_code" : "JV1605/006";
"journal_date" : "2016-05-31 00:00:00";
"journal_id" : 2;
outstanding : 120;
},
{
cancelled : F;
"cust_code" : "700-T280";
"journal_amount" : 57;
"journal_code" : "JV1609/001";
"journal_date" : "2016-09-22 00:00:00";
"journal_id" : 3;
outstanding : 0;
}
];
};
message = "";
"message_code" = "";
result = 1;}
The code below doing is getting the JSON from URL and storing them in NSMutableArray. Until storing them into array, it's working fine but I'm bit confused with the JSON format and don't know how to get result by a key.
__block NSMutableArray *jsonArray = nil;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSString *urlString = [NSString stringWithFormat:#"http://xxxxxxx/api.php?action=getAllJournal"];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
{
if (data)
{
id myJSON;
#try {
myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}
#catch (NSException *exception) {
}
#finally {
}
jsonArray = (NSMutableArray *)myJSON;
NSString *nsstring = [jsonArray description];
NSLog(#"IN STRING -> %#",nsstring);
NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError;
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if(jsonObject !=nil){
if(![[jsonObject objectForKey:#"journalList"] isEqual:#""]){
NSMutableArray *array=[jsonObject objectForKey:#"journalList"];
NSLog(#"array: %lu",(unsigned long)array.count);
int k = 0;
for(int z = 0; z<array.count;z++){
NSString *strfd = [NSString stringWithFormat:#"%d",k];
NSDictionary *dicr = jsonObject[#"journalList"][strfd];
k=k+1;
// NSLog(#"dicr: %#",dicr);
NSLog(#"cust_code - journal_amount : %# - %#",
[NSMutableString stringWithFormat:#"%#",[dicr objectForKey:#"cust_code"]],
[NSMutableString stringWithFormat:#"%#",[dicr objectForKey:#"journal_amount"]]);
}
}
}else{
NSLog(#"Error - %#",jsonError);
}
}
}];
From this, I am able to get the JSON successfully. But it's always giving me this error: Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in an object around character 6." UserInfo={NSDebugDescription=No string key for value in an object around character 6.} How can I get all values from journalList? I'm new to iOS, that's why not sure what I'm missing.
id myJSON;
#try {
myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}
#catch (NSException *exception) {
}
#finally {
}
jsonArray = (NSMutableArray *)myJSON;
NSString *nsstring = [jsonArray description];
NSLog(#"IN STRING -> %#",nsstring);
NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError;
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
I'd say: NO and NO.
I wouldn't do a #try/#catch on a NSJSONSerialization, because the real issues are on the error parameter (and they won't throw a NSException for most of the cases). Just check if (data) is quite efficient.
Then, let's say it worked, and you have myJSON.
In fact, myJSON is a NSDictionary, not a NSArray, so the cast is useless and doesn't make sense.
Next issue:
Your are using -description (okay, if you want to debug), but you CAN'T use it to reconstruct AGAIN a JSON. It's not a valid JSON, it's the way the compiler "print" an object, it adds ";", etc.
If your print [nsstring dataUsingEncoding:NSUTF8StringEncoding] and data you'll see that they aren't the same.
For a more readable:
NSString *dataJSONStr = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];, it's clearly not the same structure as your nsstring.
Then, you are redoing the JSON serialization? Why ?
So:
NSError *errorJSON = nil;
NSDictionary *myJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&errorJSON];
if (errorJSON)
{
NSLog(#"Oops error JSON: %#", errorJSON);
}
NSDictionary *data = myJSON[#"data"];
NSArray *journalList = data[#"journalList"]
for (NSDictionary *aJournalDict in journalList)
{
NSUInteger amount = [aJournalDict[#"journal_amount"] integerValue];
NSString *code = aJournalDict[#"journal_code"];
}
There is a dictionary named "data" you're not fetching, represented by {}.
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (!jsonError) {
// Fetch the journalList
NSArray *journalList = json[#"data"][#"journalList"];
// iterate over every entry and output the wanted values
for (NSDictionary *journal in journalList) {
NSLog(#"%# %#", journal[#"cust_code"], journal[#"journal_amount"]);
}
}
json[#"key"] is a short form of [json objectForKey:#"key"] I find easier to read.
That is not a valid JSON. Entries should be separated by comma ,, not semicolon ;
You need to fetch journalList from data.
Try below code:
This is demo code to create array like you:
NSMutableDictionary *jsonObject = [NSMutableDictionary new];
jsonObject[#"action"]= #"";
jsonObject[#"message"]= #"";
jsonObject[#"message_code"]= #"";
jsonObject[#"result"]= #"1";
NSMutableArray *ary1 = [NSMutableArray new];
for(int i=0;i<5;i++)
{
NSMutableDictionary *dd = [NSMutableDictionary new];
dd[#"cancelled"]= #"F";
dd[#"cust_code"]= #"F";
[ary1 addObject:dd];
}
NSMutableDictionary *dicjournal = [NSMutableDictionary new];
[dicjournal setObject:ary1 forKey:#"journalList"];
[jsonObject setObject:dicjournal forKey:#"data"];
This is main Logic:
NSMutableArray *journalList = [NSMutableArray new];
NSMutableDictionary *dic = [jsonObject valueForKey:#"data"];
journalList = [[dic objectForKey:#"journalList"] mutableCopy];
Looks like your JSON is invalid. You can see whether your JSON is correct or not using http://jsonviewer.stack.hu/ and moreover format it. Meanwhile your code is not using "data" key to fetch "journalList" array.
Code : -
NSDictionary *dic = [jsonObject valueForKey:#"data"];
NSMutableArray *arr = [dic objectForKey:#"journalList"];
for (int index=0 ; index < arr.count ; index++){
NSDictionary *obj = [arr objectAtIndex:index];
// Now use object for key from this obj to get particular key
}
Thanks #Larme and #Amset for the help. I was doing wrong the in the NSMutableArray part. The correct version of this code is in the below:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSString *urlString = [NSString stringWithFormat:#"http://xxxxxxx/api.php?action=getAllJournal"];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
{
if (data)
{
id myJSON;
#try {
myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
}
#catch (NSException *exception) {
}
#finally {
}
NSArray *journalList = myJSON[#"data"][#"journalList"];
for (NSDictionary *journal in journalList) {
NSLog(#"%# %#", journal[#"journal_date"], journal[#"journal_amount"]);
}
}
}];

Objective C Accessing Elements

I'm attempting to obtain elements extracted from a dictionary and convert them to doubles. The data is being pulled from JSON and seems to be extracted into a type of array (not sure which type). Is there a way to obtain the numbers listed below individually out of the array? Please let me know if you need more information.
NSDictionary *parameters = #{#"username":savedUser,#"password":savedPass};
NSURL *URL = [NSURL URLWithString:#"testwebsite"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:URL.absoluteString parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject)
{
NSError *error = nil;
JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (error) {
NSLog(#"Error serializing %#", error);
}
NSLog(#"%#",JSON);
NSString *price = [NSString stringWithFormat:#"%#",[JSON valueForKey:#"UnitPrice"]];
price= [price stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSLog(#"Price: %#",price);
[transactionTotals addObject:price];
[self createGraph:100];
}
failure:^(NSURLSessionTask *operation, NSError *error)
{
NSLog(#"Error1: %#", [error debugDescription]);
NSLog(#"Error2: %#", [error localizedDescription]);
}];
}
#catch (NSException *exception)
{
NSLog(#"%#",exception);
}
Log (UnitPrice values I need individually extracted):
Dictionary output:
2016-07-03 22:52:21.330 T2PApp[2272:658440] (
{
OrderDetailID = 3;
ProductName = Oranges;
UnitPrice = "399.99";
date = "2016-06-09T21:45:06";
},
{
OrderDetailID = 7;
ProductName = Oranges;
UnitPrice = 1000;
date = "2016-06-13T22:15:47.107";
}
)
Extracted UnitPrice output (still not completely extracted):
2016-07-03 22:52:21.330 T2PApp[2272:658440] Price: (
399.99,
1000
)
I think what you need is digging out the data from the objects in array. It not about the JSON.
There is many way to do it, but not one simply way to dig it out.
For example, create a new array, and traverse the target array, put the property you need into the new array.
It is basically like that.
In your code, maybe the code below will work.
NSLog(#"%#",JSON);
NSMutableArray *priceArr = [NSMutableArray array];
NSArray *arr = nil;
if ([JSON isKindOfClass:[NSArray class]]) {
arr = (NSArray *)JSON;
for (NSDictionary *dic in arr) {
NSString *price = [NSString stringWithFormat:#"%#",[dic valueForKey:#"UnitPrice"]];
price= [price stringByReplacingOccurrencesOfString:#"\"" withString:#""];
[priceArr addObject:price];
}
}
priceArr is what you need.

Google Place Search API in IOS

I have implemented the google place search API in IOS and enabled the API in the developer console and used the below code but its shows error that "This IP, site or mobile application is not authorized to use this API key. Request received from IP address 122.173.223.114, with empty refer"
After regenerate the API key its shows API key is expired and after sometime its shows the same above errors. Please help someone.
-(void) queryGooglePlaces: (NSString *) googleType {
// Build the url string to send to Google. NOTE: The kGOOGLE_API_KEY is a constant that should contain your own API key that you obtain from Google. See this link for more info:
// https://developers.google.com/maps/documentation/places/#Authentication
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=%#&types=%#&sensor=true&key=%#", appDel.objLocationManager.location.coordinate.latitude, appDel.objLocationManager.location.coordinate.longitude, [NSString stringWithFormat:#"%i", appDel.currenDist],googleType, kGOOGLE_API_KEY];
//Formulate the string as a URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
-(void)fetchedData:(NSData *)responseData {
//parse out the json data
if (responseData==nil) {
}else{
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
NSArray* places = [json objectForKey:#"results"];
//Write out the data to the console.
NSLog(#"Google Data: %#", json);
}
}
I did it with use of AFNetworking class Try this one,
#define kGoogleAutoCompleteAPI #"https://maps.googleapis.com/maps/api/place/autocomplete/json?key=%#&input=%#"
-(void)getAutoCompletePlaces:(NSString *)searchKey
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// set request timeout
manager.requestSerializer.timeoutInterval = 5;
NSString *url = [[NSString stringWithFormat:kGoogleAutoCompleteAPI,GoogleDirectionAPI,searchKey] stringByReplacingOccurrencesOfString:#" " withString:#"+"];
NSLog(#"API : %#",url);
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSDictionary *JSON = responseObject;
predictions = [NSMutableArray array];
// success
AutomCompletePlaces *places = [AutomCompletePlaces modelObjectWithDictionary:JSON];
[arrSuggestionData removeAllObjects];
if (!arrSuggestionData) {
arrSuggestionData = [NSMutableArray array];
}
for (Predictions *pred in places.predictions)
{
[arrSuggestionData addObject:pred.predictionsDescription];
}
[self.Tbl_suggestion reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
}

Parsing JSON object and sub-elements

I just need to know proper method to parse the JSON string.
Here is my sample JSON response:
[
{
"my_response": [
{
"name": "XXX",
"Area": "XXX",
"Num": 123
}
]
},
{
"other_response": [
{
"message": "Hello",
"status": "Success",
"flag_value": "1"
}
]
}
]
I want to parse flag_value in a String
I tried this method
NSString *str1 = [json valueForKeyPath:#"other_response. flag_value"];
NSLog(#"str %#",str1);
And my output is some what like this
str (
"<null>",
(
1
)
)
But I want my output to be a string like this:
1
[{"my_response":[{"name":"XXX","Area":"XXX","Num":123}]},{"other_response":[{"message":"Hello","status":"Success","flag_value":"1"}]}]
actually your Json response Start in Array so follow this step
Step-1
NSArray *jsonDict = [NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil];
Step-2
in here you are get 2 Dictionaries
NSString *FlagStr;
for (NSMutableDictionary *temp in jsonDict)
{
NSArray *secondOption=[temp objectForKey:#"other_response"];
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[second objectForKey:#"flag_value"];
}
}
Choice no-2
I am not try this but May be it work for you , once check
Step-1
NSArray *jsonDict = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"];
Step-2
NSString *FlagStr;
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[temp objectForKey:#"flag_value"];
}
Choice no-3
you can directly fetch the string value I am not try this but May be it work for you , once check
NSString *flage = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"]objectAtIndex:0] objectForKey:#"flag_value"];
First of all, I think your JSON would be better formatted like the following:
{
"my_response": {
"name": "XXX",
"area": "XXX",
"num": "XXX"
},
"other_response": {
"message": "Hello",
"status": "success",
"flag_value": "1"
}
}
Then you can use the following code to access your data:
NSString *jsonString = #"{\"my_response\": {\"name\": \"XXX\",\"area\": \"XXX\",\"num\": \"XXX\"},\"other_response\": {\"message\": \"Hello\",\"status\": \"success\",\"flag_value\": \"1\"}}";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSLog(#"str: %#", [jsonDict valueForKeyPath:#"other_response.flag_value"]);
Format your Json array like this way.
{
"my_response": {"name": "XXX","area": "XXX","num": "XXX"
},
"other_response": {"message": "Hello","status": "success","flag_value": "1"
}
}
**Step : 2**
Use AFNetworking for HTTP Client
- (void)yourMethod{
NSString *urlString = [NSString stringWithFormat:#"%#", your_service_url];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
your_parameters_list,
nil];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:urlString
parameters:params];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#" Success %#", JSON);
NSDictionary *jsonDictionary1 = [JSON valueForKey:#"my_response"];
NSDictionary *jsonDictionary2 = [JSON valueForKey:#"other_response"];
NSString* name = [jsonDictionary1 valueForKey:#“name”];
NSString* area = [jsonDictionary1 valueForKey:#"name"];
NSString* num = [jsonDictionary1 valueForKey:#"num"];
} failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Fail %#", [error userInfo]);
NSLog(#“Error %#", [error localizedRecoverySuggestion]);
}];
[operation start];
}
As accepted above brother Anbu.Karthick answer.But I want to give answer for this
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:yourResponseData options: NSJSONReadingMutableContainers error: &err];
for (int i =0; i<[jsonArray count]; i++)
{
NSMutableDictionary *dict = [[jsonArray objectAtIndex:i] mutableCopy];
NSString *strFlag = [NSString stringWithFormat:#"%#",[[[dict objectForKey:#"other_response"] objectAtIndex:0] valueForKey:#"flag_value"]];
NSLog(#"The strFlag is-%#",strFlag);
}

How do I make my AFNetworking "responseObject" that I receive a NSDictionary I can parse?

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];
}
...

Resources