How to display json data in UITableviewcell in iphone [duplicate] - iphone

This question already has an answer here:
How to display Json data in UITableviewCell
(1 answer)
Closed 9 years ago.
I am currently working in JSON. I am just using a JSP webserver. Using this server, I want to display ticket number, time and status, which is to be displayed in the table view. I dont know how to display the JSON DATA in UITableview.Please give me idea any body. I am new to the ios progrmming.Thanks in advance.
I am menctioned below is my Json data.
{"result":[{"request_id":587,"ticket_number":"P_1000587","email":"hars","user_id":6,"description":"","createdTime":"10/15/2013
06:15:06
PM","status":"initiated"},{"request_id":586,"ticket_number":"P_1000586","email":"h14s","user_id":6,"description":"fdyfyt","createdTime":"10/15/2013
06:12:56
PM","status":"initiated"},{"request_id":585,"ticket_number":"P_1000585","email":"har","user_id":6,"description":"","createdTime":"10/15/2013
06:12:29 PM","status":"initiated"},

To get NSDictonary out of JSON use:
NSError* error = nil;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
To create a UITableView read tutorials on Apple:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/CreateConfigureTableView/CreateConfigureTableView.html

Step 1 Declare Dictionary in .h file
NSDictionary* dictJson;
Step 2 Parse JSON Data and store it into Dictionary
NSError* error = nil;
dictJson = [[NSDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:YOURDATA options:kNilOptions error:&error]];
Step 3 User following TableView Methods to fill your data and display it
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
cell = [[UITableViewCell alloc] init];
// Display Ticket_number in Text Field of TableView Cell
[cell.textLabel setText:[[[dictJson objectForKey:#"result"] objectAtIndex:indexPath.row] valueForKey:#"ticket_number"]];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return Number of Objects in Result
return [[dictJson objectForKey:#"result"] count];
}

Related

I want to populate my tableview from my NSDictionary

- (void)receiveData:(NSData *)data {
self.office = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
self.files = [office objectForKey:#"files"];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.files.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] init];
NSDictionary *file = [self.files objectAtIndex:indexPath.row];
cell.textLabel.text = [file objectAtIndex:1]; //here i want to get data from the array
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
cell.textLabel.numberOfLines = 1;
return cell;
NSLog(#"files:\n%#", file);
}
I have a json response that i have stored in NSDictionary offices, and array in that json is stored in NSArray files,now i have given files array to another NSDictionary file and according to data that stored in that file i want that data in my table row, but i don't have any "key" in my files array only value in that array,
so my question is that how can i point that value in that my file dictionary, i have make comment where i want that please see that comment....
You're creating a dictionary:
NSDictionary *file = [self.files objectAtIndex:indexPath.row];
NSDictionary is indexed with keys, so you'll have to obtain the string with objectForKey:
cell.textLabel.text = [file objectForKey:#"fileName"];
I think you must either misunderstand how an NSDictionary works or else the objects that you're accessing in self.files are not actually NSDictionaries. If they are in fact NSDictionary objects they need to be accessed like runmad says with
[file objectForKey:#"keyName"]
If there are no keys then you are dealing with a different type of object and we would need to know more specifics to be able to help you. As you posted the question runmad has given you the correct answer.
The JSON parser NSJSONSerialization may not be creating the NSDictionary/NSArray structures you think you have. You'll have to check your JSON, e.g. with jsonlint.com, then use NSLog to have a look at what is placed in your dictionaries/arrays. Also try some of the NSJSONReadingOptions options.

Getting an ID string when selecting a cell

I am making an iPhone app with different views, one of these being an UITableView, and i want to pass an ID string to another view, depending on the selected row.I have multiple row selection.I don't want to pass the data of the cell, but an ID to associate with it.
F.E: Cell name: "United States", to return a NSString: "09r454-0567-34".I don't have an idea of how to associate these strings to a cell.Thanks in advance.
Maybe you need to declare an array of dictionaries, then you catch didSelectRowAtIndexPath:, and retreive the information in that array
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dict = [myIDArray objectAtIndex:indexPath.row];
NSLog(#"ID %#", [dict objectForKey:#"ID"]);
NSLog(#"Name %#", [dict objectForKey:#"Name"]);
}
NSArray* myIDArray; //must be declared in .h
Hope this help...

Instance variable not returning a value in iOS application

This problem might be related to Instance variable not retaining value in iOS application.
My application has a table view that's supposed to be populated with data from a plist. The plist is question is determined based on a defaults setting.
After setting the contents of the instance variable, a count on it shows that it contains multiple records. However, if I then later try to count this instance variable when drawing the table view cells, it shows no records.
--
I declared a "providerData" NSDictionary instance variable in my class header:
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController {
NSDictionary *providerData;
}
#property (nonatomic, retain) NSDictionary *providerData;
- (void)loadProviderDataSource:(NSString *)providerName;
#end
In my implementation I use viewDidLoad to read a dictionary from a plist file, check the value of "provider_preference", and then call [self loadProviderDataSource:providerPreference]:
- (void)viewDidLoad
{
[super viewDidLoad];
// Retrieve the user's provider preference from defaults:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Set a default value for provider preference if the user didn't explicitly set one:
NSString *providerPreference = [[NSString alloc] initWithString:#"foo"];
if ([defaults stringForKey:#"provider_preference"]) {
providerPreference = [defaults stringForKey:#"provider_preference"];
}
// Load provider data from the relevant plist:
[self loadProviderDataSource:providerPreference];
}
This all works fine (using NSLog I can see that the plist file is read correctly and that a correct providerPreference value is passed to loadProviderDataSource.
The implementation for loadProviderDataSource is as follows:
- (void)loadProviderDataSource:(NSString *)providerName
{
// Set the filename and path for the data source:
NSString *dataSourceFileName = [[NSString alloc] initWithFormat:#"data-%#.plist",providerName];
NSString *dataSourcePath = [[NSBundle mainBundle] bundlePath];
dataSourcePath = [dataSourcePath stringByAppendingPathComponent:dataSourceFileName];
// Read the provider data:
self.providerData = [[NSDictionary alloc] initWithContentsOfFile:dataSourcePath];
NSLog(#"provider data entry count 1: %d", [self.providerData count]);
}
At this point the NSLog shows me that there are 2 entries in providerData.
However, when I have to set the cells for my table view, the NSLog in the following code shows me that providerData has 0 entries:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(#"provider data entry count 2: %d", [self.providerData count]);
return cell;
}
In loadProviderDataSource I've tried using:
self.providerData = [[NSDictionary alloc] initWithContentsOfFile:dataSourcePath];
and:
[self setProviderData:[[NSDictionary alloc] initWithContentsOfFile:dataSourcePath]];
... neither work and I still end up with this in my log:
provider data entry count 1: 2
provider data entry count 2: 0
provider data entry count 2: 0
Any ideas?
Based on NSLog(#"%#", self); in both the method which shows up as follows
loadProviderDataSource
self: <ViewController: 0x83739b0>
tableView:cellForRowAtIndexPath
self: <ViewController: 0x8373170>
It looks like you are creating a second instance of ViewController somehow.
I understand one of them is created using XIB. Verify whether you are creating another one programmatically.

Objective-C/iOS : Message sent to deallocated instance

This is my first post on stackoverflow.com so please be kind (rewind) ;)
I have a navigation based application whose purpose is to display blog posts (title) in a Table View (with JSON).
The problem I ran into occurred when a cell got out of the screen and then back in.
I was getting a EXC_BAD_ACCESS (because I sent a message to a deallocated instance), so I struggled to understand where it came from and I finally found a solution. But the fact is I don't exactly understand how the problem occurs. That's why I need someone to enlighten me, I think this is fundamental understanding !
When the connection to the JSON web service has finished loading, I parse the JSON code to obtain a list of blog posts (recentPosts), then I create a BlogArticle object for each post (blogArticle), store it in a MutableArray iVar (allEntries) and insert a row in the Table View :
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSError *error;
SBJsonParser *json = [[SBJsonParser new] autorelease];
NSDictionary *recentPostsData = [json objectWithString:responseString error:&error];
[responseString release];
NSArray *recentPosts = [recentPostsData objectForKey:#"posts"];
int i = 0;
for (NSDictionary *post in recentPosts) {
BlogArticle *blogArticle = [[BlogArticle alloc] initWithDictionary:post];
[allEntries insertObject:blogArticle atIndex:i];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationRight];
i++;
}
}
Here's the initialisation of the BlogArticle object which turned to be the origin of the problem :
- (id)initWithDictionary:(NSDictionary *)article
{
if (self = [super init])
{
// title = [[[article valueForKey:#"title"] gtm_stringByUnescapingFromHTML] copy];
// title = [[NSString alloc] initWithString:[[article valueForKey:#"title"] gtm_stringByUnescapingFromHTML]];
title = [[article valueForKey:#"title"] gtm_stringByUnescapingFromHTML];
}
return self;
}
So every Objective-C programmer who isn't as noobish as me is able to tell that title is never allocated before being assigned. If I uncomment one of the two lines above it will work. The program crashes exactly when I try to initialize a cell with that title variable, here :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(#"indexPath.row = %i", indexPath.row);
// Configure the cell.
BlogArticle *article = [allEntries objectAtIndex:indexPath.row];
cell.textLabel.text = article.title;
return cell;
}
Now, what I need to understand is why it does compile/work without allocating the iVar and where exactly it causes trouble (or where exactly the content of title is released causing the program to crash).
Any good resource (noob friendly) about memory management in iOS environment would be much appreciated.
Thanks in advance :)
This line
title = [[article valueForKey:#"title"] gtm_stringByUnescapingFromHTML];
is allocating an autoreleased string. Essentially, think of it that an autoreleased string will get released at the end of the method (though it can last longer, it's useful to think of it that way).
You know the string is autoreleased because the name of the method gtm_stringByUnescapingFromHTML does not start with alloc, new, copy or mutableCopy.
You can add retain to this to stop it getting autoreleased:
title = [[[article valueForKey:#"title"] gtm_stringByUnescapingFromHTML] retain];
Now you own the string, and it will not get released until you say so.
The best summary I know of is Apple's own documentation here.
Well, the problem is, that you have to initialize your object, if you want to manage the memory of it on your own. Why should you manage now the memory of title?
Quite simple:
Every object reference, that is stored in an Array, Set, Dictionary etc. is managed by the Array, Dictionary and Set.
If you now just use this reference (by writing: "title = ...") in your cell, you will add the reference also to the cell. And now the cell is also responsible for the object-reference. So if the tableView wants to release your cells, which will happen from time to time to save memory, the cell will release your title-object. And this would cause the NSDitionary to be quite sad, since the NSDictionary wants to take care about the objects stored within itself.
So you could write the following in the tableView-method:
cell.textLabel.text = [article.title retain];
Or the commented lines of your own method.
That means, you will "raise" the storage-level of your object up and if it gets released, the storage level itself will be decreased by one.
If the storage-level will reach zero, it will be completely released (that should happen, if your tablecell is released AND your NSDIctionary)
I hope i could help you a bit :)

How do I display data in a UITableView cell from an NSDictionary?

Hi i received 2000 of datas from udp and display the values in tableview .What is the easiest method to do this ?
Now i am using Two nsthreads and one thread for receive data via udp and stores it in NSMutableDictionary.Another thread update the tableview using these Dictionary values. But it crashes my app.
Here is some code i used
I stored Received values like this
NSMutableDictionary *dictItem
CustomItem *item = [[CustomItem alloc]init];
item.SNo =[NSString stringWithFormat:#"%d",SNo];
item.Time=CurrentTime;
[dictItem setObject:item forKey:[NSString stringWithFormat:#"%d",SNo]];
[item release];
Delegate method i used and i used CustomTableCells to display data as column vice.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dictItem count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"CustomTableCell";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[[CustomTableCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
NSArray *keys = [dictItem allKeys];
CustomItem *item = [dictItem objectForKey:[keys objectAtIndex:indexPath.row]];
cell.SNo.text = item.SNo;
cell.Time.text = item.Time;
return cell;
}
The errror is
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection was mutated while being enumerated.'
2010-07-23 02:33:07.891 Centrak[2034:207] Stack: (
42162256,
43320108,
42161198,
43372629,
41719877,
41719345,
9948,
3276988,
3237662,
3320232,
3288478,
71153942,
71153189,
71096786,
71096114,
71296742,
41650770,
41440069,
41437352,
51148957,
51149154,
2925426
)
terminate called after throwing an instance of 'NSException'
Can anyone help me ?
Thanks in advance.......
You probably have to use locking because when you access your dictionary from table view, it perhaps being mutated with other thread.
Try to look at NSLock docs. Before mutating your dictionary do [myLock lock]; and after mutating do [myLock unlock];. Similar in other thread: before enumerating dictionary do [myLock lock]; and after getting all values do [myLock unlock];.
myLock is a NSLock object and must be shared between your threads.
Mutable collections are not thread-safe by nature, so if you use them with multiple threads, you have to create an immutable copy first. For example, if you want to iterate through all the keys in your NSMutableDictionary, you would do this (assuming your NSMutableDictionary is called mutableDictionary):
NSDictionary *dictionary = [NSDictionary dictionaryWithDictionary:mutableDictionary];
for(id key in dictionary) {
// Do anything you want to be thread-safe here.
}
If you don't want to copy the dictionary, I suppose you could use locks or simply the #synchronized directive as follow:
#synchronized(mutableDictionary) {
// Do anything you want to be thread-safe here.
}
For more information, please have a look at the Apple documentation regarding multithreading and thread-safe objects: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html