NSArray count not working - iphone

So I have a UITableView, and I populate the tableview with data from a .plist. This has been working fine for me until today, when I tried to do the same and I can't get the numberOfRowsInSection, method to work. Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if...
else if (segmentOptions == exchange){
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
return [array count];
}
//Else
return contentArray.count;
}
So in that code, everytime I run it, the code crashs. But, I use basiacally the same code to set the tableview text and that works fine:
- (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];
}
if...
else if (segmentOptions == exchange) {
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:indexPath.section]]];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
}
return cell;
}
And that code works fine, which is why I'm so confused. When I set the number of rows to return to a specific number, and run the rest of the code, everything works fine. So I'm really lost. Thands in advance
UPDATE
I tried it with the proper count notation, return [array count];, and I still get the same crash and the same console output.

First, count is not a property so you should not be using dot syntax to access it.
I would suggest changing your code so that you are not accessing the count method like a property.
Second,
Test to see if your array is nil and that it is even an array.
Third,
Post the actual complete stack trace.

Break it down and debug, if console message is not being helpful. It helps sometimes, specially when it's late. i.e.
// NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
NSLog(#"%d", section);
id objAtIndex = [listOfExchanges objectAtIndex:section];
NSLog(#"%#", listOfExchanges);
NSLog(#"%#", objAtIndex);
id objForKey = [exchangeDictionary objectForKey:objAtIndex];
NSLog(#"%#", exchangeDictionary);
NSLog(#"%#", objForKey);

Try this:
[array count]
count is not a property, it is a method you run on the array.

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.

NSMutableArray not updating and UITableView not reloading

I'm creating a chat application. I have 2 methods in my view controller one for sending and one for receiving the messages. In the sending method i create a NSMutableDictionary with two objects ..
NSMutableDictionary *msgFilter = [[NSMutableDictionary alloc] init];
[msgFilter setObject:messageStr forKey:#"msg"];
[msgFilter setObject:#"you" forKey:#"sender"];
[messages addObject:msgFilter];
"messages" is my main NSMutableArray for holding all the messages, whose property is set and synthesized and allocated. When i send the message it is properly added into the NSMutableArray and the UITableView is updated showing me the values in the cell.
I have a method in my appDelegate to check for messages received and use the same procedure to parse the data and store it in an NSMutableDictionary. This dictionary is then passed to the viewcontroller and added into the same NSMutableArray(messages) and i then call [self.chattable reloadData]. But this doesn't do anything. When i nsloged the NSMutableArray it only had the received message not the whole data(send + received).
Why is it not adding the received messages into the same array and why is it not refreshing my table. I've been trying to get it to work for days now...Plz help..
//Recives message section
NSMutableDictionary *msgFilter = [myDelegate msgFilter];
[messages addObject:msgFilter];
[self.tView reloadData];
//Tableview section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [messages count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(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];
}
NSDictionary *s = (NSDictionary *) [messages objectAtIndex:indexPath.row];
NSString *sender = [s objectForKey:#"sender"];
NSString *message = [s objectForKey:#"msg"];
if ([sender isEqualToString:#"you"])
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"TX: %at", message];
}
else
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"RX: %at", message];
}
return cell;
}
Declare messages array in Application Delegate. so it will be shared array. so might be your problem get solved. because it is shared array. so you can add Dictionary in messages array from any where, no need to pass dictionary between diff UIView.

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"];

Unable to view table in RootViewController

I have a navigation app that I am working on which for some reason is not allowing me to view my table on my initial screen (i.e. from the RootViewController). I have the following method that is called by my "viewDidLoad" method:`
- (void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
`
which does some work, and then calls the method:
- (void) readRestaurantsFromDatabase:(double)userLatitude
withUserLocation:(double)userLongitude{
This method does some work with an NSArray called "sortedArray" which is a property declared, and synthesized in RootViewController:
//compile a list of categories
NSMutableArray *categoryList = [[NSMutableArray alloc] init];
[categoryList addObject:#"All Types"];
for (Restaurant *restCat in restaurants){
[categoryList addObject:restCat.category];
}
//remove duplicates
NSArray *copy = [categoryList copy];
NSInteger index = [copy count] - 1;
for (NSString *restCategory in [copy reverseObjectEnumerator]) {
if ([categoryList indexOfObject:restCategory inRange:NSMakeRange(0, index)] != NSNotFound) {
[categoryList removeObjectAtIndex:index];
}
index--;
}
[copy release];
//put list in alphabetical order
sortedArray = [categoryList sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
This is how the above method ends. I then have the following code for my "cellForRowAtIndexPath" 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] autorelease];
}
// Configure the cell.
NSString *cellValue = [sortedArray objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
To me, everything looks fine. When I run my code, I have NSLog statements that issue output to the console which clearly shows me that the NSArray sortedArray contains data. Yet, when I run the code on my iPhone simulator in XCode, I get an empty table. Can anyone see what I'm doing wrong?
Thanks in advance to all who reply.
Have you connected your tableView to a property in interface builder?
Also, when your sorted array changes, you might want to call [myTabelView reloadData]; to refresh the table. Do this each time you change your sortedArray i.e.
//put list in alphabetical order
sortedArray = [categoryList sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
// The sorted array has changed, get the table view to refresh
[myTabelView reloadData];
Have you implemented tableView:numberOfRowsInSection: ?
This should probably return [sortedArray count].
Did you fill numbersOfRowInSection?
On a side note, I don't understand why you're copying everything then removing duplicates instead of skipping adds when your array contains the object.
Double check your tableview datasource property. If the datasource isn't set for your UITableView. Make sure that you are setting that to your object and make sure your object defines the -(NSInteger)tableView:numberOfRowsInSection: method.
That should return [sortedArray count].