why am I getting NSRangeException in Xcode - ios

I am trying to load a plist from my project, this was working until I accidentally deleted my plist. the plist has 5 arrays, with 2 elements apiece. I know that I the program is trying to access beyond the range of the array, but what I don't know is where this index is set? Here is the code that it bombs on: this code is executed twice successfully,then for some reason it tries to access it a third time and bombs on the first line,why?
It throws this exception:
NSRangeException -[_NSCFARRAY objectAtIndex] index(2) beyond bounds (2)
please help, this is for a final project due on Monday and now I feel like I have to start over again.
NSString *nameOfAccount = [account objectAtIndex:indexPath.row];
cell.textLabel.text = nameOfAccount;
NSString *accountNumber = [number objectAtIndex:indexPath.row];
cell.detailTextLabel.text = accountNumber;

Since you are displaying the data in same cell, you can include both name and number of account into a dictionary or a custom model object which will hold both info.
In your plist this might be the structure, array of dictionary objects
When you are displaying the info. For the dataSource create an array say accounts.
#define kAccountName #"Name"
#define kAccountNumber #"Number"
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle]pathForResource:#"Accounts" ofType:#"plist"];
self.accounts = [NSArray arrayWithContentsOfFile:filePath];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.accounts count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *account = self.accounts[indexPath.row];
cell.textLabel.text = account[kAccountName];
cell.detailTextLabel.text = account[kAccountNumber];
// Configure the cell...
return cell;
}
Source code

Related

objective c - table view not able to show the data in the screen

I have an array of data. And wr my data are not displaying in the screen. Not sure, what i am missing.
#property NSMutableArray *NotifTotal;
#interface HomeVC ()<UITableViewDelegate, UITableViewDataSource>
#end
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.NotifTotal count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"FilterTableViewCell";
FilterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dict;
dict = [self.NotifTotal objectAtIndex:indexPath.row];
NSLog(#"%#", dict); // data is coming.
NSString* salt = [dict objectForKey:#"salt"];
NSString* name = [dict objectForKey:#"Name"];
NSLog(#"%#%#", name,swerk); // in console i can print the data
cell.sLabel.text = [NSString stringWithFormat: #"%#", salt];
cell.nLabel.text = [NSString stringWithFormat: #"%#", name];
return cell;
}
Why my data is not showing in my screen.I added the delegate, data source also in my screen.Any solution ?
You said "I added the delegate, data source also in my screen" but it is not very clear to me by that you meant conforming your HomeVC to UITableViewDelegate and UITableViewDataSource as your posted code or you actually set the delegate of your UITableView to HomeVC. So here are something you should check:
Set datasource of your UITableView to HomeVC using Interface Builder or following code:
self.tableView.dataSource = self; // I am assuming self == HomeVC instance
Make sure [self.NotifTotal count] > 0.
Make sure it is not about UITableView's configuration issue by adding a break point to cellForRowAtIndexPath and confirm it called.
If it isn't: go back to 2 points above.
If it is: this is UI issue, let's check if your cells's height is near 0 or they have a transparent color and so on. You can use Xcode's View Debugging tool to debug the issue.
Since you haven't mentioned having registered the cell identifier yet, I assume that's the problem. One way to do this is in your storyboard or xib. Select the prototype cell in your tableview, and set the "identifier" field (in the Attributes inspector pane of Interface Builder). Set it to "FilterTableViewCell".
This looks like a xib problem. I added a bit of code in the middle.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"FilterTableViewCell";
FilterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//Add this part
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"FilterTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
//end
NSDictionary *dict;
dict = [self.NotifTotal objectAtIndex:indexPath.row];
NSLog(#"%#", dict); // data is coming.
NSString* salt = [dict objectForKey:#"salt"];
NSString* name = [dict objectForKey:#"Name"];
NSLog(#"%#%#", name,swerk); // in console i can print the data
cell.sLabel.text = [NSString stringWithFormat: #"%#", salt];
cell.nLabel.text = [NSString stringWithFormat: #"%#", name];
return cell;
}

how to display one of the 4 values in one label from a JSON link in objective c?

I am doing one project now with JSON links.
In that, leaves for employees are given as casual-5, emergency-2, vacation-3, medical-0.
In JSON link it is given seperately.
"employee_casual_leave":0,"employee_medical_leave":0,"employee_annual_leave":0,"employee_emergency_leave":1
But in my code I have to get any one of them in one label. i.e. type of leave a person took should be displayed in a label.
I had put an label in xib and set my cellForRowAtIndexPath as following:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
static NSString *CellIdentifier = #"cel";
NSString *str=[NSString stringWithFormat:#"%ld",(long)indexPath.section];
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
[UserDefaults setObject:str forKey:#"leaveCount"];
[UserDefaults synchronize];
cell1=[self.tab1 dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell1==nil) {
NSArray*toplevelobject=[[NSBundle mainBundle] loadNibNamed:#"emp_leave_list" owner:self options:nil];
cell1=[toplevelobject objectAtIndex:0];
}
NSString *s7=[[[Dict1 objectForKey:#"employee_list"]objectAtIndex:indexPath.section ]objectForKey:#"employee_other_leave"] ;
NSString *s700= [NSString stringWithFormat:#"%#", s7];
cell1.leave_type.text=s7;
return cell1;
}
In the label "leave_type" I want to display the type of leave the employee took whether its casual or emergency or others or vacation. Please give me an answer as soon as possible.
1) Parse json in method and declare a array in YourViewController.h file
NSMutableArray *arrEmployee;
-(void)getEmployeeDetail:(NSDictionary *)jsonResponse
{
arrEmployee = [jsonResponse objectForKey:#"employee_list"];
[yourTable reloadData];
}
2) Add tableview delegate
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return arrEmployee.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
YourCell *cell = (YourCell *)[tableView dequeueReusableCellWithIdentifier:#"YourCellIdentifier"];
NSDictionary *info = [arrEmployee objectAtIndex:indexPath.row];
cell.lblLeave = [info objectForKey:#"employee_annual_leave"];
return cell;
}

Unable to load json data into tableView

i'm trying to do a weather application
#import "LocationTableViewController.h"
#interface LocationTableViewController (){
NSArray *hourlyData;
NSArray *dailyData;
}
#end
#implementation LocationTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = #"https://api.forecast.io/forecast/cd8edc928426f2ac3e341441c7a9c6d3/37.8267,-122.423";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
NSDictionary *dataFromWeb = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
i took a json query that gives hourly and daily data, then converted it into dictionary. Here i created two dictionaries ie hourly dictionary and daily dictionary which contains fields like temperature, humidity, etc etc
My main goal is to create a weather app using both of the dictionaries hourly and daily by loading them into a table view.
NSDictionary *hourlyDict = [dataFromWeb objectForKey:#"hourly"];
hourlyData = [hourlyDict objectForKey:#"data"];
NSDictionary *dailyDict = [dataFromWeb objectForKey:#"daily"];
dailyData = [dailyDict objectForKey:#"data"];
NSLog(#"%#", [[dailyData objectAtIndex:0] objectForKey:#"humidity"]);
}
By here i successfully created both the dictionaries and tried to NSlog the data it works fine.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
I feel like my problem starts here in loading the dictionary into tableView.
1) In storyboard i embedded the table view into NavigationView.
2) i made the table View content as dynamic protocol
3) named the cell identifier as cell
i think problem starts here in sending data into table. Basically my app should contains 3 sections summary,hourly data and daily data. but i just want to try for now only on daily data.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
Since i don't want any section, i removed this no.of. sections, but it threw me error, so kept it back and returned 0. , i also tried making it 1, but app crashes.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"hello");
return dailyData.count;
}
Here i want columns as no.of rows in dictionary, so i made dailyData.count.
Here starts the main problem, this - (UITableViewCell *)tableView:........ function is not being called, i tried to NSlog a message, it didn't show up
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSLog(#"hello");
cell.textLabel.text = [[dailyData objectAtIndex:indexPath.row]objectForKey:#"sunsetTime"];
return cell;
}
can some one help me out please. Thanks in advance. Im new to programming.
here i attached the Google Drive link for project
To fix your issue you need to set your number of sections to 1 (you must always have at least 1 section for anything to display).
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
The reason you are getting a crash when you set your number of sections to 1 is because you are trying to use an NSDictionary as an NSString. You need to get an NSString from the NSDictionary. The below code will get the summary from the daily data for that row and display the summary.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSDictionary *rowData = [dailyData objectAtIndex:indexPath.row];
cell.textLabel.text = [rowData objectForKey:#"summary"];
return cell;
}
// sections should be 1 instead of 0
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
[dailyData objectAtIndex:indexPath.row] has following dictionary that cannot be assigned as Cell label text , you have to assign some string value to Cell Label text
{
apparentTemperatureMax = "60.49";
apparentTemperatureMaxTime = 1462316400;
apparentTemperatureMin = "52.96";
apparentTemperatureMinTime = 1462276800;
cloudCover = "0.92";
dewPoint = "50.37";
humidity = "0.8100000000000001";
icon = "partly-cloudy-day";
moonPhase = "0.89";
ozone = "351.23";
precipIntensity = 0;
precipIntensityMax = 0;
precipProbability = 0;
pressure = "1014.68";
summary = "Mostly cloudy throughout the day.";
sunriseTime = 1462281126;
sunsetTime = 1462331002;
temperatureMax = "60.49";
temperatureMaxTime = 1462316400;
temperatureMin = "52.96";
temperatureMinTime = 1462276800;
time = 1462258800;
visibility = "8.779999999999999";
windBearing = 275;
windSpeed = "5.83";
}
cell.textLabel.text = [dailyData objectAtIndex:indexPath.row]; you are assigning a dictionary to tableViewCell label. if you want specific key value then check below code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
//Number to Sting --> [Number stringValue]
cell.textLabel.text = [[[dailyData objectAtIndex:indexPath.row]objectForKey:#"sunsetTime"] stringValue];
return cell;
}
I was trying to pass float into my table cell text, theres the mistake. We have to pass only text into that one, but i was trying to insert float values. now i passes some text values it works fine
Thank you all for your lovable support. Thank you once again
use this below code, And your code is working for me,
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"hello");
return dailyData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSLog(#"hello %#",[[dailyData objectAtIndex:indexPath.row] objectForKey:#"humidity"]);
cell.textLabel.text = [NSString stringWithFormat:#"%#",[[dailyData objectAtIndex:indexPath.row] objectForKey:#"humidity"]];
return cell;
}
And your output is given below,
humidity value is printed
hope its helpful
You must show not to come out the data, because your dailyData is a NSArray! How do you use an array as a string to use?Suggest you use a model, to store data.
NSDictionary *hourlyDict = [dataFromWeb objectForKey:#"hourly"];
hourlyData = [hourlyDict objectForKey:#"data"];
NSDictionary *dailyDict = [dataFromWeb objectForKey:#"daily"];
dailyData = [dailyDict objectForKey:#"data"];
for (id obj in hourlyData) {
newsModel *model=[[newsModel alloc]init ];
model.name=obj[#"summary"];
[_dataArray addObject:model];
}
NSLog(#"%#", [[dailyData objectAtIndex:0] objectForKey:#"humidity"]);
In the table view delegate :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIde=#"cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIde];
if (!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIde ];
}
newsModel *model=_dataArray[indexPath.row];
cell.textLabel.text=model.name;
return cell;
}

Section Header Titles incorrect

I have been trying to set the uiTableViewHeader for my UITableView for a couple of days now with no luck. I don't think I am far off. Currently it shows the section Titles however multiples the number of records by X amount ( I presume my count may be wrong).
I think I need to further configure my cellForRowAtIndexPath method but Im unsure how.
I am a bit confused. I need to group the rowsAtIndexPath to the sections and stop them multiplying.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"atozCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
//Searchbar code is here
NSDictionary *dataDict = [self.sortedArray objectAtIndex:indexPath.section];
cell.textLabel.text = [dataDict objectForKey:#"Title"];
}
return cell;
}
Section Counts
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.sectionArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.sectionArray objectAtIndex:section];
}
Data Populated from
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"law2" ofType:#"plist"];
// Load the file content and read the data into arrays
self.dataArray = [NSArray arrayWithContentsOfFile:path];
//Sort the array by section
self.sortedArray = [self.dataArray sortedArrayUsingDescriptors:#[
[NSSortDescriptor sortDescriptorWithKey:#"Section" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"Title" ascending:YES]]];
//Section for sorting
self.sectionArray = [self.sortedArray valueForKeyPath:#"Section"];
Always you are sending index of the object. So please try to use this one
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [self.tableDataIndexTitles objectAtIndex:index];
}

Accessing dictionaries in PList for UITableView

I'd like to create a simple reference app that lists a group of people, their job title, and their portrait. What I have so far is the list of people and their job title. It works alright, but I think I should have done it differently.
From reading other posts, I suppose I should be using dictionaries. This is how my PList currently looks:
And this is how the important bits of my code look:
#implementation RootViewController
#synthesize staffArray, subtitleArray;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* path = [[NSBundle mainBundle] pathForResource:#"StaffData" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableArray *tmpNameArray = [dict objectForKey:#"Root"];
self.staffArray = [[NSMutableArray alloc] initWithArray:tmpNameArray copyItems:YES];
NSMutableArray* tmpSubtitleArray = [dict objectForKey:#"Subs"];
self.subtitleArray = [[NSMutableArray alloc] initWithArray:tmpSubtitleArray copyItems:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [staffArray count];
}
// Customize the appearance of table view cells.
- (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];
}
// Configure the cell.
cell.textLabel.text = [staffArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [subtitleArray objectAtIndex:indexPath.row];
return cell;
}
Using two arrays kind of defeats the purpose of OOP, I think, because in this case the people aren't connected to their job titles; they just happen to be in the same order. I'd like to create for example:
Array called Jonas, first value = job title, second value = pathToImage.png.
Another array called Andreas, etc etc etc.
What do I do?
I think that as a start, your design lacks an "Employee" object, that has data members like "Name", "JobTitle", etc... After you have this set up, just create an array of people and take whatever you need from there, by index.

Resources