2

I am working on my first app and am in need of some assistance. I've read through tons of similar questions on SO but just not getting anywhere.

I have a simple table view controller which has a plus button; when pressed, that leads to a modal view controller asking the user to insert information into 4 separate fields. When the user clicks save, the modal view dismisses and the information is displayed in the table view because the save button calls the NSManagedObject subclasses and through Core Data, it saves it.

I'm trying to have it so that when a user types into the first field (name), if they have already typed that name before (if they added it to Core Data with the save method), it auto-populates and shows a hidden table view with entries matching that name. I first started working with a NSMutableArray but thanks to Jeff's comments, that would not persistently keep the data, so because I already have the Core Data functionality, it makes more sense to use that. I am editing this post to include how my Core Data is currently set up.

I basically want to achieve this but with Core Data (http://www.dalmob.org/2011/03/01/alternative-autocomplete-uitextfield/)

There is a Information Entity with a relationship to the People Entity.

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Information *information = [NSEntityDescription insertNewObjectForEntityForName:@"Information" inManagedObjectContext:context];

    People *enteredPerson = (People *)[People personWithName:self.nameTextField.text inManagedObjectContext:context];
    information.whichPerson = enteredPerson;
    NSError *error = nil;
    if (![context save:&error])
    {
        NSLog(@"Can't save! %@ %@", error, [error localizedDescription]);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

The enteredPerson calls the personWithName method in the People NSManagedObjectSubclass:

+ (People *)personWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
{
    People *people = nil;

    // Creating a fetch request to check whether the name of the person already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    request.predicate = [NSPredicate predicateWithFormat:@"name = %@", name];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *fetchedPeople = [context executeFetchRequest:request error:&error];
    if (!fetchedPeople)
    {
        // Handle Error
    }
    else if (![fetchedPeople count])
    {
        // If the person count is 0 then let's create it
        people = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:context];
        people.name = name;
    }
    else
    {
        // If the object exists, just return the last object .
        people = [fetchedPeople lastObject];
    }
    return people; 
}

Based on the suggestion to create the NSFetchRequest, I am wondering the best technique to do this.

Do I do this in the Save method of the Add Entry at the end to something like this:

// NSFetchRequest

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
[fetchRequest setEntity:entity];

// Specifiy a predicate here if there are certain conditions your fetch must adhere to
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY name CONTAINS[c] %@", self.nameTextField.text];
[fetchRequest setPredicate:predicate];

//NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
    // Handle error
}
if ([fetchedObjects count] == 0)
{
    // Add entry to results
}

What I want to achieve is, from Core Data, when the user types in the name, reference core data (with a fetch request) and if that name exists, as the user starts typing, populate the Table view that sits below the Text field.

Any guidance would be appreciated.

EDIT: I have updated an answer with some further code to almost get this working.

EDIT: More Code:

Property Declarations in .h

@property (retain, nonatomic) IBOutlet UITextField *nameTextField;
@property (nonatomic, retain) NSString *substring;
@property (weak, nonatomic) IBOutlet UITableView *testTableView;
@property (nonatomic, retain) NSFetchedResultsController* autocompleteFetchedResultsController;

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring;

ViewDidLoad

- (void)viewDidLoad
{
    NSError *error;
    if (![[self autocompleteFetchedResultsController] performFetch:&error])
    {
        NSLog(@"Unresolved error %@ %@", error, [error userInfo]);
        exit(-1);
    }
    self.testTableView.delegate = self;
    self.testTableView.dataSource = self;
    self.testTableView.hidden = YES;
    self.testTableView.scrollEnabled = YES;
    self.nameTextField.delegate = self;
    [super viewDidLoad];
}

Save Method

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];    
    People *enteredPerson = (People *)[People personWithName:self.nameTextField.text inManagedObjectContext:context];
    transaction.whoFrom = enteredPerson;
    NSError *error = nil;
    if (![context save:&error])
    {
        NSLog(@"Can't save! %@ %@", error, [error localizedDescription]);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

Thanks,

amitsbajaj
  • 1,304
  • 1
  • 24
  • 59
  • You need to use a persistent store of information, as soon as your NSMutableArray goes out of scope it will lose all of it's information. Take a look at NSUserDefaults or CoreData to persist your data. – Tim Nov 25 '13 at 10:39
  • Thank you @Jeff for the reply - that is helpful. I am actually using Core Data for the entire app so far, so when a user adds in the "NameTextField", it actually gets saved to Core Data. With using Core Data in mind, how can I, instead of using a MutableArray, go ahead and reference the Core Data information to fill in the Table view, based on what the user is typing? Thanks! – amitsbajaj Nov 25 '13 at 10:40
  • You will need to perform a Core Data Fetch Request on your managed object context, to retrieve an array of NameTextField entries that you can then populate into the array each time you load the screen. – Tim Nov 25 '13 at 10:56
  • I've added some code to an answer, hopefully this helps. – Tim Nov 25 '13 at 11:00
  • Thank you very much Jeff - this makes very good sense with the code you've provided - I will work through that now - this will keep me occupied for a while and I'll keep you posted on the progress! Thanks again – amitsbajaj Nov 25 '13 at 11:07
  • I'm a bit lost @Jeff - I had updated my question which includes the Core Data checking I'm already doing for adding entries into the Database (it works well now by not adding duplicate entries), but I want to adapt this to fit in with the original question - when the user is adding the "Name" text field, for Core Data to be fetched to see if that name exists, if it does, display it in the table view below the text field, and if it does not, do nothing (because the Core data is already adding that code).. sorry! – amitsbajaj Nov 25 '13 at 11:43

3 Answers3

0

Using the basic code from the Xcode library of snippets you can perform a Core Data fetch:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>" inManagedObjectContext:<#context#>];
[fetchRequest setEntity:entity];

// Specifiy a predicate here if there are certain conditions your fetch must adhere to
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"<#Predicate string#>", <#Predicate arguments#>];
[fetchRequest setPredicate:predicate];

NSError *error = nil;
NSArray *fetchedObjects = [<#context#> executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
    // Handle error
}

Replace the Entity name with the one that stores your NameTextField entries. And fetchedObjects is an array that will store your information you need to populate your table with.

Obviously, you will also need to save any new NameTextField entries to core data by creating a new entity and saving the context.

Tim
  • 8,932
  • 4
  • 43
  • 64
0

I have sort of got this working. Rather than update the entire question, I have left that there for reference because I am sure someone will come across a similar situation. Through the use of a FetchedResultsController object within my view controller, I'm now getting a list of names to populate the table view that sits below the text field.

Let's look at some code:

- (NSFetchedResultsController *)autocompleteFetchedResultsController
{
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    if (_autocompleteFetchedResultsController != nil)
    {
        return _autocompleteFetchedResultsController;
    }
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"People" inManagedObjectContext:managedObjectContext];
    fetchRequest.entity = entity;

    if ([self.substring length] > 0) {
        NSPredicate *peoplePredicate = [NSPredicate predicateWithFormat:@"ANY name CONTAINS[c] %@", self.nameTextField.text];

        [fetchRequest setPredicate:personPredicate];
    }

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    self.autocompleteFetchedResultsController = theFetchedResultsController;    _autocompleteFetchedResultsController.delegate = self;
    return _autocompleteFetchedResultsController;
}

- (void)viewDidLoad
{

    NSError *error;
    // I am performing the fetchHere and if there is an error, it will get logged.
    if (![[self autocompleteFetchedResultsController] performFetch:&error])
    {
        NSLog(@"Unresolved error %@ %@", error, [error userInfo]);
        exit(-1);
    }

    // Further code relating to tableview to make it hidden, etc
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id  sectionInfo = [[_autocompleteFetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    self.testTableView.hidden = NO;
    self.substring = self.nameTextField.text];
    self.substring = [self.substring stringByReplacingCharactersInRange:range withString:self.substring];
    [self searchAutocompleteEntriesWithSubstring:self.substring];
    return YES;
}

#pragma mark UITableViewDataSource methods


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"autocomplete cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    People *people = [self.autocompleteFetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = people.name;
    return cell;
}

#pragma mark UITableViewDelegate methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    self.nameTextField.text = selectedCell.textLabel.text;

}

So this works to some extent. When I place the cursor in the nameTextField, it unhides the table view, but it currently shows me the name of ALL the names already entered.

What I want is the ability to, as I'm typing, for the table to only show me what matches that.

The [self searchAutocompleteEntriesWithSubstring:substring]; in the shouldChangeCharactersInRangeMethod is calling a custom method I created.

When I had this set to a NSMutableArray instead of using Core Data, it was the code below, but I have no idea how to adjust this code to say, search core data and only display the results that match what I am already typing.

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {

        self.autocompleteFetchedResultsController = nil;
        [self autocompleteFetchedResultsController];
        [self.testTableView reloadData];
}

I'm almost there - just need a bit of a push to get there!

amitsbajaj
  • 1,304
  • 1
  • 24
  • 59
  • I have not read this whole post in detail but are you aware that the searchBar and searchBarController will effectively do this filtering of what appears in a tableView for you based on what has been entered in the searchBar so far. – Duncan Groenewald Nov 25 '13 at 20:58
  • If you investigate how the searchBarController integrates with a fetchedResultsController to perform Core Data searches in response to the user entering data you could adopt the same approach. – Duncan Groenewald Nov 25 '13 at 21:07
  • Thanks @DuncanGroenewald - That's very interesting.. the problem is.. I have many text fields n this view controller.. along with a date picker, etc.. I'm just trying to get the auto-populating for the text field - if I were to use a search bar, would I get the same behaviour with what the textfield is doing now? (adding names, saving to core data, etc).. I feel I'm so close to getting this working that I'd love to just work on this – amitsbajaj Nov 25 '13 at 21:07
  • You would still use your text field, just use the same approach to set up the predicate and use fetchedResultsController to get the filtered list from Core Data to offer up as options that match. – Duncan Groenewald Nov 25 '13 at 21:12
  • Thanks @DuncanGroenewald - that does make sense - I almost think I'm doing something very similar (with my answer further down) but it's just not seeming to work at all - I will look into this now - – amitsbajaj Nov 25 '13 at 21:19
0

I guess self.autocompleteUrls is the NSMutableArray u had previously... Ok, U have come a long way, now see the autocompleteFetchedResultsController -> that is what fetches, and the condition if (_autocompleteFetchedResultsController != nil) protects property method from being called every time U reference autocompleteFetchedResultsController. So U should do something like this:

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
    _autocompleteFetchedResultsController = nil;
    [self autocompleteFetchedResultsController];
    [self.testTableView reloadData];
}

and If U done everything else correctly that should be it...

Your cellFoRowAtIndexPath should look like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"autocomplete cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier];
    }

    People *people = [self.autocompleteFetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = people.name;
    return cell;
}
AntonijoDev
  • 1,317
  • 14
  • 29
  • Thank you! That is very helpful! Having just tried that code (copied and pasted), it unfortunately didn't work, but it gave me strange results. With that code in and my code out, when I type in the text field, it didn't show up any results. I put my code back (although it's still referencing the Array which I'm not using but have not removed from the code), when I start typing.. it shows me ALL the values in the "person.name" rather than just the one's I'm typing.. I want to have it so that, as I type, it's searching through and finding matches and filtering more matches with more characters – amitsbajaj Nov 25 '13 at 15:56
  • put the breakpoint in autocompleteFetchedResultsController after if(_autocompleteFetchedResultsController != nil){}, does it hit the breakpoint for every letter that U type in the text field? – AntonijoDev Nov 25 '13 at 16:01
  • Thanks! With a breakpoint at that if statement, it hits it when the view controller is loaded (makes sense) but it evaluates to false so it doesn't return _autocompleteFetchedResultsController and then with every character I typed (typed in John), it hit that if statement (evaluated as false of course) and went on in the fetchedResults - it hit the if statement for the predicates and set that too.. I see the Table view, just don't see the word "John" auto populated in that under the text view.. I feel we're almost there! – amitsbajaj Nov 25 '13 at 16:13
  • I meant that U put it after the whole statement, say on if ([self.nameTextField.text length] > 0) line, then U follow the course and see if the predicate is being created with the letters and so on... U get all results because the first time U go in the autocompleteFetchedResultsController method U dont – AntonijoDev Nov 25 '13 at 16:54
  • have anything in your text box, and the predicate doesn't get created, and the next time U don't pass the condition at the entrance of the method, thats why U have to use my code cause it sets _autocompleteFetchedResultsController to nil what allows you to pass the precondition... – AntonijoDev Nov 25 '13 at 16:56
  • oh sorry, now I get it. I ran the breakpoint against the if ([self.nameTextField.text length] >0) and as expected, before I even start typing, the predicate line does not get called (that if statement is false), but strangely, when I type the first letter (any letter), it also fails that if statement and so does not run the predicate. It is only when I type the second character onwards that it starts evaluating as true and the predicate gets created.. why would it skip the first typed letter? – amitsbajaj Nov 25 '13 at 17:47
  • Ok, we have a bug, U create a sub string and we never use it, create an instance variable in your .h and call it substring (or smth), replace the one u have in shouldChangeChara... with this one, then use it in autocompleteFetchedResultsController instead of self.nameTextField.text and that is it... – AntonijoDev Nov 25 '13 at 20:09
  • Great catch there - I think we're real close - it's not populating the table still though with these changes - self.substring is now in the if statement with the length.. I've updated my answer to reflect the new code but the outcome is unfortunately the same - the table is not populating and with a breakpoint on the if statement, it's still not going into the predicate with the first typed letter.. sorry to keep dragging this one on! – amitsbajaj Nov 25 '13 at 20:37
  • Hi there - do you have any further ideas with this? I'm so keen to get this sorted.. your thoughts would really be appreciated! – amitsbajaj Nov 26 '13 at 07:31
  • Ok U need to see what is happening, cause this is it. put a breakpoint in shouldChangeCharactersInRange and see what happens the first time U type a letter, NSLog the self.substring after U set it. And I see that u still have your old code in searchAutocompleteEntriesWithSubstring, U need to change it, just copy paste the code I have written in the answer, cause without it this just wont work, your fetch wont pass the initial condition... – AntonijoDev Nov 26 '13 at 08:06
  • Thanks - sorry forgot to update my code in the question here but in the searchAutocompleteEntries, I'm using your code. In the predicate, should it be self.substring, or self.nameTextField.text? Also in the predicateWithFormat, should it be self.substring or self.nameTextField.text? I'm running the break points now to see what's going on - will update shortly - thanks again – amitsbajaj Nov 26 '13 at 08:26
  • Thanks - so just tried that with the breakpoint in the shouldChangeCharactersInRange method. I added in the letter a into the text field, it fired the breakpoint and with a NSLog after setting the self.substring (2 lines), it recognised the entered character of self.substring is a. The call then fired off the searchAutoCompleteEntries method where self.substring still equals the letter a. With your code, that set autocompleteFetchedResultsController to nil and it fired off that method. It skipped the first if statement because we set it to nil. It went through the FetchRequest and it hit – amitsbajaj Nov 26 '13 at 08:39
  • the if ([self.substring length] > 0) statement and evaluated as TRUE because there was one character. It ran the predicate set to @"ANY name CONTAINS[c] %@", self.substring and went through the rest of the autocompleteFetchResultsController method just fine with the descriptor, etc. It then returned back to the searchAutocomplete method, reloaded the table and returned back to the shouldChangeCharacters - but the actual table view in the app was not getting updated with results - it was no results at all.. do you think there's anything to do with the way the properties are declared, etc? – amitsbajaj Nov 26 '13 at 08:42
  • because it's hitting the predicate but it's not "filtering" out any information in the table - in fact, it's not displaying anything in the table. – amitsbajaj Nov 26 '13 at 08:42
  • Ok put the breakpoint in cellforrowAtIndexpath... does it ever get hit?? – AntonijoDev Nov 26 '13 at 08:49
  • With a breakpoint in cellForRow, it hits when I first enter the view controller - it goes to the autocompleteFetchedResultsController and the if (_autocompleteFetchedResultsController != nil) evaluates as true and then it returns _autocompleteFetchedResultsController - it does not get called when I am typing in the text field.. which sounds like part of the problem here! So it's only being called when I first access this view controller but not when I'm typing in the text field. interestingly - in the searchAutocomplete method, if I comment out the self.autocompleteFetchedResultsController – amitsbajaj Nov 26 '13 at 09:02
  • = nil - if I comment that out, when I start typing in the text field, ALL results are displayed in the cellForRow - which makes sense because the predicate is being run, but it does look like it's correctly called - just when I leave that setting to nil as per your code, the cellForRow does not get called when I start typing, just when I enter the view controller – amitsbajaj Nov 26 '13 at 09:03
  • No it will show all the results cause when U entered for the first time U didn't have the predicate so the method returned all results from database, if U comment the line in question than the fetch wont do anything it will return as soon as it enters the method and U will always see the results from the first fetch. So the line stays cause it needs to be there, u have some other problem... Return the line and put the breakpoint on fetchRequest.sortDescriptors... line. Then NSLog the predicate after each letter U type in. – AntonijoDev Nov 26 '13 at 09:13
  • With a breakpoint on the sortDescriptor, it gets called when I get to this view controller (makes sense) and when I enter the first letter, a NSLog inside the predicate if statement indicates that the entered character is the one I entered. The sortDescriptors has one object after the code passes through it. When I enter the second letter, the predicate's NSLog shows the first and second letter. The sort descriptor is nil before it is run and when that line is run, it has one object again. This cycle continues. I hope this makes sense? – amitsbajaj Nov 26 '13 at 09:47
  • Ok, put this line after setting sort descriptor: NSError *error; NSArray *tmp = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; and NSLog tmp and error after this line executes, just to see if u are fetching this right... – AntonijoDev Nov 26 '13 at 09:54
  • Thanks - with the NSLog(@"Temp = %@ and error = %@", tmp, error), I am getting the following output: Temp = ( " (entity: People; id: 0x8b0d590 ; data: )", " (entity: People; id: 0x8b3c980 ; data: )"," (entity: People; id: 0xdc262d0 ; data: {\n name = Jack;\n transactions = \"\";\n})", – amitsbajaj Nov 26 '13 at 10:03
  • and lots of other similar statements - does that make sense? I'm not sure if that is what I'm supposed to see.. and error = (null) – amitsbajaj Nov 26 '13 at 10:03
  • Thats great, those are your managed objects (People records), now U make sure that U get the similar log while typing letters, maybe U are typing something U don't have in your database, so always test with first couple of letters U know U have in database. OK I have just observed that u have peoplePredicate and personPredicate it should be [fetchRequest setPredicate:peoplePredicate]; cause that is the one u set for each letter... – AntonijoDev Nov 26 '13 at 10:36
  • That makes sense! With that in mind, I ran a test and the NSLog output for Temp was interesting. I have 3 People (Jilly, Jain, Jack) in the App and if I type J in the Text field the output shows Jilly, Jain, Jack - Temp = ( " (entity: People; id: 0x8a2ab70 ; data: {\n name = Jilly;\n transactions = \"\";\n})", " (entity: People; id: 0x8a3dfb0 ; data: {\n name = Jain;\n – amitsbajaj Nov 26 '13 at 10:50
  • and true enough, if I type in Q (I don't have any names with Q), it comes back with: Temp = ( ) and error = (null) so it's definitely finding the names in the predicate.. it's just not displaying it in the cellForRow - we're so close! For clarity, my cellForRow is: static NSString *CellIdentifier = @"autocomplete cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; People *people = [self.autocompleteFetchedResultsController objectAtIndexPath:indexPath]; cell.textLabel.text = people.name; return cell; } – amitsbajaj Nov 26 '13 at 10:52
  • Ok that is working now, now U can delete the temp line, and go to cellforRow and put the breakpoint there and see if it gets called when U type a letter – AntonijoDev Nov 26 '13 at 10:53
  • With the breakpoint in cellForRow, it only gets called when I invoke this Modal View - it does not get called when I enter any letters into the textField, whether the first, second letter, etc.. it just doesn't get called when I enter letters, only when the view controller comes on screen for the first time.. is there a way to force it to appear when I start typing? Because the table view is hidden when the view comes on, it only unhides when I start typing (in the shouldChangeCharactersInRange method) (self.testTableView.hidden = NO; – amitsbajaj Nov 26 '13 at 11:02
  • after U type a letter put breakpoint on return _autocompleteFetchedResultsController; line and see if it is different from 0x000000 ... – AntonijoDev Nov 26 '13 at 11:09
  • So I removed breakpoint in cellForRow, ran program, invoked modal view, typed in a letter and then put a breakpoint at return _autocomplete at the end of that method and it is 0xb42, etc. I did the same with the breakpoint there and it is 0xbetc - it is not 0x000000 anytime I run it – amitsbajaj Nov 26 '13 at 11:14
  • Each time I add a letter, the return _autocompleteFetchedResultsController at the end of the autocompleteFetchedResultsController method comes back with a different 0x value - in no case is it nil, except when the program first runs before the sortdesriptor, etc – amitsbajaj Nov 26 '13 at 11:18
  • Ok put the breakpoint on return [sectionInfo numberOfObjects]; and inspect sectionInfo, NSLog [sectionInfo numberOfObjects] before u return it.. Error is somewhere... – AntonijoDev Nov 26 '13 at 11:37
  • I did: id sectionInfo = [[_autocompleteFetchedResultsController sections] objectAtIndex:section]; NSLog(@"Information = %lu", (unsigned long)[sectionInfo numberOfObjects]); return [sectionInfo numberOfObjects]; with the breakpoint on return [sectionInfo numberOfObjects] and the NSLog comes back with 13 (the number of People entries). In the debug console, the sectionInfo = 0x8aa450, etc - so not nil.. – amitsbajaj Nov 26 '13 at 12:00
  • what about when U type? – AntonijoDev Nov 26 '13 at 12:06
  • very interesting - when I type, the NSLog returns 0 and the sectionInfo in the debugging console returns 0x0 - when I first invoke this view controller, the NSLog returns 13 and sectionInfo is 0x298a etc, so not 0x0.. as soon as I type, the NSLog returns 0 and the sectionInfo is 0x0 - the same goes for the first, second, third letter, etc - it doesn't change.. – amitsbajaj Nov 26 '13 at 12:30
  • That's of course with typing a letter that exists in the People entity like the letter a – amitsbajaj Nov 26 '13 at 12:31
  • It is.. no changes at all. I can add the property declarations and the viewDidLoad as well just to be sure. Shouldn't the return [sectionInfo numberOfObjects] not be nil when I type something in though? – amitsbajaj Nov 26 '13 at 13:05
  • I have edited the question to show the viewDidLoad and property declarations, etc. I'm not sure if the return [sectionInfo numberOfObjects should return nil though - that almost looks like that should be returning a dynamic count of objects.. so if I type in J and there's three J's, it should return 3, etc? – amitsbajaj Nov 26 '13 at 13:12
  • jep tu should do that – AntonijoDev Nov 26 '13 at 13:15
  • Is there any other code I can try in the numberOfRowsInSections? I'm not using sections here - just a simple Table view.. – amitsbajaj Nov 26 '13 at 13:19
  • I've been trying for a while and I just cannot figure out why when typing, the return [sectionInfo numberObjects] = nil.. I just don't know what I can do to get this working! – amitsbajaj Nov 26 '13 at 15:51
  • I have it working! I'll update this soon because I have another error, but I may have got it working! – amitsbajaj Nov 26 '13 at 16:18
  • A simple [self.autocompleteFetchedResultsController performFetch:NULL]; before the return _autocompleteFetchedResultsController got this working! Thanks for all your help on this my friend - I couldn't have done this without you! Now, I want to do the exact same for a second text field which fetches into a different entity - how would I do the cellForRow to reflect two different cells? – amitsbajaj Nov 26 '13 at 17:18
  • Nice job, Is it going to be in the same table? – AntonijoDev Nov 26 '13 at 18:44
  • Thanks for all your help my friend. The second table is actually separate, the same behaviour for a second textfield - but basically exactly the same behaviour, just with a different entity and different table but in the same view and therefore the same class - I'm happy with the multiple predicates.. but I'm just wondering how to do the cellForRowAtIndex, etc – amitsbajaj Nov 26 '13 at 22:24
  • cellForRowAtIndex is UITableView delegate methods, so all tables will call the same method, U just have to distinguish them. One way is to set tags to tables and check them in delegate method. Say this first table has tag 200, and second 300, than u ask if(tableView.tag == 200) {do smth}, else if(tableView.tag == 300) do something else... – AntonijoDev Nov 27 '13 at 07:57
  • Hi there- that makes sense with the tags - just wondering - if I want to do this for a second table with different information.. would I create a second fetchedResultsController just for that second table, and apart from CellforRow, which methods would I use that if tag statement? Thanks! – amitsbajaj Nov 30 '13 at 09:45