I have a plist with dictionary.
In the dictionary i have a string called "cellPic" that have url address of an image.
I'm trying to populate my table view with images that i put on my dropbox account & read them through the plist string.
("arrayFromPlist" is my array)
The problem is that when i run it, i'm getting an error in the console:
[__NSCFDictionary objectAtIndex:]: unrecognized selector
This is my code:
-(void) readPlistFromDocs
{
// Path to the plist (in the Docs)
NSString *rootPath =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:#"Data.plist"];
NSLog(#"plistPath = %#",plistPath);
// Build the array from the plist
NSMutableArray *arrayFromDocs = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
if (arrayFromDocs)
{
NSLog(#"\n content of plist file from the documents \n");
NSLog(#"Array from Docs count = : %d", [arrayFromDocs count]);
}
arrayFromPlist = [[NSArray alloc] initWithArray:arrayFromDocs];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Returns the number of rows in a given section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayFromPlist count];
NSLog(#"Array SIZE = %d",[arrayFromPlist count]);
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSURL *url = [[NSURL alloc] initWithString:[[arrayFromPlist objectAtIndex:indexPath.row] objectForKey:#"cellPic"]];
NSData *urlData = [[NSData alloc] initWithContentsOfURL:url];
[[cell imageView] setImage:[UIImage imageWithData:urlData]];
return cell;
}
My other question is - how can i load the images asynchronous when i read the url from the plist string?
I tried to find an example for that but i found only asynchronous without uisng plist.
Thanks.
Change Following line
NSDictionary *arrayFromDocs = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
Best Tutorial for load the images asynchronous
Hope, this will help you..
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Get Data from a PList into UITableView?
I have a plist with Dictionary and numbers of strings per dictionary.show into the url below.and this list of items is in thousands in the plist.
Now want to display these list into the tableview
.
now how can i display this plist into the UITableView
what I am trying is:
- (id)readPlist:(NSString *)fileName
{
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:#"A" ofType:#"plist"];
dic =[NSDictionary dictionaryWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:dic mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
[error release];
}
return plist;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
dict =[self readPlist:#"A"];
return dict.allKeys.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
dict = [self readPlist:#"A"];
key = [dict.allKeys objectAtIndex:section];
return [[dict valueForKey:key] count];
}
- (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];
}
cell.textLabel.text = [[dict objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
UPDATE 2: You need to set the delegate and datasource for your tableView in your xib or ViewController.
In your ViewController.h file
#interface ViewController:UIViewController <UITableViewDelegate, UITableDataSource>
Try this code which I have written for you.
- (void)viewDidLoad {
tableView.delegate = self;
tableView.dataSource = self;
NSString *path = [[NSBundle mainBundle] pathForResource:#"Filename" ofType:#"plist"];
NSArray *contentArray = [NSArray arrayWithContentsOfFile:path];
// Having outlet for tableArray variable.
tableArray = [[NSMutableArray alloc]initWithArray:contentArray copyItems:YES];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// In your case dictionary contains strings with keys and values. The below line returns dictionary only. not array..
NSDictionary *dictionary = [tableArray objectAtIndex:section];
return dictionary.allKeys.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
NSDictionary *dictionary = [tableArray objectAtIndex:indexPath.section];
NSArray *keysArray = dictionary.allKeys;
// This below line display the key in textLabel
cell.textLabel.text = [keysArray objectAtIndex:indexPath.row];
// Below line will display the value of a key in detailTextLabel.
cell.detailTextLabel.text = [dictionary valueForKey:[keysArray objectAtIndex:indexPath.row]];
return cell;
}
UPDATE 2: After I have seen your plist in my MAC, I have found out that we are working with array of dictionaries in your A.plist.
So I found there is a bug in our code itself. Not in the plist file and you can use your 8000 data plist too.. Its working too. I have checked out totally. Now you can get the above Code and start work with.
store Plist data in array
- (id)readPlist:(NSString *)fileName
{
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:#"A" ofType:#"plist"];
// declare your array in .h file
array = [NSArray arrayWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:dic mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
[error release];
}
return plist;
}
and then write it in table
- (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];
}
cell.textLabel.text = [array objectAtIndex:indexPath.row] valueForKey:#"keyname"];;
return cell;
}
Hi I have this code here
- (void)viewDidLoad
{
[super viewDidLoad];
jsonURL = [NSURL URLWithString:#"http://oo.mu/json.php"];
jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL usedEncoding:nil error:nil];
self.jsonArray = [jsonData JSONValue];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *jsonObject = [parser objectWithString:jsonData error:NULL];
NSArray *list = [jsonObject objectForKey:#"Dewan's Party"];
for (NSDictionary *lesson in list)
{
// 3 ...that contains a string for the key "stunde"
NSString *content = [lesson objectForKey:#"Street"];
NSLog(#"%#", content);
}
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [jsonArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
return cell;
}
I'm using this JSon.php file.
{"Steffan's Party":{"Street":"774 Hoodwinked Avenue","City":"Sacramento","State":"California"},"Dewan's Party":{"Street":"2134 Statewide Lane","City":"New York","State":"New York"},"Austin's Party":{"Street":"9090 Gravink Court","City":"Woodland","State":"California"}}
This is a link to the website http://oo.mu/json.php.
What I'm trying to do here is parse each array in it's own UITableView cell. Example below, how can I do this?
Table Cell 1:
Steffan's Party
774 Hoodwinked Ave
Sacramento, California
Table Cell 2:
Dewan's Party
2134 Statewide Lane
New York, New York
How can I do this?
To get all keys and values from your current json do the following
in your viewDidLoad
NSString *yourJson = #"{\"Steffan's Party\":{\"Street\":\"774 Hoodwinked Avenue\",\"City\":\"Sacramento\",\"State\":\"California\"},\"Dewan's Party\":{\"Street\":\"2134 Statewide Lane\",\"City\":\"New York\",\"State\":\"New York\"},\"Austin's Party\":{\"Street\":\"9090 Gravink Court\",\"City\":\"Woodland\",\"State\":\"California\"}}";
SBJSON *json = [[SBJSON alloc] init];
NSDictionary *dic = [json objectWithString:yourJson error:NULL];
//NSMutableArray * keys; is defined in your interface .h file
//NSMutableArray * values; is defined in your interface .h file
keys = [[NSMutableArray alloc] init];
values = [[NSMutableArray alloc] init];
for(NSString *key in dic.keyEnumerator)
{
[keys addObject:key];
[values addObject:[dic objectForKey:key]];
}
now in your cellForRowAtIndexPath would look like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//Steffan's Party 774 Hoodwinked Ave Sacramento, California
NSString *partyName = [keys objectAtIndex:indexPath.row];
NSDictionary *dicValues = [values objectAtIndex:indexPath.row];
NSString *Street = [dicValues objectForKey:"Street"];
NSString *City = [dicValues objectForKey:"City"];
NSString *State = [dicValues objectForKey:"State"];
//Steffan's Party 774 Hoodwinked Ave Sacramento, California
NSString *fullString = [NSString stringWithFormat:#"%# %# %# %#", partyName, Street, City, State];
return cell;
}
Why are you using SBJsonParser? It's easier using only -JSONValue! Look:
NSDictionary *jsonDict = [jsonData JSONValue];
// you can declare it as ivar
Then, in -tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// that's how you can get key by index
NSString *key = [[jsonDict allKeys] objectAtIndex:indexPath.row];
NSDictionary *party = [jsonDict objectForKey:key];
NSString *street = [party valueForKey:#"Street"];
NSString *city = [party valueForKey:#"City"];
NSString *state = [party valueForKey:#"State"];
cell.textLabel.text = [NSString stringWithFormat:#"%# %# %#, %#", key, street, city, state];
return cell;
}
hi i am new to iphone development
i am using a webservice to connect with where i am getting json response string and i am parsing json responsetring using JSONvalue and i am displaying the parsed json on the label using button...
when i click the button the parsed json it will display on label field..
my question is can v have a textfield,button and webview or tableview in the UI..
when i enter the particular method in the textfield as json file is huge and press button shd display contents of particular method on the webview or tableview..
is this possible? if so then how to implement?
thank u
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:dataWebService encoding:NSUTF8StringEncoding];
self.dataWebService = nil;
NSArray* latestLoans = [(NSDictionary*) [responseString JSONValue] objectForKey:#"loans"];
[responseString release];
NSDictionary* loan = [latestLoans objectAtIndex:0];
//fetch the data
NSNumber* fundedAmount = [loan objectForKey:#"funded_amount"];
NSNumber* loanAmount = [loan objectForKey:#"loan_amount"];
float outstandingAmount = [loanAmount floatValue] - [fundedAmount floatValue];
NSString* name = [loan objectForKey:#"name"];
NSString* country = [(NSDictionary*)[loan objectForKey:#"location"] objectForKey:#"country"];
//set the text to the label
label.numberOfLines = 0;
label.text = [NSString stringWithFormat:#"Latest loan: %# \n \n country: %# \n \n µamount $%.2f", name,country,outstandingAmount];
If you want the loans in a table, you should read up on UITableView and Cell Styles
you'll add your table, then indicate the number of sections, rows in each section, the content for each cell (row), and what to do if one of the rows is touched:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//after turning latestLoans into a property
return self.latestLoans.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text=[[self.latestLoans objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.detailTextLabel.text=[[self.latestLoans objectAtIndex:indexPath.row] objectForKey:#"loan_amount"];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//do something with the row that was selected, like load a table of detailed information
}
I have a NSURL request that brings back an array of "name" and "phone", "etc"... The "name" Key shows up fine on the master table, but I'm having trouble figuring out how to get the rest of the array to show up on the detail table when I select the row. (I have the DetailerTableViewController working to accept the view). Any help would be appreciated.
Thanks,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [rowsArray count];
NSLog(#"row count: %#",[rowsArray count]);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict = [rowsArray objectAtIndex: indexPath.row];
cell.textLabel.text = [dict objectForKey:#"name"];
cell.detailTextLabel.text = [dict objectForKey:#"loginName"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.0/255.0 green:207.0/255.0 blue:255.0/255.0 alpha:1.0];
self.title = NSLocalizedString(#"Master", #"Master");
NSURL *url = [NSURL URLWithString:#"http://10.0.1.8/~imac/iphone/jsontest.php"];
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url];
NSLog(jsonreturn); // Look at the console and you can see what the results are
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSError *error = nil;
// In "real" code you should surround this with try and catch
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict)
{
rowsArray = [dict objectForKey:#"member"];
[rowsArray retain];
}
NSLog(#"Array: %#",rowsArray);
NSLog(#"count is: %i", [self.rowsArray count]);
[jsonreturn release];
}
You need to implement:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
to handle row selection and to push the view controller for the detail view.
Okay, so I have an app that I'm trying to get to populate a UITableView with the contents of a plist file. I haven't been able to find anyone else having problems doing this and how they fixed it so I'm probably just an idiot but I need to know how all the same!
I'm sure the error is somewhere in my viewDidLoad section or my tableview section...but maybe someone else can give me a better idea.
-(void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"datam" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
self.listData = array;
[array release];
[super viewDidLoad];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
I think [super viewDidLoad] should be foremost in the viewDidLoad method.
NSString *path = [[NSBundle mainBundle] pathForResource:#"datam" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
This seems a little odd; is your file named "datam.plist"?
Try using some NSLogs() throughout your code to see what the status of your array is at any given time:
NSLog(#"%# has %i elements",ARRAY_OBJECT,[ARRAY_OBJECT count]);
Check the GDB output in XCode while the application runs to see if the results match what you expect.
self.listData = array; [array release];
Try this instead:
self.listData = [array copy]; [array release];
NSArray objects are pointers; when you set self.listData = array, you really tell anything looking for listData to look in the memory address originally occupied by array. When you release array, it vacates that memory address, thus making the pointer point to nothing.