SearchBar in UITableView - sorting array issue - objective-c

I'm trying to integrate search bar with my remote table view but it didn't work properly. There were no errors. I think I did some mistakes but I don't know which part so I need your help.
This is my full code:
//
// MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "SDWebImage/UIImageView+WebCache.h"
static NSString *const kConsumerKey = #"a1SNULSPtp4eLQTsTXKKSgXkYB5H4CMFXmleFvqE";
#interface MasterViewController ()<UISearchDisplayDelegate>
#property (nonatomic, assign) NSInteger currentPage;
#property (nonatomic, assign) NSInteger totalPages;
#property (nonatomic, assign) NSInteger totalItems;
#property (nonatomic, assign) NSInteger maxPages;
#property (nonatomic, strong) NSMutableArray *photos;
#property (nonatomic, strong) NSMutableArray *searchResults;
#property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
#end
#implementation MasterViewController
- (void)awakeFromNib {
[super awakeFromNib];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.photos = [NSMutableArray array];
self.searchResults = [NSMutableArray arrayWithCapacity:[self.photos count]];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self loadPhotos:self.currentPage];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.currentPage == self.maxPages
|| self.currentPage == self.totalPages
|| self.currentPage == self.totalPages
|| self.totalItems == self.photos.count) {
return self.photos.count;
}else if(tableView == self.searchDisplayController.searchResultsTableView){
return [self.searchResults count];
}
return self.photos.count + 1;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.currentPage != self.maxPages && indexPath.row == [self.photos count] - 1 ) {
[self loadPhotos:++self.currentPage];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if (indexPath.row == [self.photos count]) {
cell = [tableView dequeueReusableCellWithIdentifier:#"LoadingCell" forIndexPath:indexPath];
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:100];
[activityIndicator startAnimating];
}else{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if(tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
}
NSDictionary *photoItem = self.photos[indexPath.row];
cell.textLabel.text = [photoItem objectForKey:#"name"];
if (![[photoItem objectForKey:#"description"] isEqual:[NSNull null]]) {
cell.detailTextLabel.text = [photoItem objectForKey:#"description"];
}
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[photoItem objectForKey:#"image_url"]]
placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (error) {
NSLog(#"Error occured : %#", [error description]);
}
}];
}
return cell;
}
#pragma mark UISearchDisplay delegate
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.searchResults removeAllObjects];
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.searchResults = [NSMutableArray arrayWithArray:[self.photos filteredArrayUsingPredicate:resultPredicate]];//[self.tableData filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
- (void)loadPhotos:(NSInteger)page {
NSString *apiURL = [NSString stringWithFormat:#"https://api.500px.com/v1/photos?feature=editors&page=%ld&consumer_key=%#",(long)page,kConsumerKey];
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:apiURL]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
if (!error) {
NSError *jsonError = nil;
NSMutableDictionary *jsonObject = (NSMutableDictionary *)[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
NSLog(#"%#",jsonObject);
[self.photos addObjectsFromArray:[jsonObject objectForKey:#"photos"]];
self.currentPage = [[jsonObject objectForKey:#"current_page"] integerValue];
self.totalPages = [[jsonObject objectForKey:#"total_pages"] integerValue];
self.totalItems = [[jsonObject objectForKey:#"total_items"] integerValue];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}] resume];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DetailViewController *vc = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
vc.StoreList = [_photos objectAtIndex:indexPath.row];
}
#end

NSDictionary *photoItem = self.photos[indexPath.row];
and later
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchText];
self.searchResults = [NSMutableArray arrayWithArray:[self.photos filteredArrayUsingPredicate:resultPredicate]];
This looks like u try to sort with predicate not String but Dictionary.
Try :
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#", searchText];
Also i'd recommend u to read this code style and here some tutorial how to implement search
Regarding ur second question
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (indexPath.row == [self.photos count]) {
cell = [tableView dequeueReusableCellWithIdentifier:#"LoadingCell" forIndexPath:indexPath];
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:100];
[activityIndicator startAnimating];
} else{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if(tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchResults[indexPath.row] valueForKey:#"name"] } else {
NSDictionary *photoItem = self.photos[indexPath.row];
cell.textLabel.text = [photoItem objectForKey:#"name"];
if (![[photoItem objectForKey:#"description"] isEqual:[NSNull null]]) {
cell.detailTextLabel.text = [photoItem objectForKey:#"description"];
}
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[photoItem objectForKey:#"image_url"]]
placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (error) {
NSLog(#"Error occured : %#", [error description]);
}
}];
}
}
return cell;
}

Related

Search Bar based on JSON not working

I have a TableViewController and array from JSON url. I wanted to search #Name from server.Tableview showing data were well.But searching does not working.How to do it ?Where is the mistake?
Tableviewcontroller.h :
#interface CitiesViewController ()
#property(nonatomic,strong)NSMutableArray *jsonArray
#property(nonatomic,strong)NSMutableArray *citiesArray;
#property (nonatomic, copy)NSMutableArray *filteredNames;
#property (nonatomic, strong)UISearchController *searchController;
#property (strong, readwrite, nonatomic) NSMutableArray *arrayPlace;
#property (weak, nonatomic) IBOutlet UISearchBar *searcBar;
-(void)retrieveData;
Tableviewcontroller.m :
#end
#implementation CitiesViewController
#synthesize
citiesArray,jsonArray,filteredNames,arrayPlace,searcBar,searchController;
#pragma mark -
#pragma mark Class Methods
-(void)retrieveData
{
NSURL *url = [NSURL URLWithString:getDataURL];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
citiesArray =[[NSMutableArray alloc]init];
for (int i= 0; i<jsonArray.count; i++)
{
NSString *cID = [[jsonArray objectAtIndex:i] objectForKey:#"id"];
NSString *cName = [[jsonArray objectAtIndex:i] objectForKey:#"Name"];
NSString *cCompany = [[jsonArray objectAtIndex:i] objectForKey:#"company"];
NSString *cPosition = [[jsonArray objectAtIndex:i] objectForKey:#"position"];
NSString *cEmail = [[jsonArray objectAtIndex:i] objectForKey:#"email"];
NSString *cNumber = [[jsonArray objectAtIndex:i] objectForKey:#"number"];
NSString *cPhoto = [[jsonArray objectAtIndex:i] objectForKey:#"photo"];
NSURL *urlOne = [NSURL URLWithString:cPhoto];
// NSLog(#"%#",urlOne);
NSData *photoData = [NSData dataWithContentsOfURL:urlOne];
UIImage *imageOne = [[UIImage alloc] initWithData:photoData];
[citiesArray addObject:[[City alloc]initWithCityName:cName andCityState:cCompany andCityCountry:cEmail andCityPopulation:cPosition andCityID:cID andCityNumber:cNumber andCityPhoto: (UIImage *) imageOne]];
}
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self retrieveData];
self.arrayPlace = [NSMutableArray new];
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
filteredNames = [[NSMutableArray alloc]init];
searchController = [[UISearchController alloc]init];
self.searchController.searchResultsUpdater = self;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView.tag == 1) {
return citiesArray.count;
} else {
return [filteredNames count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell...
if (tableView.tag == 1){
City *cityob;
cityob=[citiesArray objectAtIndex:indexPath.row];
cell.textLabel.text=cityob.employeeName;
}else{
cell.textLabel.text = filteredNames[indexPath.row];
}
return cell;
}
#pragma mark Search Display Delegate Methods
-(void)searchDisplayController:(UISearchController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
-(BOOL)searchDisplayController:(UISearchController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[filteredNames removeAllObjects];
if (searchString.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searcBar.text];
for (NSString *name in citiesArray) {
NSArray *matches = [[self.jsonArray[name] objectForKey:#"Name"]filteredArrayUsingPredicate:predicate];
[filteredNames addObjectsFromArray:matches];
}
NSLog(#"filteredNames==%#",filteredNames);
}
return YES;
}

How to pass a Dictionary data from table View to the another View Controller

I am fetching the contacts of iPhone and make their Dictionary Check my code
-(void) fetchContacts
{
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
UIImage *profileImage;
NSMutableArray *contactNumbersArray;
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:#"acc_sett.png "];
}
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,#"fullName",profileImage,#"userImage",phone,#"PhoneNumbers", nil];
[_Contacts addObject:personDict];
NSLog(#"%#",phone);
NSLog(#"%#",fullName);
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.contacttableview reloadData];
});
}
}
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_Contacts count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary* personDict = [_Contacts objectAtIndex:indexPath.row];
UITableViewCell *cell = nil;
cell = [_contacttableview dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.imageView.image = [personDict objectForKey:#"userImage"];
cell.textLabel.text = [personDict objectForKey:#"fullName"];
cell.detailTextLabel.text = [personDict objectForKey:#"phoneNumbers"];
return cell;
}
With the help of this code Dictionary Data is display on the tableview now i want to pass image fullname and phone number of a person on the another view controller on selecting their row.
I have tried many method but not get any result
In YourViewController.h, create a property of Person that you want to pass
#property (nonatomic, assign) NSDictionary *person;
In TableViewController.m, didSelectRowAtIndexPath:
YourViewController *vc = [[YourViewController alloc] init];
vc.person = [_Contacts objectAtIndex:indexPath.row];
[self.navigationController pushViewController:vc animated:YES];
First create any NSDictionary object or Your model class object on OtherViewController where you want to navigate then write code like Below,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
OtherViewController *VC = [[OtherViewController alloc] init];
VC.objContactModel = [_Contacts objectAtIndex:indexPath.row];
[self.navigationController pushViewController:VC animated:YES];
}
Hope it will work.

NSPredicate not filtering UITableView?

For some reason NSPredicate isn't filtering my UITableView (it's supposed to be filtering my TableView by selections made in a UIPickerView). Users make their pickerview selections, press the GO button (segue is attached from Pickerview to Table View controller).
Any idea as to why it isn't working? See code below.
ViewController.m (TABLE VIEW CONTROLLER)
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [Strains count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strainTableIdentifier = #"StrainTableCell";
StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
if (cell == nil)
cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StrainTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"Using the search results");
cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
NSLog(#"%#", searchResults);
} else {
NSLog(#"Using the FULL LIST!!");
cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:#"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {
detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];
} else {
detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
NSLog(#"%#", Strains);
}
[self.navigationController pushViewController:detailViewController animated:YES];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)PickerViewControllerDidFinish:(PickerViewController *)viewController {
[self.navigationController popViewControllerAnimated:YES];
}
PickerViewController.h
#protocol PickerViewControllerDelegate;
#interface PickerViewController : UIViewController {
UIPickerView *pickerView;
NSMutableArray *array1;
NSMutableArray *array2;
NSMutableArray *array3;
NSArray *Strains;
NSArray *searchResults;
NSMutableData *data;
}
- (IBAction)buttonpressed:(UIButton *)sender;
#property (nonatomic, weak) id<PickerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
- (void)populateArray1;
- (void)populateArray2;
- (void)populateArray3;
#end
#protocol PickerViewControllerDelegate <NSObject>
- (void)PickerViewControllerDidFinish:(PickerViewController*)viewController;
#end
PickerViewController.m
#pragma mark -
#pragma mark picker view methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 3;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSLog(#"you selected %#", [array1 objectAtIndex:row]);
}
if (component == 1)
{
NSLog(#"you selected %#", [array2 objectAtIndex:row]);
}
if (component == 2)
{
NSLog(#"you selected %#", [array3 objectAtIndex:row]);
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 count];
}
if (component == 1)
{
return [array2 count];
}
if (component == 2)
{
return [array3 count];
}
else
{
return [array1 count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 objectAtIndex:row];
}
if (component == 1)
{
return [array2 objectAtIndex:row];
}
if (component == 2)
{
return [array3 objectAtIndex:row];
}
else
{
return [array2 objectAtIndex:row];
}
}
- (void)populateArray1
{
array1 = [[NSMutableArray alloc] init];
[array1 addObject:#"Arthritis"];
[array1 addObject:#"Cancer"];
[array1 addObject:#"HIV"];
[array1 addObject:#"Migraines"];
[array1 addObject:#"Insomnia"];
}
- (void)populateArray2
{
array2 = [[NSMutableArray alloc] init];
[array2 addObject:#"Nausea"];
[array2 addObject:#"Pain"];
[array2 addObject:#"Appetite"];
[array2 addObject:#"Fever"];
[array2 addObject:#"Exhaustion"];
}
- (void)populateArray3
{
array3 = [[NSMutableArray alloc] init];
[array3 addObject:#"Oil"];
[array3 addObject:#"Plant"];
[array3 addObject:#"Edible"];
[array3 addObject:#"Powder"];
}
- (IBAction)buttonpressed:(UIButton *)sender {
NSLog(#"Button Pushed!");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"pickerGo"])
{
// Get reference to the destination view controller
ViewController *strainTableView = [(UINavigationController *)[segue destinationViewController] topViewController];
NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:#"Ailment contains[cd] %#", [pickerView selectedRowInComponent:0]];
NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:#"Action contains[cd] %#", [pickerView selectedRowInComponent:1]];
NSPredicate *ingestPredicate = [NSPredicate predicateWithFormat:#"Ingestion contains[cd] %#", [pickerView selectedRowInComponent:2]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: ailmentPredicate,actionPredicate,ingestPredicate, nil]];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
// Pass any objects to the view controller here, like...
[strainTableView setSearchResults: searchResults];
}
}
Very puzzling, your code actually seems ok to me. I'd start by NSLoging searchResults right after the searchResults = [Strains filteredArrayUsingPredicate:resultPredicate]; line is fired, just in case something funny is happening in the table view delegates.
You should also probably check out the free Sensible TableView framework, as it provides automatic searching and filtering for your data. Should save you a ton of time.
It seems your Strains array contains dictionaries. So you should decide on what key you want to filter, for example the Title key, instead of using SELF:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
From the pickerViewController, you need to go back to the tableViewController. You can use delegate. And try to make a separate function in the table view controller to filter which contains the predicate:
- (void)filterContentForPicker:(NSString*)searchText
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
[self.tableView reloadData]
}

For some reason, NSPredicate is not filtering my UITableView?

For some reason NSPredicate isn't filtering my UITableView (it's supposed to be filtering my TableView by selections made in a UIPickerView). Users make their pickerview selections, press the GO button (segue is attached from Pickerview to Table View controller).
Any idea as to why it isn't working? See code below.
ViewController.m (TABLE VIEW CONTROLLER)
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [Strains count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strainTableIdentifier = #"StrainTableCell";
StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
if (cell == nil)
cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StrainTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"Using the search results");
cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
NSLog(#"%#", searchResults);
} else {
NSLog(#"Using the FULL LIST!!");
cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[se
lf filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:#"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {
detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];
} else {
detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
NSLog(#"%#", Strains);
}
[self.navigationController pushViewController:detailViewController animated:YES];
}
- (void)PickerViewControllerDidFinish:(PickerViewController *)viewController {
[self.navigationController popViewControllerAnimated:YES];
}
PickerViewController.h
#protocol PickerViewControllerDelegate;
#interface PickerViewController : UIViewController {
UIPickerView *pickerView;
NSMutableArray *array1;
NSMutableArray *array2;
NSMutableArray *array3;
NSArray *Strains;
NSArray *searchResults;
NSMutableData *data;
}
- (IBAction)buttonpressed:(UIButton *)sender;
#property (nonatomic, weak) id<PickerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
- (void)populateArray1;
- (void)populateArray2;
- (void)populateArray3;
#end
#protocol PickerViewControllerDelegate <NSObject>
- (void)PickerViewControllerDidFinish:(PickerViewController*)viewController;
#end
PickerViewController.m
#implementation PickerViewController
- (void)handleCloseButton:(id)sender {
if ([self.delegate respondsToSelector:#selector(PickerViewControllerDidFinish:)]) {
[self.delegate PickerViewControllerDidFinish:self];
}
}
#synthesize pickerView;
#pragma mark -
#pragma mark picker view methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 3;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSLog(#"you selected %#", [array1 objectAtIndex:row]);
}
if (component == 1)
{
NSLog(#"you selected %#", [array2 objectAtIndex:row]);
}
if (component == 2)
{
NSLog(#"you selected %#", [array3 objectAtIndex:row]);
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 count];
}
if (component == 1)
{
return [array2 count];
}
if (component == 2)
{
return [array3 count];
}
else
{
return [array1 count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 objectAtIndex:row];
}
if (component == 1)
{
return [array2 objectAtIndex:row];
}
if (component == 2)
{
return [array3 objectAtIndex:row];
}
else
{
return [array2 objectAtIndex:row];
}
}
- (void)populateArray1
{
array1 = [[NSMutableArray alloc] init];
[array1 addObject:#"Arthritis"];
[array1 addObject:#"Cancer"];
[array1 addObject:#"HIV"];
[array1 addObject:#"Migraines"];
[array1 addObject:#"Insomnia"];
}
- (void)populateArray2
{
array2 = [[NSMutableArray alloc] init];
[array2 addObject:#"Nausea"];
[array2 addObject:#"Pain"];
[array2 addObject:#"Appetite"];
[array2 addObject:#"Fever"];
[array2 addObject:#"Exhaustion"];
}
- (void)populateArray3
{
array3 = [[NSMutableArray alloc] init];
[array3 addObject:#"Oil"];
[array3 addObject:#"Plant"];
[array3 addObject:#"Edible"];
[array3 addObject:#"Powder"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"pickerGo"])
{
// Get reference to the destination view controller
ViewController *strainTableView = [(UINavigationController *)[segue destinationViewController] topViewController];
NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:#"Ailment contains[cd] %#", [pickerView selectedRowInComponent:0]];
NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:#"Action contains[cd] %#", [pickerView selectedRowInComponent:1]];
NSPredicate *ingestPredicate = [NSPredicate predicateWithFormat:#"Ingestion contains[cd] %#", [pickerView selectedRowInComponent:2]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: ailmentPredicate,actionPredicate,ingestPredicate, nil]];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
// Pass any objects to the view controller here, like...
[strainTableView setSearchResults: searchResults];
}
}
Your predicate:
NSPredicate *resultPredicate =
[NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
Looks to be trying to use "Strain" objects (which you haven't given a definition of but which are definitely compound objects) as string objects.
CONTAINS[cd] is a string comparison function.
Define your predicate more like the compound version you're using for the picker.

NSFetchedResultsController & UITableViewController not communicating

I have some "details" saved into my Core Data, and I'm trying to call it out from an NSFetchedResultsController into my tableView. For whatever reason, the tableView isn't populating once the block is finished running.
I have been searching and asking everywhere I can to try and figure out this whole Core Data debacle. Hopefully, someone on here is kind enough to help me out!
HomeViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Home";
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0 green:0.7 blue:2.3 alpha:1];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:#selector(addShindy:)];
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"light_alu.png"]];
self.tableView.opaque = NO;
self.tableView.backgroundView = nil;
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(refresh:)
forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
[self setShindyDatabase:self.shindyDatabase];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.shindyDatabase) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
self.shindyDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
}
}
- (void)refresh:(UIRefreshControl *)sender
{
[self useDocument];
[sender endRefreshing];
}
- (void)addShindy:(UIBarButtonItem *)sender
{
AddShindyViewController *addShindyViewController = [[AddShindyViewController alloc] initWithNibName:#"AddShindyViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addShindyViewController];
[self presentViewController:navController animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma Core Date Stack
- (void)fetchShindyDataIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchIntoDocument = dispatch_queue_create("Fetch Into Document", nil);
dispatch_async(fetchIntoDocument, ^{
NSArray *shindys = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
for (NSDictionary *shindyInfo in shindys) {
[Shindy shindyWithShindyDBInfo:shindyInfo inManagedObjectContext:document.managedObjectContext];
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
});
}
- (void)setShindyDatabase:(UIManagedDocument *)shindyDatabase
{
if (_shindyDatabase != shindyDatabase) {
_shindyDatabase = shindyDatabase;
[self useDocument];
}
}
- (void)useDocument
{
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.shindyDatabase.fileURL path]]) {
NSLog(#"Create document");
[self.shindyDatabase saveToURL:self.shindyDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
[self fetchShindyDataIntoDocument:self.shindyDatabase];
if (!success) {
NSLog(#"error for creation of document: %#", [error localizedDescription]);
}
}];
} else if (self.shindyDatabase.documentState == UIDocumentStateClosed) {
NSLog(#"Closed document");
[self.shindyDatabase.managedObjectContext.parentContext performBlock:^{
[self setupFetchedResultsController];
}];
} else if (self.shindyDatabase.documentState == UIDocumentStateNormal) {
NSLog(#"Normal Document");
[self setupFetchedResultsController];
}
if (error) {
NSLog(#"Error in useDocument: %#", [error localizedDescription]);
}
}
- (void)setupFetchedResultsController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Shindy"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"details" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
// request.predicate = [NSPredicate predicateWithFormat:#"details = %#", [self.shindyDatabase valueForKey:#"details"]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.shindyDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
#pragma mark - Table view data source
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 75;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
Shindy *shindy = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(#"%#", shindy.details);
cell.textLabel.text = shindy.details;
Shindy+CreateDB.m
+ (Shindy *)shindyWithShindyDBInfo:(NSDictionary *)shindyInfo
inManagedObjectContext:(NSManagedObjectContext *)context
{
Shindy *shindy = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Shindy"];
// NSSortDescriptor *dateAndTimeSort = [NSSortDescriptor sortDescriptorWithKey:#"dateAndTime" ascending:YES];
NSSortDescriptor *detailsSort = [NSSortDescriptor sortDescriptorWithKey:#"details" ascending:YES];
// NSSortDescriptor *locationSort = [NSSortDescriptor sortDescriptorWithKey:#"location" ascending:YES];
// NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
// NSSortDescriptor *photoSort = [NSSortDescriptor sortDescriptorWithKey:#"photo" ascending:YES];
// NSSortDescriptor *timePostedSort = [NSSortDescriptor sortDescriptorWithKey:#"timePosted" ascending:YES];
// title
request.sortDescriptors = [NSArray arrayWithObject:detailsSort];
// request.sortDescriptors = [NSArray arrayWithObjects:dateAndTimeSort, detailsSort, locationSort, nameSort, photoSort, timePostedSort, nil];
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (error) {
NSLog(#"document failed in file: %#", [error localizedDescription]);
}
if (!matches || ([matches count] > 1)) {
NSError *error = nil;
NSLog(#"error in DBInfo: %#", [error localizedDescription]);
} else if ([matches count] == 0) {
shindy = [NSEntityDescription insertNewObjectForEntityForName:#"Shindy" inManagedObjectContext:context];
// shindy.dateAndTime = [shindyInfo objectForKey:#"dateAndTime"];
shindy.details = [shindyInfo objectForKey:#"details"];
// shindy.location = [shindyInfo objectForKey:#"location"];
// shindy.name = [shindyInfo objectForKey:#"name"];
// shindy.photo = [shindyInfo objectForKey:#"photo"];
// shindy.timePosted = [shindyInfo objectForKey:#"timePosted"];
// title
// Guestlist? The rest?
// Use below for reference
// shindy.whoseShindy = [User userWithName:[shindyInfo objectForKey:#"whoseShindy"] inManagedObjectContext:context];
} else {
shindy = [matches lastObject];
}
return shindy;
}
EDIT:
I suppose I should have also shown a file of which I have set as a subclass of my HomeViewController. It's basically the same thing as the code that is given to you to paste in the Apple Documentation
CoreDataTableViewController.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface CoreDataTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>
#property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
- (void)performFetch;
#property (nonatomic) BOOL suspendAutomaticTrackingOfChangesInManagedObjectContext;
#property BOOL debug;
#end
CoreDataTableViewController.m
#interface CoreDataTableViewController()
#property (nonatomic) BOOL beganUpdates;
#end
#implementation CoreDataTableViewController
#pragma mark - Properties
#synthesize fetchedResultsController = _fetchedResultsController;
#synthesize suspendAutomaticTrackingOfChangesInManagedObjectContext = _suspendAutomaticTrackingOfChangesInManagedObjectContext;
#synthesize debug = _debug;
#synthesize beganUpdates = _beganUpdates;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark - Fetching
- (void)performFetch
{
if (self.fetchedResultsController) {
if (self.fetchedResultsController.fetchRequest.predicate) {
if (self.debug) NSLog(#"[%# %#] fetching %# with predicate: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate);
} else {
if (self.debug) NSLog(#"[%# %#] fetching all %# (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName);
}
NSError *error;
[self.fetchedResultsController performFetch:&error];
if (error) NSLog(#"[%# %#] %# (%#)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]);
} else {
if (self.debug) NSLog(#"[%# %#] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
}
[self.tableView reloadData];
}
- (void)setFetchedResultsController:(NSFetchedResultsController *)newfrc
{
NSFetchedResultsController *oldfrc = _fetchedResultsController;
if (newfrc != oldfrc) {
_fetchedResultsController = newfrc;
newfrc.delegate = self;
if ((!self.title || [self.title isEqualToString:oldfrc.fetchRequest.entity.name]) && (!self.navigationController || !self.navigationItem.title)) {
self.title = newfrc.fetchRequest.entity.name;
}
if (newfrc) {
if (self.debug) NSLog(#"[%# %#] %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), oldfrc ? #"updated" : #"set");
[self performFetch];
} else {
if (self.debug) NSLog(#"[%# %#] reset to nil", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
[self.tableView reloadData];
}
}
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[[self.fetchedResultsController sections] objectAtIndex:section] name];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [self.fetchedResultsController sectionIndexTitles];
}
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext) {
[self.tableView beginUpdates];
self.beganUpdates = YES;
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type
{
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
if (self.beganUpdates) [self.tableView endUpdates];
}
- (void)endSuspensionOfUpdatesDueToContextChanges
{
_suspendAutomaticTrackingOfChangesInManagedObjectContext = NO;
}
- (void)setSuspendAutomaticTrackingOfChangesInManagedObjectContext:(BOOL)suspend
{
if (suspend) {
_suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
} else {
[self performSelector:#selector(endSuspensionOfUpdatesDueToContextChanges) withObject:0 afterDelay:0];
}
}
#end
And then last, but not least, I have the header file for my HomeViewController of which I implement CoreDataTableViewController. Hopefully this is useful in better explaining what I've got.
HomeViewController.h
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
#import "CoreDataTableViewController.h"
#interface HomeViewController : CoreDataTableViewController
#property (strong, nonatomic) UIManagedDocument *shindyDatabase;
#property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
#end
It's quite difficult to see what is going on, but, I think you need to do the following steps when the block has finished (I suppose this since I don't see any similar in your code).
execute the fetch request through the fetched controller
reload the data table
So,
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// error handling here...
}
[yourTable reloadData];
Try and let me know. If doesn't work, try to edit a minimal question because there is too much code to follow.
Hope that helps.
I ended up figuring this, and many other Core Data issues I was having. I wasn't setting my managed object context to a store!! DUH!!!
self.managedObjectContext = [(AppDelegate *)[UIApplication sharedApplication].delegate managedObjectContext];
That did the trick. Everything began working after that.
I hope this is able to point out another duh to anybody out there forgetting the same thing I did!