Im newly using AFNetworking to get JSON and parse it,I've imported it to my project and got the JSON but i don't know how is it possible to parse the JSON for display especially in Objective-c.
Here is the code in my viewDidLoad to Get JSON :
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://api.androidhive.info/json/movies.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
The Retrieved JSON for parsing:
{
genre = (
Action,
Drama,
"Sci-Fi"
);
image = "http://api.androidhive.info/json/movies/1.jpg";
rating = "8.300000000000001";
releaseYear = 2014;
title = "Dawn of the Planet of the Apes";
},
{
genre = (
Action,
"Sci-Fi",
Thriller
);
image = "http://api.androidhive.info/json/movies/4.jpg";
rating = "8.4";
releaseYear = 2014;
title = "X-Men: Days of Future Past";
},
{
genre = (
Action,
Adventure,
Fantasy
);
image = "http://api.androidhive.info/json/movies/7.jpg";
rating = "7.3";
releaseYear = 2014;
title = "The Amazing Spider-Man 2";
},
{
genre = (
Animation,
Comedy,
Family
);
image = "http://api.androidhive.info/json/movies/9.jpg";
rating = "8.300000000000001";
releaseYear = 2013;
title = Rush;
},
{
genre = (
Animation,
Adventure,
Family
);
image = "http://api.androidhive.info/json/movies/15.jpg";
rating = "8.199999999999999";
releaseYear = 2010;
title = "How to Train Your Dragon";
}
)
Update :
How is it possible to display it and store the retrieved data so its easier to show it in UITableView.
i tried to do like :
NSLog(#"JSON: %#", [responseObject objectForKey:#"image"]);
to get the whole images only but it crashes. i just need to get for example all the titles and store them in array and then display them UITableView.
you try this way to get data from NSDictionary
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://api.androidhive.info/json/movies.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
self.arrData=[[NSMutableArray alloc]initWithArray:responseObject];
[self.tableView reloadData];// reload table data
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
TableView Delegate Method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// your cell code here
// indexPath.row(use in tableView) means your number of index to get value
NSLog(#"JSON: %#", [[self.arrData objectAtIndex:indexPath.row] objectForKey:#"image"]);
NSLog(#"title: %#", [[self.arrData objectAtIndex:indexPath.row] objectForKey:#"title"]);
NSLog(#"rating: %#", [[self.arrData objectAtIndex:indexPath.row] objectForKey:#"rating"]);
NSLog(#"releaseYear: %#", [[self.arrData objectAtIndex:indexPath.row] objectForKey:#"releaseYear"]);
NSLog(#"genre: %#", [[self.arrData objectAtIndex:indexPath.row] objectForKey:#"genre"]);// return array get value particular using array index
}
AFNetworking returns already processed JSON in responseObject - and in your case it's an NSArray of NSDictionary objects inside it.
To access a single NSDictionary create an NSArray property (e.g. resultArray) and set it to responseObject, then you can access its objects by resultArray[1] (make sure to bounce check).
Then you can access the values of the dictionary by their keys (myDictionary[#"title] and so on).
Related
I could able to POST the parameters as follows, it works if I have only one item for each dictionary item. In the following params I have only one pName and one price.
NSMutableDictionary *params= [NSMutableDictionary dictionaryWithDictionary:
#{#"pName":pData.pName,
#"price":pData.price,
#"notes":pData.notes}];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"text/html",nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:URL_SIGNIN parameters:params progress: nil
success:^(NSURLSessionTask *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:
^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
However, I wonder how could I able to put items as a parameters if I have more than one items such as pNames = [Beef, Coffee, Rice ,Sprite] and prices = ["$10", $"3", "$5", #"1"].
Consider as following object at the end.
orders = {#"Beef" : #"$10",#"Coffee" : #"$3", #"Rice" : #"$5", #"Sprite" : #"$1"}
Assume that it is restaurant application where user selects multiple items to check out.
You want an array ($[]), not a dictionary (${}).
In your example:
prices = #[#"$10", #"$3", #"$5", #"$1"];
EDIT:
As parameters:
NSMutableDictionary *params= [NSMutableDictionary dictionaryWithDictionary:
#{#"prices": #[#"$10", #"$3", #"$5", #"$1"]}];
OR:
NSArray *prices = #[#"$10", #"$3", #"$5", #"$1"];
NSMutableDictionary *params= [NSMutableDictionary dictionaryWithDictionary:
#{#"prices": prices];
I'm trying to check if NSString 'testing' (47) exists inside of my NSMutableArray 'self.checkfriendData'. I'm using the code below, though after logging my if statement it appears as though it's never executed (even though the statement is true - see console data below, uid = 47, and thus hiding my object should fire?) Any idea as to why this isn't working? Help is much appreciated!
ViewController.m
NSMutableDictionary *viewParams3 = [NSMutableDictionary new];
[viewParams3 setValue:#"accepted_friends" forKey:#"view_name"];
[DIOSView viewGet:viewParams3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.checkfriendData = (NSMutableArray *)responseObject;
NSString *testing = #"47";
NSArray *friendorNo = self.checkfriendData;
if ([friendorNo containsObject:testing]) // YES
{
self.addFriend.hidden = YES;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Here's what's inside self.checkfriendData:
2017-05-18 19:36:07.266529-0700 This is the friend data check (
{
body = "My name is Britt";
friendphoto = "/sites/default/files/stored/x.jpg";
"node_title" = "Britt";
uid = 47;
}
)
It appears that your NSArray contains NSDictionarys and you are asking if the array contains an NSString. The answer will always be no as the array doesn't directly contain any NSStrings.
If you want to search for the uid of 47 you will have to iterate over the array and check the uid key of each NSDictionary for the value 47.
The code for this would look something like:
for (NSDictionary *dict in friendorNo) {
if ([dict[#"uid"] isEqualToString:testing]) {
self.addFriend.hidden = YES;
}
}
I've retrieved data to my iOS app from my Drupal database using the below code:
.h
#property (strong, nonatomic) NSMutableArray *userData;
.m
self.userData = [NSMutableArray new];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.userData = [responseObject mutableCopy];
NSLog(#"%#",self.userData);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
self.userData = [[NSMutableArray alloc] init];
self.userBio.text = self.userData[0][#"userbio"];
self.userData is populated, so I know my data has successfully been returned. Does anyone know how I would display the JSON returned field in a UIlabel? I'm just not sure how I would write this line of code (newb, sorry). My field name is userbio.
Here's how the data structure is returned (incase it's of any use):
UPDATE: NSLog(#"userData = %#", self.userData); returns this in the console:
2015-10-25 11:22:06.601 [7605:2738034]
userData = (
> {
> userbio = "No user bio available at this time.";
> "users_name" = "<a href=\"/user/20\" title=\"View user profile.\" class=\"username\" xml:lang=\"\" about=\"/user/20\"
> typeof=\"sioc:UserAccount\" property=\"foaf:name\"
> datatype=\"\">Brittany</a>";
> },
If it's an NSDictionary the code would look like this:
self.myLabelName.text = self.userData[#"userbio"];
If it's an NSArray of NSDictionaries it would look like:
self.myLabelName.text = [self.userData firstObject][#"userbio"];
That's assuming that the array contains only one dictionary, otherwise you would have to access each element: self.userData[0], self.userData[1], etc.
I managed to get the user likes using this code:
[FBRequestConnection startWithGraphPath:#"/me/likes"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
NSLog(#"User interests data: %#",result);
self.likesTextView.text = [NSString stringWithFormat:#"User interests data: %#",result];
}];
This is the log:
User interests data: {
data = (
{
category = Company;
"created_time" = "2015-04-09T11:31:13+0000";
id = 403422586500762;
name = "Sky3888 iOS & Android - Officially Agent";
},
{
category = "Games/toys";
"created_time" = "2015-04-09T11:30:57+0000";
id = 1575053229378162;
name = i12win;
},
{
category = "Shopping/retail";
"created_time" = "2015-04-07T04:44:09+0000";
id = 273182176129865;
name = Tinkerbelle;
}
);
However how do I get and display the "name" and "category" field in a UILabel?
You can do as below
NSDictionary *responseDict=(NSDictionary *)result;
NSArray *mainArray=[responseDict objectForKey:#"data"];
for (NSDictionary *dict in mainArray) {
nameLabel.text=[dict valueForKey:#"name"];
catLabel.text=[dict valueForKey:#"category"];
}
Hope it helps you..!
Make an NSArray of the result and then loop through the objects in it performing the function objectForKeyon category and name to extract the data you want.
There is a similar question answered here:
NSMutableArray losing all objects
You should be able to use the code from that and copy the results into your UILabel.
I used this answer to sort 2 objects by date, and it worked perfectly: Get one NSArray
I now need to sort 3 objects by date, and can't quite modify what I have to get that right.
All of the Articles from the API/RSS feeds will be sorted by date in 1 tableView.
Here's what I tried:
- (void)sortCombinedModel {
// All 3
[self.combinedModel sortUsingComparator:^NSComparisonResult(id a, id b, id c) {
NSDate *dateA, *dateB, *dateC;
dateA = ([a isKindOfClass:[FeedRSS self]])? ((FeedRSS *)a).pubDate : ((Data *)a).created_time : ((YaRSS *)a).pubDate;
dateB = ([b isKindOfClass:[FeedRSS self]])? ((FeedRSS *)b).pubDate : ((Data *)b).created_time : ((YaRSS *)b).pubDate;
dateC = ([c isKindOfClass:[FeedRSS self]])? ((FeedRSS *)c).pubDate : ((Data *)c).created_time : ((YaRSS *)c).pubDate;
return [dateB compare:dateA compare:dateC];
}];
}
Can you help me sort the 3 dates?
Additional info if needed:
I figured out how to modify this part - Have 3 API/RSS feeds coming in to one NSMutableArray:
- (void)loadMedia {
self.combinedModel = [NSMutableArray array];
// Here's the #1
[self loadOneWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
// Here's the trick. call API2 here. Doing so will serialize these two requests
[self loadTwoWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
// Here's the trick. call API3 here. Doing so will serialize these two requests
[self loadThreeWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
[self sortCombinedModel];
[self.tableView reloadData];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"No?: %#", error);
}];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"No?: %#", error);
}];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"No?: %#", error);
}];
}
Here's what sorting 2 dates looked like previously:
- (void)sortCombinedModel {
[self.combinedModel sortUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *dateA, *dateB;
dateA = ([a isKindOfClass:[Feed self]])? ((Feed *)a).published : ((Data *)a).created_time;
dateB = ([b isKindOfClass:[Feed self]])? ((Feed *)b).published : ((Data *)b).created_time;
return [dateA compare:dateB];
}];
}
The comparator must always take two values to compare, but it wants to check if those two values are one of three types. Add the following to the public interfaces defined in FeedRSS.h, Data.h and YaRSS.h:
- (NSDate *)sortDate;
In each of the implementations, add a method that returns the right date property to sort on for the class, so, e.g.
// FeedRSS.m
- (NSDate *)sortDate {
return self.pubDate;
}
Same idea for Data.m (return self.created_time), and same for YaRSS.h, return whatever date that object has that you want to sort on. Now your comparator is like this:
- (void)sortCombinedModel {
[self.combinedModel sortUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *dateA = nil, *dateB = nil;
if ([a isKindOfClass:[Feed self]]) { dateA = ((Feed *)a).sortDate; }
else if ([a isKindOfClass:[Data self]]) { dateA = ((Data *)a).sortDate; }
else if ([a isKindOfClass:[YaRSS self]]) { dateA = ((YaRSS *)a).sortDate; }
if ([b isKindOfClass:[Feed self]]) { dateB = ((Feed *)b).sortDate; }
else if ([b isKindOfClass:[Data self]]) { dateB = ((Data *)b).sortDate; }
else if ([b isKindOfClass:[YaRSS self]]) { dateB = ((YaRSS *)b).sortDate; }
return [dateA compare:dateB];
}];
}
This works if the array contains only the three kinds of objects you expect. If you always want to sort this way, an even tidier approach is to implement compare: in each of those classes, in each one checking if the param is one of the other two types.