RSS

Core Data Basics Part 6 – Core Data UIPickerView

26 Feb


Introduction

In previous tutorials I’ve shown how to use a UITableView to select from existing values stored in Core Data. The example project showed how to select what Role a Person is in.  This tutorial will cover how to use a UIPickerView for the same purpose.  I think the Picker looks cooler and is just as practical:

As usual I’m writing this tutorial without a clue in the world of how to do what I’m teaching.  Luckily for me there are other tutorial writers out there!  After a lot of research I found this great tutorial then expanded on it to use Core Data. I hope the results are useful to you.

Prerequisites

We follow on from Part 5, so download the project from the end of Part 5 then extract and open it with Xcode.

CoreDataTableViewCell Class

Typically you would display values in a TableViewCell found within a TableView.  To change a value you would tap the TableViewCell then expect something to let you change that cell value.  In order to make TableViewCell show a Core Data Picker I’ve created a base subclass called CoreDataTableViewCell.  To use CoreDataTableViewCell we need to subclass it again in order to customise what it fetches from Core Data.

Start off by downloading, extracting and dragging the two files from CoreDataTableViewCell.zip into your project. Next create a new class by clicking File > New > New File

Call the class RolePickerTVCell and make it a subclass of UITableViewCell:

Replace all the code in RolePickerTVCell.h with the code below.  Note that RolePickerTVCell inherits from CoreDataTableViewCell:

#import <UIKit/UIKit.h>
#import "CoreDataTableViewCell.h"
#import "Role.h"
 
@class RolePickerTVCell;
 
@protocol RolePickerTVCellDelegate 
- (void)roleWasSelectedOnPicker:(Role*)role;
@end
 
@interface RolePickerTVCell : CoreDataTableViewCell 
 
@property (nonatomic, weak) id <RolePickerTVCellDelegate> delegate;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) Role *selectedRole;
 
@end

Replace all the code in RolePickerTVCell.m with the following:

#import "RolePickerTVCell.h"
#import "AppDelegate.h"
 
@implementation RolePickerTVCell
@synthesize managedObjectContext = __managedObjectContext;
@synthesize selectedRole = _selectedRole;
@synthesize delegate;
 
- (void)setupFetchedResultsController
{
    // 0 - Ensure you have a MOC
    if (!self.managedObjectContext) {
        NSLog(@"RolePickerTVCell wasn't given a Managed Object Context ... so it's going to go get one itself!");
        AppDelegate *ad = [[UIApplication sharedApplication] delegate];
        self.managedObjectContext = ad.managedObjectContext;
    }
 
	// 1 - Decide what Entity you want
	NSString *entityName = @"Role"; // Put your entity name here
	NSLog(@"RolePickerTVCell is Setting up a Fetched Results Controller for the Entity named %@", entityName);
 
	// 2 - Request that Entity
	NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
 
	// 3 - Filter it if you want
	//request.predicate = [NSPredicate predicateWithFormat:@"Person.name = Blah"];
 
	// 4 - Sort it if you want
	request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
																					 ascending:YES
																					  selector:@selector(localizedCaseInsensitiveCompare:)]];
	// 5 - Fetch it
	self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
																		managedObjectContext:self.managedObjectContext
																		  sectionNameKeyPath:nil
																				   cacheName:nil];
	[self.fetchedResultsController performFetch:nil];
 
    NSLog(@"The following roles were fetched for the Picker by RolePickerTVCell:");
    for (Role *fetchedRole in [self.fetchedResultsController fetchedObjects]) {
        NSLog(@"Role: %@", fetchedRole.name);        
    }
}
 
- (void)initalizeInputView {
 
    // Prepare the Data for the Picker
    [self setupFetchedResultsController];
 
	self.picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
	self.picker.showsSelectionIndicator = YES;
	self.picker.autoresizingMask = UIViewAutoresizingFlexibleHeight;
 
	if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
		UIViewController *popoverContent = [[UIViewController alloc] init];
		popoverContent.view = self.picker;
		popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
		popoverController.delegate = self;
	}
}
 
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
 
		[self initalizeInputView];
 
        self.picker.delegate = self;
		self.picker.dataSource = self;
    }
    return self;
}
 
- (void)done:(id)sender {
 
    NSLog(@"Passing back the selected '%@' Role to the delegate", self.selectedRole.name);
    [self.delegate roleWasSelectedOnPicker:self.selectedRole];
    [self resignFirstResponder];
}
 
#pragma mark -
#pragma mark UIPickerViewDataSource
 
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
	return [[self.fetchedResultsController fetchedObjects] count];
}
 
#pragma mark -
#pragma mark UIPickerViewDelegate
 
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
 
    // Display the Roles we've fetched on the picker
    Role *role = [[self.fetchedResultsController fetchedObjects] objectAtIndex:row];
    return role.name;
}
 
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
    // Configure the row height
	return 44.0f;
}
 
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    // Configure the width of the picker wheel thing
	return 300.0f;
}
 
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
 
    Role *role = [[self.fetchedResultsController fetchedObjects] objectAtIndex:row];
    self.selectedRole = role;
    NSLog(@"The '%@' Role was selected using the picker", self.selectedRole.name); 
}
 
@end

RolePickerTVCell exists to help you select a role so a selectedRole property also exists for you to store a pointer to a role. The rest of the class methods have the following purposes:

  • setupFetchedResultsController is where you customise what you want to bring back to the Picker.
  • initalizeInputView calls setupFetchedResultsController then sets up some device specific settings for the picker.
  • initWithCoder is the first method called.  It simply calls initalizeInputView.
  • done is called when the done button on the picker is pressed.  This method passes the selectedRole to the delegate.
  • The remaining methods are there because RolePickerTVCell implements the UIPickerViewDataSource and UIPickerViewDelegate protocols.

Currently the Staff Manager app only lets you assign a role to a person via the Person Detail Table View.  For our example we will configure the Add Person Table View to use the picker for role selection. Click MainStoryboard.storyboard then select the Add Person Table View.  Edit the Add Person Table View as shown below, note that Table View Section – Role does not need a Text Field:

Select the Role Table View Cell on the Add Person Table View then set its Custom Class to RolePickerTVCell:

Run the app now and add a person with the ‘+’ button.  When you tap the Role cell the Core Data Role Picker should appear:

That’s almost great. If you tap done the role isn’t passed back to the Add Person Table View yet because AddPersonTVC isn’t a delegate of RolePickerTVCell.  You should be getting used to configuring delegates by now although they are a difficult concept to grasp sometimes.  Before we configure the delegate Control-drag a line from the Role Table View Cell to AddPersonTVC.h to create a new property called personRoleTVCell:

Now let’s set up the delegate.  Open up AddPersonTVC.h and add/edit the following lines of code:

#import "RolePickerTVCell.h"
@interface AddPersonTVC : UITableViewController <RolePickerTVCellDelegate>
@property (nonatomic, strong) Role *selectedRole;

Add the following to AddPersonTVC.m:

@synthesize selectedRole;
 
- (void)viewWillAppear:(BOOL)animated {
 
    personRoleTVCell.textLabel.text = @"";
    personRoleTVCell.delegate = self;
    personRoleTVCell.managedObjectContext = self.managedObjectContext;    
}
- (void)roleWasSelectedOnPicker:(Role *)role {
 
    self.selectedRole = role;
    personRoleTVCell.textLabel.text = self.selectedRole.name;
    NSLog(@"AddPersonTVC has set '%@' as the Selected Role", self.selectedRole.name);
}

Finally, add the following to the existing save method in AddPersonTVC.m just after person.surname = … :

person.inRole = selectedRole;

One thing I noticed is that the Person Detail Table View isn’t currently loading in the role associated with a person so edit the existing viewDidLoad method of the PersonDetailTVC to include these lines:

self.personRoleTableViewCell.textLabel.text = self.person.inRole.name;
self.selectedRole = self.person.inRole; // ensure null role doesn't get saved.

That’s it!  You should now be able to select a role for a new person using a picker!

Here’s the complete source code so far

If you liked this tutorial or found something wrong with it please let me know!

If you want to support my work and have an iPad please consider purchasing iSoccer *wink*

-Tim

Go to Part 7 or the Tutorials Index


Be Sociable, Share!
     

    About Tim Roadley

    I'm a senior analytics software consultant at eMite Pty Ltd primarily focused on delivering business intelligence dashboards, currently for one of Australia’s major banks. I'm also working on a revamped version of eMite's iOS App for release under iOS 7. Prior to eMite, I was Infrastructure Manager at Cuscal Pty Ltd where I was heavily involved in designing and implementing a payments switch that drives 1300+ ATM’s Australia wide. I have several apps on the App Store, including Teamwork, iSoccer and now Grocery Dude and Grocery Cloud. In my down time I enjoy spending time with my wonderful wife Tracey and two lovely children Tyler and Taliah.
    33 Comments

    Posted by on February 26, 2012 in iOS Tutorials

     

    33 Responses to Core Data Basics Part 6 – Core Data UIPickerView

    1. adrian phillips

      February 27, 2012 at 2:27 am

      the picker looks cool man. thanks for the tutorial. great job.

      adrian

       
    2. Paul

      April 7, 2012 at 4:56 am

      Your tutorials are great. I’ve been struggling with core data and these have helped a lot.

      I am having a problem with this part of the tutorial though:
      I keep getting a warning for the line in initWithCoder:
      self.picker.delegate = self;

      Passing ‘RolePickerTVCell *__strong’ to parameter of incompatible type ‘id’

      and another error for this line right below it:
      self.picker.dataSource = self;

      Passing ‘RolePickerTVCell *__strong’ to parameter of incompatible type ‘id’

      Ugh, just can’t figure it out. Many thanks if you have an idea as to why I’m getting the warnings.

      And since people are making suggestions I may as well add my two cents: It’d be great to see a tutorial where the Roles are grouped with the Name of the person associated with each. Just a suggestion. I’m going to forge ahead with the rest of your tutorial. Thanks again for doing these tutorials!

       
      • Tim Roadley

        April 8, 2012 at 8:05 am

        Hi Paul,

        Do you get this error with the source code provided at the end of the tutorial or in a adaptation of the code in a different project?

        Cheers

         
        • Paul G

          April 9, 2012 at 11:59 pm

          No, it was strictly within your tutorial. Not sure why. I took it to part 6(?) before adding the picker and search bar, implemented part 8 and it worked fine for me. :)

          My issue now is in trying to adapt it to my own project: In what would be the Roles View, I would like to select the row (with a check) to be used elsewhere in the app. But also I’d like to add a new Role or Edit the selected role. I see no other way to do that except by adding a toolbar at the bottom that has two buttons: add and edit which would segue accordingly over to the RoleDetail View. Trouble is I can’t add a toolbar in a table view controller, so I put a toolbar and a table view into a View Controller. I realize I can’t use CoreDataTableView Controller and I think I can get around that. But I’m still coming up with errors every single time I run it. Have you ever done anything similar?

           
      • Ben

        May 3, 2012 at 11:41 pm

        Hey Tim,

        Your tutorials are very instructive and easy to read. Thanks a lot.

        I think the cause of those 2 warnings is that the RolePickerTVCell.h needs to declare the UIPIckerViewDelegate and UIPickerViewDataSource.

        Ben

         
      • Jay

        September 28, 2012 at 2:46 am

        Awesome Tutorial.

        I also encountered the same error and in doing a code comparison between the downloaded project and what’s above there are a couple of differences.

        First Thing:

        In RolePickerTVCell.h it should read

        @protocol RolePickerTVCellDelegate

        and

        @interface RolePickerTVCell : CoreDataTableViewCell

        This is done to have this class conform to the DataSource and Delegate structures.

        Second thing:
        Click on the CoreDataTableViewCell.m file, and open the Utilities panel. Click on the File Inspector Icon and in the Target Membership section, Check the Checkbox beside the name of your project (probably Staff Manager).

         
    3. Tim Roadley

      April 10, 2012 at 6:50 am

      Paul,

      Instead of showing ticks for selection try just highlighting the cell to show selection. You need the disclosure indicator space for the edit segue:

      You can segue from a disclosure indication with this code:

      - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
      {
       
          RoleDetailTVC *roleDetailTVC = [self.storyboard instantiateViewControllerWithIdentifier:@"RoleDetailTVC"];
       
          // pass the selected role
          roleDetailTVC.role = [self.fetchedResultsController objectAtIndexPath:indexPath];
       
          // configure delegate so we can segue back
          roleDetailTVC.delegate = self;
       
          [self.navigationController pushViewController:roleDetailTVC animated:YES];
      }

      You will need to manually set the identifier of the roleDetailTVC in the storyboard:

      Cheers

      Tim.

       
      • Paul G

        April 10, 2012 at 1:11 pm

        I will try your suggestion Tim! You have been a bigger help to me than you realize, especially with me being a self-taught newbie to all this! THANKS!

         
      • Paul G

        April 11, 2012 at 12:15 am

        In my Roles view, I set my prototype cell’s Accessory and Editing Acc. to ‘Detail Disclosure’. But when I run the app and tap anywhere on the cell, it still segues to the RoleDetailTVC. I was thinking it would only segue when I tapped on the little blue detail disclosure indicator on the right of the cell, and I could just highlight the cell and not segue if I tapped anywhere else on the cell. Is my segue set up incorrectly? I don’t think it is. I’ve got my View Controller Identifier set up OK to RoleDetailTVC, but how does the it know to use the accessoryButtonTapped method you showed above? I can’t set the cell to use it, or does the compiler “just know” to use it?

         
    4. MIchael

      April 18, 2012 at 12:27 pm

      Could you do a tutorial on how to create a sectioned TableView with Core Data? You could maybe build off of this and divide up the TableView into sections based on the selected role, and the subtitle wouldn’t be necessary any more.

       
      • BSGraphic

        April 22, 2012 at 7:32 am

        Yes, TableView with Core Data (Xcode 4.3) tutorial that will be awesome!

         
      • Tim Roadley

        April 25, 2012 at 8:18 am

        At some point I will. I’ve only just learned how to do this. The technique is to populate separate arrays (per section) from a predicate filtered subset of the data that comes from the fetchedResultsController. Once you have those arrays you should use a switch statement to vary what goes into each section in the cellForRowAtIndexPath method. You also need that switch statement in the numberOfRowsInSection method. The numberOfSectionInTableView should return the number of arrays have.

         
    5. Kyle M

      May 9, 2012 at 1:12 pm

      Hi Tim,

      Great tutorial! Very detailed and is a huge help in learning :)

      One thing I noticed was that on the Role Picker, if you select the first role (with out scrolling), it wouldn’t take the role, just come back as null. To fix this I added the fetching to the initalizeInputView at the end but with an objectAtIndex:0 so it would pull the first item in the array:

      Role *role = [[self.fetchedResultsController fetchedObjects] objectAtIndex:0];
      self.selectedRole = role;

      Might want to add it in!

      Thanks again for sharing all your hard work!

       
    6. David

      June 19, 2012 at 1:15 am

      Hi,
      first of all congratulations for your tutorials.

      I made ​​this tutorial for IPad but I have a problem. I can not see the Done button. I see PickerView with the data but not the Done button.

      Do you have any idea?

      Thank’s a lot.

      David.

       
    7. Margreet

      June 30, 2012 at 2:01 am

      Hello, your tutorial is a great help for me, being completely ignorant on objective C. Thanks!!!!

      Now my problem.
      I’m struggling for a week now with the following:
      I want to make a list of all people with a specific role.
      I thought I could write something like this:

      //
      // PersonsTVC.m
      // Staff Manager
      //
      ALL YOUR CODE UNCHANGED AND THAN THIS:

      // 3 – Filter it if you want
      //request.predicate = [NSPredicate predicateWithFormat:@”Person.inRole” == Blah”];

      NO WAY, what is the correct way?

      And what if I want the role to be an input field like:
      //request.predicate = [NSPredicate predicateWithFormat:@”Person.inRole %@” == selectedinputfield”];

      Your help is really needed, I’m really stuck for a week.

      Thanks, Margreet

       
    8. Margreet

      July 2, 2012 at 6:15 pm

      ok, I found the right statement:

      request.predicate = [NSPredicate predicateWithFormat:@”ANY inRole.name == ‘Java Developer'”];

       
    9. Margreet

      July 7, 2012 at 4:39 am

      Now for something completely different: I have an entity: MOVE, it has 2 attributes: FROM and TO. I want to make a list of all moves until one is back to the starting point (endstation == starting point (New York)) OR if no new move is found ( Paris London, if they hadn’t moved to New York after that)

      Like this:
      From                     To
      New York                Washington
      Washington             Paris
      Paris                       London
      London                    New York
       
      .
      They adviced me to use recursion. Since I’m new in all this, could somebody indicate how to write the code?
      Thanks!!!!!!!!

       
    10. James

      July 11, 2012 at 3:47 am

      Have you tried this on a device? The docs for UIPopoverController state “Popover controllers are for use exclusively on iPad devices. Attempting to create one on other devices results in an exception.”

      – James

       
      • James

        July 11, 2012 at 4:01 am

        Ah nvm. I see its only being used for iPad

         
    11. Ken Davis

      August 24, 2012 at 7:33 am

      I really appreciate this tutorial, but when I use this code example in a project it runs quite well except the addition of this object instead of a regular tableviewcell causes the keyboard to cover up any cells below the UIPicker section.

      Any ideas as to a code block to correct the scroll problem?

       
      • Ken Davis

        August 25, 2012 at 2:51 am

        Let me explain this better:
        Using your code from this part6:
        1. open storyboard for AddPersonTVC
        2. click drag the Role section to be at the top
        3. Run app in simulator
        4. picker works fine
        5. click on Surname and keyboard covers the textfield

        any Ideas how to make the textfield scroll up to be above the keyboard?

         
        • Ken Davis

          August 26, 2012 at 2:06 pm

          Tim:
          Thank you for sending me to this page. It was full of different ideas about recalculating the view or the frame usually in the context of a ‘view’ not a ‘tableview’.

          I spent the better part of the day testing all of the various solutions presented to find them all overly complex or non-functional.

          However, the solution was near the bottom in a very brief comment.

          You can use your PickerView or any other custom object that will work in a table cell and put it in a section anywhere in a TableView. However, because of it’s presence, after the view is loaded and some object becomes the first responder, as your code was written, caused an issue with fields being covered by the keyboard. That normally should not happen as the UITableViewController should bring the textfield into the view just above the keyboard without any coding.

          The solution was simple. Because the picker code used the ‘viewWillAppear’ code block to set and return delegate matters, all that was needed was to add two lines of code to the ‘viewWillAppear’

          //add the following line to fix keyboard issue

          [super viewWillAppear:animated];

          [self.tableView reloadData];

          Problem solved: Now the UITableViewController method code works as expected.

          Again, thank you for your tutorial and the rapid response to my comments.

           
    12. Autumn

      September 30, 2012 at 1:40 am

      Thank you so much for this (and all of your) tutorials!!

      I was wondering if you can use code similar to this to get the UIDatePicker to appear. So that the user can select a date and have it appear in the cell.

       
    13. Jay

      October 2, 2012 at 5:56 am

      There is one issue with the Role Picker: UIPickerView has a ‘feature’ whereas it will not select (pick) something unless you scroll the picker first. In other words, if you tap row 0 (the default row in this case) and click Save, nil is returned. If the picker is scrolled and then moved back to row 0 and tapped, it returns the proper information.

       
      • Jay

        October 2, 2012 at 6:59 am

        Here’s one solution..

        In RolePickerTVCell.m code the done: method to look like this

        //clicked the done button
        – (void)done:(id)sender {

        if ( self.selectedRole == nil ) { //if self.selectedRole is nil then it means nothing was tapped, i.e. row 0
        Role *role = [[self.fetchedResultsController fetchedObjects] objectAtIndex:0];
        self.selectedRole = role;
        }

        [self.delegate roleWasSelectedOnPicker:self.selectedRole];
        [self resignFirstResponder];

        NSLog(@” done: Passing back the selected ‘%@’ Role to the delegate”, self.selectedRole.name);
        }

        However a better solution would be to have a default row 0 of ‘None’ which will then allow the user to scroll to select the role, or optionally select None.

         
    14. carrie

      October 18, 2012 at 11:42 pm

      This is a great example, but I’d like to have a form which has this picker only when in edit mode. I know the method to call for editing, but how can I change the enabled/disabled state of this picker, i.e. turn off the click event when not in editing mode?

      Thanks in advance

       
    15. Franz

      October 26, 2012 at 4:50 am

      Hi,
      the tutorial is really great. It helps to get things done although I don’t really understand what I am doing.
      I have setup my app so that the picker is shown on the PersonDetail view. It works well, but when activating the picker it always starts at row 0.
      Ideally, for an existing person with a selected role, the picker should directly jump to the corresponding row and show it.
      I was able to add some code to determine which row it should display. But I am stuck at how to actually tell the picker to jump to the desired row. In the developer’s doc, there is a method: selectRow:inComponent:animated: but I am not able to use it. Does not seem to work for CoredataTableViewCell. Who can help?

      thanks a lot
      Franz

       
    16. David

      August 23, 2013 at 12:31 am

      Hi Tim,

      First of all Great Tutorials. very easy to understand.

      I am having problems with the Picker though in iPad. Everything works in the iPhone storyboard but when I put it into the iPad storyboard I do not get the “Done” button for the iPad. Can you explain how I go about the change please?

      Thanks

       
    17. Paula

      November 13, 2013 at 1:55 am

      Hi,

      I downloaded the file Staff Manager – After Part6.zip, but when I run it crashes when I add a person.
      Here’s the log:
      2013-11-12 15:45:45.806 Staff Manager[2867:70b] Setting up a Fetched Results Controller for the Entity named Role
      2013-11-12 15:45:45.854 Staff Manager[2867:70b] !!!!! ~~> There’s nothing in the database so defaults will be inserted
      2013-11-12 15:45:45.855 Staff Manager[2867:70b] Importing Core Data Default Values for Roles…
      2013-11-12 15:45:45.871 Staff Manager[2867:70b] Importing Core Data Default Values for Roles Completed!
      2013-11-12 15:45:45.887 Staff Manager[2867:70b] Setting up a Fetched Results Controller for the Entity named Person
      2013-11-12 15:45:56.428 Staff Manager[2867:70b] Setting up a Fetched Results Controller for the Entity named Role
      2013-11-12 15:45:57.763 Staff Manager[2867:70b] Setting up a Fetched Results Controller for the Entity named Person
      2013-11-12 15:45:59.392 Staff Manager[2867:70b] Setting PersonsTVC as a delegate of AddPersonsTVC
      2013-11-12 15:45:59.398 Staff Manager[2867:70b] RolePickerTVCell wasn’t given a Managed Object Context … so it’s going to go get one itself!
      2013-11-12 15:45:59.400 Staff Manager[2867:70b] RolePickerTVCell is Setting up a Fetched Results Controller for the Entity named Role
      2013-11-12 15:45:59.403 Staff Manager[2867:70b] The following roles were fetched for the Picker by RolePickerTVCell:
      2013-11-12 15:45:59.404 Staff Manager[2867:70b] Role: ASP.NET Developer
      2013-11-12 15:45:59.405 Staff Manager[2867:70b] Role: Business Analyst
      2013-11-12 15:45:59.409 Staff Manager[2867:70b] Role: C/C++ Developer
      2013-11-12 15:45:59.410 Staff Manager[2867:70b] Role: Chief Information Officer
      2013-11-12 15:45:59.411 Staff Manager[2867:70b] Role: Desktop Support Analyst
      2013-11-12 15:45:59.412 Staff Manager[2867:70b] Role: Infrastructure Manager
      2013-11-12 15:45:59.413 Staff Manager[2867:70b] Role: Java Developer
      2013-11-12 15:45:59.413 Staff Manager[2867:70b] Role: Obj-C Developer
      2013-11-12 15:45:59.414 Staff Manager[2867:70b] Role: Operations Manager
      2013-11-12 15:45:59.414 Staff Manager[2867:70b] Role: Project Manager
      2013-11-12 15:45:59.415 Staff Manager[2867:70b] Role: Unix Engineer
      2013-11-12 15:45:59.415 Staff Manager[2867:70b] Role: Windows Engineer

      2013-11-12 15:49:47.787 Staff Manager[2867:70b] *** Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key personRoleTVCell.’
      *** First throw call stack:
      (
      0 CoreFoundation 0x01ab85e4 __exceptionPreprocess + 180
      1 libobjc.A.dylib 0x0183b8b6 objc_exception_throw + 44
      2 CoreFoundation 0x01b486a1 -[NSException raise] + 17
      3 Foundation 0x012ef9ee -[NSObject(NSKeyValueCoding) setValue:forUndefinedKey:] + 282
      4 Foundation 0x0125bcfb _NSSetUsingKeyValueSetter + 88
      5 Foundation 0x0125b253 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 267
      6 Foundation 0x012bd70a -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 412
      7 UIKit 0x0063ea15 -[UIRuntimeOutletConnection connect] + 106
      8 libobjc.A.dylib 0x0184d7d2 -[NSObject performSelector:] + 62
      9 CoreFoundation 0x01ab3b6a -[NSArray makeObjectsPerformSelector:] + 314
      10 UIKit 0x0063d56e -[UINib instantiateWithOwner:options:] + 1417
      11 UIKit 0x004af605 -[UIViewController _loadViewFromNibNamed:bundle:] + 280
      12 UIKit 0x004afdad -[UIViewController loadView] + 302
      13 UIKit 0x0065811e -[UITableViewController loadView] + 80
      14 UIKit 0x004b00ae -[UIViewController loadViewIfRequired] + 78
      15 UIKit 0x004b05b4 -[UIViewController view] + 35
      16 UIKit 0x004ca3e2 -[UINavigationController _startCustomTransition:] + 778
      17 UIKit 0x004d70c7 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
      18 UIKit 0x004d7cb9 -[UINavigationController __viewWillLayoutSubviews] + 57
      19 UIKit 0x00611181 -[UILayoutContainerView layoutSubviews] + 213
      20 UIKit 0x00407267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
      21 libobjc.A.dylib 0x0184d81f -[NSObject performSelector:withObject:] + 70
      22 QuartzCore 0x045982ea -[CALayer layoutSublayers] + 148
      23 QuartzCore 0x0458c0d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
      24 QuartzCore 0x0458bf40 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
      25 QuartzCore 0x044f3ae6 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
      26 QuartzCore 0x044f4e71 _ZN2CA11Transaction6commitEv + 393
      27 QuartzCore 0x044f5544 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
      28 CoreFoundation 0x01a804ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
      29 CoreFoundation 0x01a8041f __CFRunLoopDoObservers + 399
      30 CoreFoundation 0x01a5e344 __CFRunLoopRun + 1076
      31 CoreFoundation 0x01a5dac3 CFRunLoopRunSpecific + 467
      32 CoreFoundation 0x01a5d8db CFRunLoopRunInMode + 123
      33 GraphicsServices 0x02ea89e2 GSEventRunModal + 192
      34 GraphicsServices 0x02ea8809 GSEventRun + 104
      35 UIKit 0x0039cd3b UIApplicationMain + 1225
      36 Staff Manager 0x00001d4d main + 141
      37 Staff Manager 0x00001cb5 start + 53
      )
      libc++abi.dylib: terminating with uncaught exception of type NSException

      I’m working with xcode 5.0.1 and running on Simulator -> iPhone Retina (3.5-inch)

      Thanks

       
    18. doge

      December 26, 2013 at 7:26 am

      Wow, thanks for this amazing tutorial! What should I do when I want “interactive” search results, so I get into the corresponding “Role Detail View” when I click on them?

       

    Leave a Reply