Unable to load json data into tableView - ios

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;
}

Related

Show date from Parse database in UITableView section header

I'm building an app that retrieves items from a Parse database and inserts them into a UITableView. In my Parse database, each item has its own date (i.e. film dates). Now this is the part I’m having trouble with:
I would like to sort the items by their own date, with the date for that item being in the section header. I would also like to show only the items whose date is from the current date and onwards. Please also know that I’m using the latest version of iOS and using Objective-C. I have exhausted other sources but have yet to find exactly what I need. Any guidance will be greatly appreciated!
Right now I have this in my ShowsTableViewController.m:
My getShows method:
-(void)getShows{
PFQuery *retrieveShows = [PFQuery queryWithClassName:#"shows"];
[retrieveShows findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError
*error) {
//NSLog(#"%#", objects);
if (!error)
{
_showsArray = [[NSArray alloc] initWithArray:objects];
}
[showsTableView reloadData];
}];
}
And this is how I'm currently populating the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ShowsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"showsCell" forIndexPath:indexPath];
PFObject *tempObject = [_showsArray objectAtIndex:indexPath.row];
cell.cellTitle.text = [tempObject objectForKey:#"title];
return cell;
}
With you require, I think you have to sort your data and put it in to a Array. And this Array will hold list of Dictionary. Each Dictionary will have two key (first key is title: and value of it is title you want show to header, second key is data: and value of it is array item in seciton)
And now you will implement UITableViewDataSource for it:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.listData count];
}
for each section you can implement same like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *data = [[self.listData objectAtIndex:section] objectForKey:#"data"];
}
And show header:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[self.listData objectAtIndex:section] objectForKey:#"title"];
}
And show to cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ShowsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"showsCell" forIndexPath:indexPath];
PFObject *tempObject = [[self.listData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.cellTitle.text = [tempObject objectForKey:#"title];
return cell;
}
You can do this way to achieve what you want.

Why same nsmutablearray gives me valid value and a null on different functions used

I have a NSMutableArray with some objects of type Notes i.e. my class with attributes, iD,note,noteTitle.. I am using the notes array to populate a tableview, and on click, I am trying to open another controller view, to show that specific table row clicked
My code are :
when controller load:
- (void)viewDidLoad {
[super viewDidLoad];
Notes * myNotes =[[Notes alloc] init];
notes = [myNotes getMyNotes];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSString *title = [NSString stringWithFormat:#"%#...",((Notes *) [notes objectAtIndex:indexPath.row]).noteTitle ];
// here i am using my notes nsmutablearray from above method to populate tableview list of titles.. and it is populated fine.
cell.textLabel.text = title;
cell.imageView.image=[UIImage imageNamed:#"back.jpg"];
return cell;
}
Now when I click a row, I am trying to just see if, I will be getting title, body and it for that certain note..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
long selectedRow = indexPath.row;
NSString *title = [NSString stringWithFormat:#"%#...",((Notes *) [notes objectAtIndex:selectedRow]).notes];
NSLog(#"%#",title);
}
But I am getting null this time...
why same code in above function is populating my table view but here not even logging it.
Thank you in advance....
You can try in didSelectRowAtIndexPath method
Notes *note = [[Notes alloc]init];
note = [notes objectAtIndex: indexPath.row];
NSString *title = [NSString stringWithFormat:#"%#...",note.notes];
NSLog(#"%#",title);
Hope it works.

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

UITableView returns the same items on each section

I created a table with sections. Each section has a date (2014-03-23) as a title and under each date I want to populate a list of games to be played that day. When I run the app the table gets the section title fine (date of game), but every section has the same matches list. I want to have the games match under the section date.
I know i need to include indexPath.section in the CellForRowsAtIndexPath but I'm having a hard time figuring it out.
Here's my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return gamesArray.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
uniqueArray = [[NSOrderedSet orderedSetWithArray:dateSection] array];
return [uniqueArray count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.dateSection objectAtIndex:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//NSString *CellIdentifier = [NSString stringWithFormat:#"games cell-%ld-%ld", (long)indexPath.section, (long)indexPath.row];
static NSString *CellIdentifier = #"games cell";
//NSString *CellIdentifier = [NSString stringWithFormat:#"cell-%d-%d", indexPath.section, indexPath.row];
CustomInboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = (CustomInboxCell *)[[CustomInboxCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
PFObject *post = [gamesArray objectAtIndex:indexPath.row];
[cell.teamsLabel setText:[post objectForKey:#"teams"]];
[cell.liveRepeatLabel setText:[post objectForKey:#"liveRepeat"]];
[cell.gameTimeLabel setText:[post objectForKey:#"gameTime"]];
return cell;
}
Any help would be greatly appreciated.
//======================================================
//I decided to use a predicate to filter and get the number of items per date(Number of games per date)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *sectionTitle = [uniqueArray objectAtIndex:section];
if (section >=0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"gameDate == %#",sectionTitle];
NSLog(#"section name = %#", sectionTitle);
NSArray *filtered = [gamesArray filteredArrayUsingPredicate:predicate];
NSLog(#"filtered = %#",filtered);
return filtered.count;
}
return 0;
}
//I just need to iterate through every date and return the number of games per date. Any suggestions?
You need a separate array for each section of the table. In numberOfRowsForSection, you need to return a count for the array that corresponds to the given section.
Here's an example. The data for the table is stored in an NSArray called tableData. The array has one entry for each section of the table. Each entry in tableData is an NSDictionary. The NSDictionary has two keys, title and items. The title key corresponds to an NSString that serves as the title for the table section. The items key corresponds to an NSArray that has the row information for the table section.
The table is organized into two sections like this
Fruits
Apples
Oranges
Animals
Dog
Cat
Horse
Cow
Here's the code
#import "MainViewController.h"
#interface MainViewController () <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (strong, nonatomic) NSArray *tableData;
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.dataSource = self;
self.tableView.delegate = self;
NSDictionary *fruits, *animals;
fruits = #{ #"title" : #"Fruits" , #"items" : #[#"Apples", #"Oranges"] };
animals = #{ #"title" : #"Animals", #"items" : #[#"Dog", #"Cat", #"Horse", #"Cow"] };
self.tableData = #[fruits, animals];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return( self.tableData.count );
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *sectionData = self.tableData[section];
NSArray *items = sectionData[#"items"];
return( items.count );
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *sectionData = self.tableData[section];
NSString *title = sectionData[#"title"];
return( title );
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SomeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *sectionData = self.tableData[indexPath.section];
NSArray *items = sectionData[#"items"];
NSString *name = items[indexPath.row];
cell.textLabel.text = name;
return cell;
}
#end
This is a data set problem, you need to have a separate dataset prepared for each section of your tableview and iterate them using the index path (row, section) properties in your cellForRowAtIndexPath method. If you can do NSLog and share your dataset, it would be more helpful to answer accurately. Hope this helps.

why am I getting NSRangeException in Xcode

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

Resources