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
Wayne Patnode
1,227 PointsHow do you fetch core data entity attribute key values in a prepareForSegue method?
I had originally posed this question to StackOverflow, so I'll try to summarize where I am at with it currently...
I am trying to pass existing entity attribute values for a managed object to a modal segue view's fields, for editing.
My TableViewCells have two segues from them: one for a detail view, and another for an editing view. There's a UIToolBarButtonItem to toggle editing in the navigation bar. From "editing mode," I'm going from a UITableViewController subclass (BreadRackTableViewController), using a modal segue to a UIViewController subclass (EditBreadRackTableViewController) by means of an embedded UINavigationController. Normal TableViewCell selection pushes to another UITableViewController subclass for detail view, but that's not important for the time being.
I did try to put this into my didSelectRowAtIndexPath method, but it corrupted my navigation bar's functionality. I am assuming it did that because I have multiple segues branching from the same row. Selecting a normal row, and selecting a row with an editing accessory present must be two different events.
I've added properties to my editing view controller header file (and @synthesized in my implementation file), to function as getters. I've also tried to set these properties as id types too, and just assigning their description to the target fields. For the most part, this process is working to assign values:
@property (nonatomic, strong) NSString *existingBreadRackDataName;
@property (nonatomic, strong) NSString *existingBreadRackDataDetails;
What I'm trying to do is populate the edit view's fields with the existing Core Data Entity Attribute values, which would have been previously set by the user (in theory). The edit view has a UITextView and a UITextField object that I need to populate values for. The entity attributes are already of the String type in my data model too. I can get the data to show up if I pass along a literal string value, but I need to retrieve and pass the existing data.
Here's what I have currently:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"editBreadRackSegue"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
BreadRackClass *breadRackClass = [[self fetchedResultsController]objectAtIndexPath:indexPath];
[segue.destinationViewController setExistingBreadRackDataName:[breadRackClass valueForKey:@"breadRackDataName"]];
[segue.destinationViewController setExistingBreadRackDataDetails:[breadRackClass valueForKey:@"breadRackDataDetails"]];
NSLog(@"Sent Name: %@", [breadRackClass valueForKey:@"breadRackDataName"]);
NSLog(@"Sent Name: %@", breadRackClass.breadRackDataName);
}
// another if statement for an addButton segue here...
}
These last two lines of code...
[segue.destinationViewController setExistingBreadRackDataName:[breadRackClass valueForKey:@"breadRackDataName"]];
[segue.destinationViewController setExistingBreadRackDataDetails:[breadRackClass valueForKey:@"breadRackDataDetails"]];
...they both return nil. If I specify a literal string though, that literal string passes through to where it needs to by doing this:
[segue.destinationViewController setExistingBreadRackDataName:@"test string"];
But, of course I don't want it to be a static value. I would prefer it to populate the existing entity attribute key value, so the user can see what's currently there since their screen changes. When I launch the app and perform the editBreadRackSegue, the NSLog returns "Sent Name: (null)" every time.
I did follow Amit's instructions in the Core Data videos, too, to verify that data actually exists in my *.sqlite file.
I also tried to put this into my prepareForSegue, thinking I could create some reference to just the selected cell's properties rather than the passed Core Data:
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[sender indexPathForSelectedRow]];
But when I tried to test it, with this simple log:
NSLog(@"Sent Name: %@", cell.textLabel.text);
...the thing threw an error at me:
-[UITableViewCell indexPathForSelectedRow]: unrecognized selector sent to instance
I was trying to reference the cell's text labels since they're already being populated properly when they're drawn by my BreadRackTableViewController implementation. I'm do feel that this method is not quite the wisest approach, but I was mostly just tinkering with code to see if I could get it to work that way.
In the end though, I'd still like to reference the entity attributes for the row doing the segue and at least be able to send the values successfully to a NSLog.
5 Answers
Nick Pettit
Treehouse TeacherHey Wayne,
I notified Amit about this thread, so he should be able to respond shortly. :)
Nick
Amit Bijlani
Treehouse Guest TeacherHey Wayne, could you share your latest project file? Hard to tell what could be going on with just the snippets of code. You can share it here or just email it to me.
Wayne Patnode
1,227 PointsSure thing, I'll send it via email. Thank you, Amit, again!
And thanks, Nick, as well!
Wayne Patnode
1,227 PointsAmit, to the rescue!
As per his suggestion, I've replaced only one line of code from what is listed in the original post. Turns out, I was referencing the row in the table rather than the specific cell for the row in that table. D'oh!
Here's the end result:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"editBreadRackSegue"])
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
BreadRackClass *breadRackClass = [[self fetchedResultsController]objectAtIndexPath:indexPath];
[segue.destinationViewController setExistingBreadRackDataName:[breadRackClass valueForKey:@"breadRackDataName"]];
[segue.destinationViewController setExistingBreadRackDataDetails:[breadRackClass valueForKey:@"breadRackDataDetails"]];
}
// other segue code here...
}
The culprit was:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
...which I've changed to:
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
I have spent HOURS looking for answers to a missing identifier in my code related to prepareForSegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
I'll try your fix, but I am wondering if it is an iOS 6 simulator problem?