Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Strings Going Missing

I have been trying to build an app and here is my latest issue. i am trying to take the value of certain things when a row is selected in a tableview and hold onto the value into the next view. in the did select row at index path method each string has a value but in the prepare for segue method it is blank. I don know what i am doing wrong.

Header File

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface PastHoursTableViewController : UITableViewController

@property (strong, nonatomic) NSArray *uploads;
@property (strong, nonatomic) NSString *date;
@property (strong, nonatomic) NSString *crew;
@property (strong, nonatomic) NSString *timeIn;
@property (strong, nonatomic) NSString *timeOut;
@property (strong, nonatomic) NSString *hours;
@property (strong, nonatomic) NSString *objectid;
@property (strong, nonatomic) PFObject *uploadedHours;
@end
'''



Implementation File
'''IOS
#import "PastHoursTableViewController.h"
#import "OldHoursViewController.h"


@interface PastHoursTableViewController ()

@end

@implementation PastHoursTableViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    PFUser *currentUser = [PFUser currentUser];
    PFQuery *query = [PFQuery queryWithClassName:@"Hours"];
    [query whereKey:@"StudentName" equalTo:currentUser.username];
    [query orderByDescending:@"createdAt"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
             NSLog(@"Error %@ %@", error, [error userInfo]);
        }else{
            self.uploads = objects;
            [self.tableView reloadData];
        }
    }];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#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.uploads count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    PFObject *hours = [self.uploads objectAtIndex:indexPath.row];
    cell.textLabel.text = [hours objectForKey:@"Date"];

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    PFObject *selectedHours = [self.uploads objectAtIndex:indexPath.row];
    self.date = [selectedHours objectForKey:@"Date"];
    self.crew = [selectedHours objectForKey:@"Crew"];
    self.timeIn = [selectedHours objectForKey:@"TimeIn"];
    self.timeOut = [selectedHours objectForKey:@"TimeOut"];
    self.hours = [selectedHours objectForKey:@"NumberOfHours"];
    self.objectid = selectedHours.objectId;
    self.uploadedHours = selectedHours;
    NSLog(@"Date:%@ Crew:%@ Time In:%@ Time Out:%@ Hours:%@ Object ID:%@", self.date, self.crew, self.timeIn, self.timeOut, self.hours, self.objectid);
    if ([self.date length]== 0|[self.crew length]== 0|[self.timeIn length] == 0| [self.timeOut length] == 0| [self.hours length]==0) {
        UIAlertView *alertview = [[UIAlertView alloc]initWithTitle:@"Oops" message:@"Yarg" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alertview show];
    }
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/



- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showDetails"]) {
        if ([self.date length]== 0|[self.crew length]== 0|[self.timeIn length] == 0| [self.timeOut length] == 0| [self.hours length]==0) {
            UIAlertView *alertview = [[UIAlertView alloc]initWithTitle:@"Oops" message:@"Yipee" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alertview show];
        }
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
        OldHoursViewController *oldHoursViewController = (OldHoursViewController *)segue.destinationViewController;

        oldHoursViewController.dateString = self.date;
        oldHoursViewController.crewString = self.crew;
        oldHoursViewController.timeInString = self.timeIn;
        oldHoursViewController.timeOutString = self.timeOut;
        oldHoursViewController.hoursString = self.hours;
        oldHoursViewController.objectidString = self.objectid;
        oldHoursViewController.oldHours = self.uploadedHours;
        if ([oldHoursViewController.dateString length]== 0|[oldHoursViewController.crewString length]== 0|[oldHoursViewController.timeInString length] == 0| [oldHoursViewController.timeOutString length] == 0| [oldHoursViewController.hoursString length]==0) {
            UIAlertView *alertview = [[UIAlertView alloc]initWithTitle:@"Oops" message:@"WoooHooo" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alertview show];
        }
    }
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}


@end
'''

2 Answers

Stone Preston
Stone Preston
42,016 Points

it really seems like all your string properties are not necessary. I assume your Hours object contains all this data correct? there really is no reason to have a separate property for all the different strings when the Hours object it self contains it. You should just access the data through that object, not assign it to 10 different strings.

id make the following changes

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    PFObject *selectedHours = [self.uploads objectAtIndex:indexPath.row];
   //remove all the string assignments, you dont really need them when they are stored in the object. 
   //also remove that uploadedHours object (you already have your selectedHours object)

}

and then in prepare for segue just pass the selectedHours object to the view controller (you will have to add a property to your view controller thats being segued to to hold it)

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showDetails"]) {

        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
        OldHoursViewController *oldHoursViewController = (OldHoursViewController *)segue.destinationViewController;

       OldHoursViewController.hoursObject = self.selectedHours

    }

}

that will make your data much easier to pass around.

While that did clear up my code. all the values of each item are still null. here is what it use them for in the ned view in case it helps: '''iOS

  • (void)viewDidLoad { [super viewDidLoad];

        NSString *date = [NSString stringWithFormat:@"Date: %@",[self.oldHours objectForKey:@"Date"]];
        NSString *crew = [NSString stringWithFormat:@"Crew: %@",[self.oldHours objectForKey:@"Crew"]];
        NSString *timeIn = [NSString stringWithFormat:@"Time In: %@",[self.oldHours objectForKey:@"TimeIn"]];
        NSString *timeOut = [NSString stringWithFormat:@"Time Out: %@",[self.oldHours objectForKey:@"TimeOut"]];
        NSString *hours = [NSString stringWithFormat:@"Hours Of Work: %@",[self.oldHours objectForKey:@"NumberOfHours"]];
        self.date.text =date;
        self.crew.text =crew;
        self.timeIn.text =timeIn;
        self.timeOut.text =timeOut;
        self.hours.text =hours;
    

    } '''

Stone Preston
Stone Preston
42,016 Points

are you sure that object actually has data with it? log the object itself and see what you get

NSLog(@"oldHours object: %@", self.oldHours);

in the did select row at index method self.uploadedHours has a full value but in the prepare for segue method it does not therefore the oldhours item has no value as well. i dont get why it has no value though .

Stone Preston
Stone Preston
42,016 Points

post your code your didSelectRow at index and the code for prepareForSegue please

'''-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ PFObject *selectedHours = [self.uploads objectAtIndex:indexPath.row]; self.uploadedHours = selectedHours;

NSLog(@"hello object: %@", self.uploadedHours);

}

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"showDetails"]) {

    [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    NSLog(@"oldHours object: %@", self.uploadedHours);
    OldHoursViewController *oldHoursViewController = (OldHoursViewController *)segue.destinationViewController;
    oldHoursViewController.oldHours = self.uploadedHours;
    NSLog(@"yoohoo object: %@", oldHoursViewController.oldHours);
    

    } // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } '''

Stone Preston
Stone Preston
42,016 Points

are you modifying self.uploadedHours anywhere else in your code other than in didSelectRow and prepareForSegue? thats the only reason I can think of it would have a different value