Iphone: Populating UITableView or CustomCells from NSMutableDictionary - iphone

I need your advice in solving this issue:
I am parsing a XML File and puting the results in NSMutableDictionarys which I put in NSMutableArray:
The NSMutableArray with the Dictionarys looks like this:
Res: (
{
adresse = "Wielandg 36";
email = "office#tierarzt-riegelnegg.at";
latitude = "47.063065712289";
longitude = "15.439759954196";
ordiname = "Kleintierpraxis Jakomini Dipl Tzt Riegelnegg Gerfried";
ort = Graz;
plz = 8010;
tel = "+43316830438";
tierarztid = 3;
web = "http://www.tierarzt-riegelnegg.at";
},
{
adresse = "Rechbauerstr 3";
email = "glantschnig#kleintierambulatorium.at";
fax = "+43316321156";
latitude = "47.070320493663";
longitude = "15.448505434137";
ordiname = "KLEINTIERAMBULATORIUM - Dr. Simon Glantschnig";
ort = Graz;
plz = 8010;
tel = "+43316321156";
tierarztid = 2;
web = "http://www.kleintierambulatorium.at";
},
{
adresse = "Humboldtstr 7";
latitude = "47.079379100630";
longitude = "15.440064023548";
ordiname = "Bernhart Barbara Dr";
ort = Graz;
plz = 8010;
tel = "+43316684912";
tierarztid = 4;
}
Well this part works really fine! Now I put "ordiname" inside a UITableView, and when the User clicks the name, I am opening a "DetailView" where I want to show the results of the dictionary inside an UITableView or CustomCells - NSLog for this works fine - I can see the whole selected dictionary in the DetailView. Presenting in the TableView or CustomCells has to be done dynamically, as not all of the possible entries have to be filled (for example: Fax is not mandatory).
How can I achieve this? The order of the NSMutableDictionary is always the same...
Thanks for any help and advice!
BR,
Stefan

All you need is to have the DetailView adopt the UITableViewDataSource protocol and add the following methods,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myDictionary count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *name = [[myDictionary allKeys] objectAtIndex: indexPath.row];
NSString *value = [myDictionary objectForKey:name];
UITableViewCell *cell = [table dequeReusableCellWithItentifier:#"MyCell"];
if(!cell) {
//create cell
}
//set the name and value
cell.textLabel.text = [NSString stringWithFormat:#"%#:%#", name, value];
return cell;
}

Related

Filling UITableview with NSMutableArray

Trying to fill my UItableview with my Array. I would like to match a object in my array to the correct cell.
My array is as follows.
(
(
{
cost = 160;
height = 1;
room_number = 1;
square_size = 1;
title = "TIMBER BLINDS";
width = 1;
}
),
(
{
cost = 170;
height = 1;
room_number = 2;
square_size = 1;
title = "ROMAN BLINDS";
width = 1;
}
)
My question is how do i match the correct title to the cell based on the room_number in my array?
Thanks
It seems like you are having array of array which contains dictionary so firstly fetch the object from an array by indexPath.row. The fetched object is also an array. Fetch dictionary object from it by objectAtIndex. Now that you have accessed dictionary so you can access your key value.
NSMutableArray *fetchedArray= [yourArray objectAtIndex:indexPath.row];
NSDictionary *fetchedDictionary = [fetchedArray objectAtIndex:0];
NSNumber *roomNumber= [fetchedDictionary valueForKey:#"room_number"];
if([roomNumber intValue] == indexPath.row) {
[cell setTextLabel:[fetchedDictionary valueForKey:#"title"]];
}
Assuming your array is self.tableContent
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *object = self.tableContent[index.section][index.row];
..... some cell code
cell.title = object[#"title"];
}
It is dictionary of array of array
you can get value of "room_number" by
NSString *room_number = [[[myarray1 objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] objectForKey:#"room_number"]
() -- this represents array
{} -- this represents dictionary
So you can see you have an array of arrays and each array contains a single object and i.e a dictionary.
In terms of Objective C, it is like this:
NSDictionary *dict1 = //first dictionary
NSDictionary *dict2 = //second dictionary
NSArray *mainArray = [NSArray arrayWithObjects: [NSArray arrayWithObject:dict1],[NSArray arrayWithObject:dict2], nil];
To retrieve value inside key title from dictionary and display that in TableView:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// other code to set up cell
NSDictionary *array =[[mainArray objectAtIndex:indexPath.row] objectAtIndex:0];
cell.textLabel.text = [array objectForKey:#"title"];
return cell;
}

-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x8943940 while parsing JSON Page to UITableView

I have been through many links and fortunately I got many similar links but nothing worked Out.
my array is appearing like this in Output, using NSLog()..
products = (
{
cid = 1;
name = "hello world";
},
{
cid = 2;
name = "It is an array";
},
{
cid = 3;
name = "error error";
},
{
cid = 4;
name = "OMG! still same";
},
{
cid = 5;
name = "any help";
...
...
},
{
cid = 130;
name = "How is the work going on.";
},
{
cid = 131;
name = "Had a nice lunch";
}
);
success = 1
Code to parse JSON, where "news" is an Array var..
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
news = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"Feeds...%#",news);
[myTableView reloadData];
}
Code to display table row, here in "news" value is being displayed by NSLog(); Error comes for NSDictionary.
-(UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"=====%#====",news);
NSDictionary *myDict = [news objectAtIndex:indexPath.row];
NSArray *myArray = [myDict objectForKey:#"name"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
for (NSString *str in myArray) {
cell.textLabel.text = str;
}
return cell;
}
I am not able to find what i'm missing here.., Please help me out.
Thank you in advance.
Your JSON structure is something like this:
Dictionary-->Array-->Object (Dictionary).
So you need to do:
Extract the Array from the dictionary using the key product
Extract an object(Dictionary) from the array using the index
Get the name from the dictionary object using the key name
Instead of this:
NSDictionary *myDict = [news objectAtIndex:indexPath.row];
NSArray *myArray = [myDict objectForKey:#"name"];
Use:
NSArray *myArr = [news objectForKey:#"products"];
cell.textLabel.text = [[myArr objectAtIndex:0] objectForKey:#"name"];
Edit
Also change your numberOfRowsInSection like:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[news objectForKey:#"products"] count];
}
news is a NSDictionary, and a dictionary does not have a method objectAtIndex:
You have to use instead [news objectForKey:...];
[news objectAtIndex:indexPath.row];
NSMutabledictionary is indexpath.row so add first news in array and that array name add in
your code and you get nothing an
Put NSDictionary in Array then use it in Table method
NSMutableArray *result=[[NSMutableArray alloc] init];
result = [googleResponse valueForKey: #"products"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *dt = [result objectAtIndex:indexPath.row];
}
It will Help you !!!!!

UITableView not reversing

I'm working on information retrieval where in the latest information in on top of UITableView. The code goes like this.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LoanModel* loan = _feed.products[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:#"Cell"];
}
NSString *myString = [NSString stringWithFormat:#"%#",[loan name]];
NSArray *myWords = [myString componentsSeparatedByString:#","];
NSMutableArray *reversed = [NSMutableArray arrayWithCapacity:[myWords count]];
NSEnumerator *enumerator = [myWords reverseObjectEnumerator];
for (id element in enumerator) {
[reversed addObject:element];
}
NSMutableString *reverseString = [reversed componentsJoinedByString:#","];
cell.textLabel.text = reverseString;
return cell;
}
I'm getting the JSON object which contain two fields cid and name respectively. I'm showing only the name is tableview. But I want to show it in reverse i,e last update should show at first. But above code showing the content in reverse. IF "hello" is the content, then it shows "olleh". Please suggest me how to get the UITableView in reverse list. I'm a newbie to iOS.
If you want to have the reversed order of cells / objects they represent, you have to change
LoanModel* loan = _feed.products[indexPath.row];
to
LoanModel* loan = _feed.products[_feed.products.count - 1 - indexPath.row];
assuming that _feed.products is an NSArray.
The array you are using to display the the data in tableView, you'll need to reverse that and then display the data in tableView
NSArray* reversed = [[myArray reverseObjectEnumerator] allObjects];
you can use this to make your array objects order in reverse.
Try This:
NSArray* reversedArray = [[myWords reverseObjectEnumerator] allObjects];

Parsing json string in iOS Objective C

I am trying to build my first iOS app that parses json from a web service.
In my .h file i create an array
NSArray *items;
In my .m file i call the website and store the data into the array. This all goes fine except eventually I am trying to display the data in a uitableview.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ItemsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"%#",items);
NSDictionary *item = [items objectAtIndex:indexPath.row];
NSString *title = [item objectForKey:#"title"];
cell.title.text = title;
return cell;
}
The nslog of items produces:
{
category = code;
keyword = "";
limit = 20;
lowPrice = "";
page = 0;
products = (
{
description = "...";
mobileFriendly = 1;
popularity = 2021;
productId = code;
title = "title";
}, and so on...
)
I am getting an error trying to do NSDictionary *item = [items objectAtIndex:indexPath.row]; It says doing objectAtIndex:indexPath.row is invalid.
What am I doing wrong?
Thanks for your help!
The value stored in items is an instance of NSDictionary, but you're sending it an NSArray message. Also, the code you posted is referring to gift and ignoring the item anyway.
The array you're looking for is actually stored under the key products inside the items dictionary, so you need to do something like this:
NSArray *products = [items objectForKey:#"products"];
NSDictionary *product = [products objectAtIndex:indexPath.row];
// Then use the product, instead of using 'gift' (whatever that is).
NSString *title = [product objectForKey:#"title"];
items is not a NSArray - it is a NSDictionary. so it has no objectAtIndexPath: method.

iPhone dev, NSDictionary how to retain full Dict?

I have a problem with retaining data in a nested NSDictionary. Or is it something with NSMutableDictionary that will make this work? Take a look, I will try to explain as good as possible.
My .h file looks like:
#interface MyViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
{
NSDictionary *fullData;
IBOutlet UITableView *tableView;
}
#property (nonatomic, retain) NSDictionary *fullData;
#property (nonatomic, retain) UITableView *tableView;
#end
I set up my inits in viewDidLoad
- (void)viewDidLoad {
...
fullData = [NSDictionary dictionaryWithContentsOfURL:url];
[fullData retain];
[super viewDidLoad];
}
And this works fine when I try to insert it into UITableViewCells and whatever I need to do, even if I do an NSLog that prints fullData here, all of the data will be displayed.
like so:
2010-11-24 14:49:53.334 MyApp[25543:40b] {
items = (
{
id = 5;
localId = 1;
name = "A name1";
},
{
id = 8;
localId = 3;
name = "A name2";
},
{
id = 9;
localId = 4;
name = "A name3";
},
{
id = 10;
localId = 5;
name = "A name4";
},
{
id = 11;
localId = 6;
name = "A name5";
}
);
results = 5;
}
Although this works perfectly I want to keep the fullData in my other events, for example didSelectRowAtIndexPath. First of all, I have to retain the , and also if I do, only the first level data will be retained. the dict items will just point to some memory which doesn't exist.
So I try:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Data: %#", fullData);
}
And this sometimes returns this:
2010-11-24 14:44:28.288 MyApp[25493:40b] Data: {
items = (
"<_NSIndexPathUniqueTreeNode: 0x9d2a820>",
"<CALayer: 0x9d27980>",
"<CALayer: 0x9d2bc30>",
"<CALayer: 0x9d29830>",
"<CALayer: 0x9d299e0>"
);
results = 5;
}
It seems like some values are retained, however the data inside items are not possible to access. Is it better for me to store the data to a local file and then access it again at this point, or should be it possible to retain the full dictionary?
I tried adding [[fullData objectForKey:#"items"] retain];
I am pretty new to this, so I need help to make my code follow best practices as well. I have tried many solutions and watched several movies from apple and other places too. I just can't solve it. It might be simple but I dont know where to look.
Thank you.
I am sorry, I did solve the issue myself
I didn't include this function:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Retain count: %i", [fullData retainCount]);
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"cell"];
// create a cell
if( cell == nil )
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
}
// fill it with content
NSArray *current = [[fullData objectForKey:#"items"] objectAtIndex:indexPath.row];
NSString *rowLabel = [NSString stringWithFormat:#"%#, %#",[current valueForKey:#"localId"], [current valueForKey:#"name"]];
cell.textLabel.text = rowLabel;
[current release];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// return it
return cell;
}
And the issue is that I release the current variable each row in the table. This should be a result of that the instance in the variable current is not a copy, instead it is the real reference.
Thanks anyways.
fullData = [NSDictionary dictionaryWithContentsOfURL:url];
is auto-released. you shouldn't retain it. Use this:
self.fullData = [[NSDictionary alloc] initWithContentsOfURL:url];
And I don't think you need to retain it for your purposes now. Only if you need to access it after MyViewController is released.
Are you releasing the UITableView? It may go through and release it's cells which are in your NSDictionary. W/o more code, I can't tell.
You'll need to post some more code in order to track down the solution. The NSDictionary retains its contents, so unless you are over-releasing the objects somewhere else, retaining the NSDictionary will be sufficient.
I am sorry, I did solve the issue myself
I didn't include this function:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Retain count: %i", [fullData retainCount]);
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"cell"];
// create a cell
if( cell == nil )
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
}
// fill it with content
NSArray *current = [[fullData objectForKey:#"items"] objectAtIndex:indexPath.row];
NSString *rowLabel = [NSString stringWithFormat:#"%#, %#",[current valueForKey:#"localId"], [current valueForKey:#"name"]];
cell.textLabel.text = rowLabel;
[current release];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// return it
return cell;
}
And the issue is that I release the current variable each row in the table. This should be a result of that the instance in the variable current is not a copy, instead it is the real reference.
Thanks anyways.