App crashes when button is pressed that points to table view - ios

I've got a button pointing to a view and whenever I see press the button my app crashes. Can anyone tell me why? The code is the implementation file for the view that the button pushes to.
#implementation OpenShiftViewController
-(void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
myDictionary = [defaults dictionaryRepresentation];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myDictionary.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray * allKeys = [myDictionary allKeys];
cell.textLabel.text = [myDictionary objectForKey:[allKeys objectAtIndex:indexPath.row]];
cell.detailTextLabel.text = [myDictionary objectForKey:[allKeys objectAtIndex:indexPath.row]];
return cell;
}
#end

- (void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
myDictionary = [defaults dictionaryRepresentation];
myMutableArray = [[NSMutableArray alloc]init];
[self storingObjectsFromDictionaryToArray];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)storingObjectsFromDictionaryToArray
{
NSArray *arr = [myDictionary allKeys];
[myMutableArray addObjectsFromArray:[myDictionary valueForKey:[arr objectAtIndex:0]]];
NSString *str = [NSString stringWithFormat:#"%#",[myDictionary valueForKey:[arr objectAtIndex:1]]];
[myMutableArray addObject:str];
str = [NSString stringWithFormat:#"%#",[myDictionary valueForKey:[arr objectAtIndex:2]]];
[myMutableArray addObject:str];
[myMutableArray addObjectsFromArray:[myDictionary valueForKey:[arr objectAtIndex:3]]];
[myMutableArray addObject:[myDictionary valueForKey:[arr objectAtIndex:4]]];
[myMutableArray addObjectsFromArray:[myDictionary valueForKey:[arr objectAtIndex:5]]];
[myMutableArray addObjectsFromArray:[myDictionary valueForKey:[arr objectAtIndex:6]]];
[myMutableArray addObject:[myDictionary valueForKey:[arr objectAtIndex:7]]];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myMutableArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [myMutableArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [myMutableArray objectAtIndex:indexPath.row];
return cell;
}

The error is Thread 1: breakpoint 9.1
Ahm ... you might have a breakpoint activated ?

You are not getting an error - it is just cause of you having an activated breakpoint.
If you're using Xcode 4, then you can see 'Breakpoints' as seen below. Just click on that to disable breakpoints.
If you are using Xcode 5, then you have to click this Blue button to disable the breakpoint.

As AlexVogel pointed out in the comments, use init method to initialize the dictionary.
Alternatively, you can use lazy loading using property:
- (NSDictionary *)myLoadedDictionary{
if (!myDictionary) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
myDictionary = [defaults dictionaryRepresentation];
}
return myDictionary;
}
Now, in your class, consume [self myLoadedDictionary] instead of myDictionary.
I am not on my machine, but I am pretty much sure that you can define even myDictionary as a getter so that you can use that same name in your code and not myLoadedDictionary.

Like everyone else I would like to point out that should post your error.
Now I also see one problem with cellAtindexPath logic. Your trying to set data on null cell, see [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; will only give you something back if you've already given it something.
You've two options for loading a cell, the new way or the old way, both are kinda of same.
Option one and I recommend this one:
in your viewDidLoad (or what not) register a class for a cell identifer:
[self.tableview registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
In CellForIndexPath to get the cell go:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
The forIndexPath is important here, using old api will return a nil cell.
Option 2:
Load a cell and if its nil, create a it.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}

Related

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.

Filling up NSMutableArray

I've got the code below to fill up an array of notifications. This array is needed to fill up a menu in my iOS app with notifications.
// extract specific value...
NSArray *switchValues = [res objectForKey:#"data"];
NSLog(#"%#", switchValues);
for (NSDictionary *switchValue in switchValues) {
NSString *text = [switchValue objectForKey:#"text"];
NSLog(#"%#", text);
[self.notificationsArray addObject:text];
}
Further down the line I then do this:
- (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];
}
NSMutableArray *titles = self.notificationsArray;
cell.textLabel.text = titles[indexPath.row];
return cell;
}
However, I keep getting an empty array. What am I doing wrong?
Why don't you do
[notificationsArray objectAtIndex:indexPath.row]
instead of
NSMutableArray *titles = self.notificationsArray;
cell.textLabel.text = titles[indexPath.row];
?
If you really dont want, at least do
NSMutableArray *titles = [NSMutableArray arrayWithArray:self.notificationsArray];
And in the first piece of code, what are the Console Logs? Are you sure you enter in the for loop?

Multiple UITableViews, One View, Two Filled, One Blank. What's the issue?

I have 3 tableViews in one view and for some reason two of them are showing data but one isn't, what's my issue?!!
I'm guessing the issue is in the cellForRowAtIndexPath declaration. Attached it is.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView==_titleTV) {
NSDictionary *dictionaryTwo = [_titleArray objectAtIndex:indexPath.section];
NSArray *arrayTwo = [dictionaryTwo objectForKey:#"data"];
NSString *cellValueTwo = [arrayTwo objectAtIndex:indexPath.row];
cell.textLabel.text = cellValueTwo;
}
if (tableView==_cuisineTV) {
NSDictionary *dictionary = [_cuisineArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}
else {
int storyIndex = [indexPath indexAtPosition: [indexPath length]-1];
cell.textLabel.text=[_favouritesArray objectAtIndex: storyIndex];
}
return cell;
}
What's the problem??
Thanks,
SebOH.
Try printing out the value of cellValueTwo to ensure its not a blank string:
NSLog(#"cellValueTwo value: %#",cellValueTwo);
Did you check to make sure the number of cells being created for _titleTV is correct with what you expect from - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section?

how to show the sqlite data in uitableview on otherviewcontroller?

i have viewcontroller .h .m and .xib that contain registration form to insert update and delete.
and i have other xib that contain uitableview that show the sqlite data .how can i display ???
i write the code but its gives the error on array of viewcontroller page and other control that are used in viewcontroller.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[data objectAtIndex:indexPath.row] valueForKey:#"name"];
cell.detailTextLabel.text = [[data objectAtIndex:indexPath.row] valueForKey:#"salary"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
name.text = [[data objectAtIndex:indexPath.row] valueForKey:#"name"];
salary.text = [[data objectAtIndex:indexPath.row] valueForKey:#"salary"];
}
here data is NSArray in viewcontroller.h file gives error here
and also in didSelectRowAtIndexPath method name.text and salary.text gives error because it is the textfield of viewcontroller.
how can i solved it ?????
You have to make sure the data array should be available in otherViewController. For that create a array property in .h file of OtherViewController and while loading this view controller, assign the data array to this property.
Well as you are using SQlite database, you can fetch the data from the database(you'll need to add additional code) in OtherViewController and display it the tableView there.
Also you can't access the private variables of a view controller inside a different view controller. You will have to create properties for them or create public methods.
do it like this.. First create temporary dictionary and than fetch the data from that..
NSDictionary * tmpDictn = [data objectAtIndex:indexPath.row];
cell.textLabel.text = [tmpDictn valueForKey:#"name"];
cell.detailTextLabel.text = [tmpDictn valueForKey:#"salary"];
And same here..
NSDictionary * tmpDictn = [data objectAtIndex:indexPath.row];
name.text = [tmpDictn valueForKey:#"name"];
salary.text = [tmpDictn valueForKey:#"salary"];

NSUserDefault not loading in table view

I have a main view with a button that when pressed it adds the url from the web view(like a bookmark) to a table view. The only problem is that its not loading. ive been at it for hours now but cant figure it out. I think i am loading the data in the table view wrong but not quiet sure.
This is the MainViewController.m
- (IBAction)bookmark:(id)sender {
UIActionSheet *actionSheet =
[[UIActionSheet alloc] initWithTitle:[[[[self webView] request] URL]
absoluteString] delegate:nil cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil otherButtonTitles:#"Add", nil];
[actionSheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSMutableArray *bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
if (!bookmarks) {
bookmarks = [[NSMutableArray alloc] init];
}
[bookmarks addObject:[[[[self webView]request] URL] absoluteString]];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks
forKey:#"Bookmarks"];
}
}
This is BookmarksViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", bookmarks);
bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
cell.textLabel.text = [self.bookmarks objectAtIndex:indexPath.row];
return cell;
}
When your app is first run there is nothing set for the Bookmarks key in NSUserDefaults. So the line:
bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
in viewDidLoad leaves bookmarks set to nil.
In your action sheet handler you actually deal with this properly.
And one other big problem is the call to:
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
in your cellForRowAtIndexPath... method. Why do you update NSUserDefaults every time a cell is needed? Don't do this.
The command [tableView dequeueReusableCellWithIdentifier:CellIdentifier] does NOT always return a cell. It only returns a cell if there is a cell in the reusable-cell queue.
So your method should be:
- (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];
}
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
cell.textLabel.text = [self.bookmarks objectAtIndex:indexPath.row];
return cell;
}

Resources