Accessing elements from an array in objective c - iphone

I am trying to access individual elements of my array. This is an example of the contents of the array i am trying to access.
<City: 0x4b77fd0> (entity: Spot; id: 0x4b7e580 <x-coredata://D902D50B-C945-42E2-8F71-EDB62222C0A7/Spot/p5> ; data: {
CityToProvince = 0x4b7dbd0 <x-coredata://D902D50B-C945-42E2-8F71-EDB62222C0A7/County/p15>;
Description = "Friend";
Email = "bla#bla.com";
Age = 21;
Name = "Adam";
Phone = "+44175240";
}),
The elements i am trying to access are Name, Phone, etc ...
How would i go about doing this?
UPDATE:
OK, understanding that I am looking at core data now, how would I go about removing an object from being displayed in my table view?
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *object = (NSManagedObject *)[entityArray objectAtIndex:indexPath.row];
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
return cell;
}

That doesn't look like an array. That looks like a Core Data entity. You may have an array of them, but it appears as though you're trying to access the members of the entity itself. To do so, you can use the NSManagedObject method -(id) valueForKey:.
NSManagedObject *entity = /* ... retrieve entity from Core Data ... */;
NSString *name = [entity valueForKey:#"Name"];

Related

Populating UITableView with NSArray in iOS 7

A lot of the methods have deprecated in iOS 7 in order to set font, textLabel, and color for UITableView cells. I'm also just having a difficult time populating the view with these values. Here's a snippet of my code:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* jobs = [json objectForKey:#"results"];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
jobsArray = [jobsInfo objectForKey:#"results"];
}
}
I am looping through an array of dictionaries from a GET request and parsed. I am now attempting to fill my UITableView with the following code:
-
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [jobsArray 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];
}
NSDictionary *jobsDic = [jobsArray objectAtIndex:indexPath.row];
[cell.textLabel setText:[jobsDic objectForKey:#"jobtitle"]];
return cell;
}
Also, I have declared this is in my .h file:
NSArray *jobsDic;
Any ideas on what I'm doing wrong? Is this an iOS 7 problem?
It seems that you reinitialize jobsarray at the end of the forin loop.
You didn't mean ?
NSArray* jobs = [json objectForKey:#"results"];
NSMutableArray *jobsTemp = [[NSMutableArray alloc] initWithCapacity:jobs.count];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
[jobsTemp addObject:jobby];
}
self.jobsArray = jobsTemp; //set #property (nonatomic, copy) NSArray *jobsArray; in the .h
[self.tableView reloadData]; //optional only if the data is loaded after the view
In the cell for row method :
- (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];
}
JobInfo *job = self.jobsArray[indexPath.row];
cell.textLabel.text = job.title;
return cell;
}
And don't forget :
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.jobsArray.count;
}
Update - an user suggested an edit :
It's true that count isn't a NSArray property. But as Objective-C lets us use a shortcut notation for calling method with a dot, this code works. You have to know limitation of this : if you use a NSArray subclass with a count property with a custom getter this could have side effects #property (nonatomic, strong, getter=myCustomCount) NSUInteger count. As I think code readability is to me one of most important things I prefer to use dot notation. I think Apple SHOULD implement count as readonly property so I use it this way (but it's my point of view). So for those which don't agree with me just read return [self.jobsArray count]; in the tableView:numberOfRowsInSection: method.
Change the declaration of jobsArray from NSArray to NSMutableArray.
Add an initialization at the beginning point of fetchedData method like follows.
if(!jobsArray) {
jobsArray = [NSMutableArray array];
}
else {
[jobsArray removeAllObjects];
}
Remove the following line.
jobsArray = [jobsInfo objectForKey:#"results"];
Instead of that, add the initialized object to the array at the end of for loop.
[jobsArray addObject:jobby];
Add a [tableView reloadData]; at the end of your *-(void)fetchedData:(NSData )responseData; method implementation.
Initially when you are loading the view, tableView will get populated. After you received the data, tableView will not be known that it is received.
Everything else seems good. Hope rest will work fine.

Parsing HTML Data in UITableView

I have an HTML Data which looks like:
<div id="foo"><a class="someClass" href="http://somelink">Some Title</a></div>
<div id="foo"><a class="someClass" href="http://somelink1">Some Title 1</a></div>
<div id="foo"><a class="someClass" href="http://somelink2">Some Title 2</a></div>
I'm able to show Link title in the tableView, but how can I get URL of these specific title to load a new view (which is pushed through navigation controller upon selecting table cell) ?
Here's the code I'm using to parse HTML Data:
HTMLParser * parser = [[HTMLParser alloc] initWithData:responseData error:&error];
HTMLNode * bodyNode = [parser body];
someArray = [[bodyNode findChildrenWithAttribute:#"id" matchingName:#"someID" allowPartial:NO] retain];
And this one to show the array data in the table:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [someArray 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];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
HTMLNode* someNode = [someArray objectAtIndex:[indexPath row]];
cell.textLabel.text = [NSString stringWithFormat:#"%#",[someNode allContents]];
return cell;
}
When you get a node and want information about a child node within it, you have to continue parsing to find the child node and then get the attribute you are looking for. For example:
HTMLNode *anchorNode = [someNode findChildTag:#"a"];
NSString *anchorHref = [anchorNode getAttributeNamed:#"href"];
It might help to mention that you are looking at Ben Reeves' HTMLParser. (At least I think that is the one you are using).

how to pass NSDictionary values to UITableViewCell properly

Hey guys I have a problem, I have a NSDictionary of NSArrays and im trying to set up alphabetical sections so AAAAA, BBBB, CCCC.... etc however when I pass my values over its printing out all of the A values right into one uitableviewcell then the B's in the next... which is not right what Im after. Im hoping to have alphabetical sections with one NSArray/Dictionary value per UItableviewcell..
this is how Im currently setting it up, I think maybe I might be missing an If statment however Im just not exactly sure how to do this so would like some help if possible.. thanks in advance.
- (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.accessoryType = UITableViewCellAccessoryNone; //make sure their are no tickes in the tableview
cell.selectionStyle = UITableViewCellSelectionStyleNone; // no blue selection
// Configure the cell...
if(indexPath.row < [self.arraysByLetter count]){
NSArray *keys = [self.arraysByLetter objectForKey:[self.sectionLetters objectAtIndex:indexPath.row]];
NSString *key = [keys description];
NSLog(#"thingy %#", key);
cell.textLabel.text = key;
}
return cell;
}
This is what it looks like on the emulator
UPdate I made chages to my code as suggested below and now this is what happens...
when emulator first loads
I then scroll to the bottom of the list and back to the top and it looks like this.
NSString *key = [keys description];
Here you're setting the text to be the string representation of ALL the keys. :)
I think you want this (and I hope I've interpreted your code properly)
NSArray *keys = [self.arraysByLetter objectForKey:[self.sectionLetters objectAtIndex:indexPath.section]];
NSString *key = [keys objectAtIndex:indexPath.row];
NSLog(#"thingy %#", key);
So, get the KeysArray using the IndexPath section,
then get the value of the cell using the IndexPath row.

Table View Crashing When Accessing Array of Dicitonarys

All,
When my table view loads, it accesses several delegate methods. When I configure the cell, I have it calling this method (where "linkedList" is an array of dictionarys):
- (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];
}
// Configure the cell...
VUWIManager *vuwiManager = [VUWIManager sharedVuwiManager];
NSLog(#"%#", [[vuwiManager linkedList]objectAtIndex:indexPath.row]);
NSLog(#"TESTZOMGOFDSOJFDSJFPODJSAPFDS");
cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row];
return cell;
}
It crashes at the line cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row]; - I know I'm doing something wrong here but I'm not sure what it is. Again, linkedList is a NSMutableArray of NSDictionarys.
Edit: if I call cell.textLabel.text = [[vuwiManager linkedList]objectAtIndex:indexPath.row]; it returns:
{
IP = "192.168.17.1";
desc = "description";
}
in the debugger. Just thought I'd give a little bit of formatting details.
Thanks
You are trying to assign an object NSDictionary to cell.textLabel.text, which must be passed a NSString.
Did you want :
NSString *s = [NSString stringWithFormat:#"%#",
[[vuwiManager linkedList]objectAtIndex:indexPath.row]];
cell.textLabel.text = s;
?
Setting an NSString * to an NSDictionary * will likely result in a crash when it tries to access any string methods that are not implemented in the dictionary. If you want that string you are logging add a call to description.
cell.textLabel.text = [[[vuwiManager linkedList]objectAtIndex:indexPath.row] description];
It looks like you are setting cell.textLabel.text to a NSDictionary instead of an NSString. If linkedList is an NSMutableArray of NSDictionaries, then you need to add on objectForKey:#"String key" to access the string
cell.textLabel.text = [[[vuwiManager linkedList]objectAtIndex:indexPath.row] objectForKey:#"STRING_KEY_HERE"];

Objective C - Problem with NSMutableArray and NSTableView

I have a class named Person and in this class is the property PersonName (amongst others).
A MutableArray MyUserInfoArr contains many Person objects.
I want to list each PersonName in a Cell of a TableView? How do I do this?
Thanks in advance.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Person *myPerson;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSString *cellValue = [myUserInfoArr objectAtIndex:indexPath.row];
cell.text = cellValue;
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
Person *myPerson = [myUserInfoArr objectAtIndex:indexPath.row];
cell.textLabel.text = myPerson.DisplayName;
NSLog(#"abc %i",indexPath.section);
}
This is my code, it ran, but it just return the attribute Person.DisplayName of the last object Person in the myUserInfoArr. How to fix it?
The easiest way would be to just set the text with:
Person *person = [MyUserInfoArr objectAtIndex:[indexPath indexAtPosition:1]];
cell.textLabel.text = person.PersonName;
indexPath contains two indexes, first is the section index, the 2nd is the item's index within the section. So I'm assuming in your case you have a single section, that's why there is nothing to do with the indexAtPosition:0.
You also have to set up the table's data source methods, these tell your table view how many sections/rows it should show:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [MyUserInfoArr count];
}
Person *person = [myUserInfoArr objectAtIndex:indexPath.row];
cell.textLabel.text = person.PersonName;
The reason your code doesn't work: the text property needs to be an NSString *, not a Person *.