0
我已經爲自定義的UITableViewCell分組了表。我正在使用AFNetworking調用Web服務並將它們存儲在Core Data Entity中。我使用NSFetchedResultsViewController顯示核心數據表中的數據。我也有在桌面上搜索。由於某些原因,即使Core Data Entity中存在數據,NSFetchedResultsController
也不會返回任何數據。你能幫助解決這個問題嗎?這是我的代碼。即使核心數據實體有數據,FetchedResultsController也會返回空
#import "MasterViewController.h"
#import "DetailViewController.h"
@interface MasterViewController()
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@end
@implementation MasterViewController
@synthesize fetchedResultsController;
- (void)viewDidLoad {
[super viewDidLoad];
appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
}
-(void)viewDidAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"RackStatusViewLoaded" object:self];
self.navigationItem.title = [defaults objectForKey:@"loggedInUserSelectedStoreName"];
NSString *activeStockTakeRequestPath = [NSString stringWithFormat:@"%@/stocktake/store/%@/activestocktake",[appDelegate baseUrl],[defaults objectForKey:@"loggedInUserSelectedStoreId"]];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:[appDelegate baseUrl]]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
path:activeStockTakeRequestPath
parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
// NSLog(@"AFNetowrking Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
NSLog(@"AF Status Code %d",statusCode);
NSError *error;
NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
if (statusCode==200)
{
NSLog(@"Status 200");
[defaults setBool:true forKey:@"isActiveStockTakeForCurrentStore"];
[defaults setObject:returnedDict[@"id"] forKey:@"ActiveStockTakeid"];
[defaults setObject:returnedDict[@"name"] forKey:@"ActiveStockTakeName"];
[defaults setObject:returnedDict[@"onDate"] forKey:@"ActiveStockTakeDate"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"setTitleForCurrentActiveStock" object:self];
NSLog(@"isActiveStock? %@",[defaults objectForKey:@"isActiveStockTakeForCurrentStore"]);
NSLog(@"ActiveStockTakeid? %@",[defaults objectForKey:@"ActiveStockTakeid"]);
NSLog(@"ActiveStockTakeName? %@",[defaults objectForKey:@"ActiveStockTakeName"]);
NSLog(@"ActiveStockTakeDate? %@",[defaults objectForKey:@"ActiveStockTakeDate"]);
[defaults synchronize];
self.fetchedResultsController = nil;
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"RackStockTakeStatus"];
[self requestLocationDataWithStatus];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if (error != nil) {
//Deal with failure
}
else {
NSLog(@"Data from Core Data %@", results);
NSLog(@"Count From Core Data Entity : %d",[results count]);
}
[self performFetchForItemsInStore];
[self.tableView reloadData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}
}];
[operation start];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
appDelegate.selectedRackForTakeStock = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Selected Rack %@",appDelegate.selectedRackForTakeStock);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[defaults setObject:cell.textLabel.text forKey:@"selectedRackInTakeStock"];
[defaults synchronize];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
NSLog(@"Number of Rows: %d",[sectionInfo numberOfObjects]);
return [sectionInfo numberOfObjects];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Number of Sections: %d",[[self.fetchedResultsController sections] count]);
return [[self.fetchedResultsController sections] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"takeStockCell";
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
RackStockTakeStatus *rackStockTakeStatus = [self.fetchedResultsController objectAtIndexPath:indexPath];
UILabel *rackName, *status, *user, *progress;
rackName = (UILabel *)[cell viewWithTag:1];
rackName.text = rackStockTakeStatus.locName;
status = (UILabel *)[cell viewWithTag:2];
status.text = rackStockTakeStatus.status;
status.text = rackStockTakeStatus.status;
progress = (UILabel *)[cell viewWithTag:3];
if (rackStockTakeStatus.percentCompleted!=nil)
{
progress.text = [NSString stringWithFormat:@"Progress: %@%%",rackStockTakeStatus.percentCompleted];
}
if (rackStockTakeStatus.stockTakeByUser!=nil)
{
user = (UILabel *)[cell viewWithTag:4];
user.text = rackStockTakeStatus.stockTakeByUser;
}
}
- (void)requestLocationDataWithStatus {
NSLog(@"Entering requestDataItemsForStore");
NSString *requestPath = [NSString stringWithFormat:@"/stocktake/stocktake/%@/usr/1/locwithstatus",[defaults objectForKey:@"loggedInUserSelectedStoreId"]];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:[appDelegate baseUrl]]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
path:requestPath
parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
// NSLog(@"AFNetowrking Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
NSLog(@"AF Status Code %d",statusCode);
NSError *error;
NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
if (statusCode==200)
{
for (NSDictionary *rackStockTakeStatus in returnedDict) {
RackStockTakeStatus *rackStockTakeStatusObj;
rackStockTakeStatusObj.stockTakeLocId = rackStockTakeStatus[@"stockTakeLocId"];
rackStockTakeStatusObj.stockTakeUuid = rackStockTakeStatus[@"stockTakeUuid"];
rackStockTakeStatusObj.locId = rackStockTakeStatus[@"locId"];
rackStockTakeStatusObj.locName = rackStockTakeStatus[@"locName"];
rackStockTakeStatusObj.status = rackStockTakeStatus[@"status"];
rackStockTakeStatusObj.stockTakeByUser = rackStockTakeStatus[@"stockTakeByUser"];
rackStockTakeStatusObj.stockTakeByUserId = rackStockTakeStatus[@"stockTakeByUserId"];
rackStockTakeStatusObj.beginTime = rackStockTakeStatus[@"beginTime"];
[self saveDataToCoreDataEntity:rackStockTakeStatusObj];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
[operation start];
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RackStockTakeStatus" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *rackNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"locName" ascending:YES];
NSArray *sortDescriptors = @[rackNameDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
return fetchedResultsController;
}
- (void)fetchItemsForStore {
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RackStockTakeStatus" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error;
[context executeFetchRequest:request error:&error];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"Begin Updates");
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(@"End Updates");
[self.tableView endUpdates];
}
-(void)performFetchForItemsInStore
{
NSLog(@"Entering performFetchForItemsInStore");
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
}
}
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSLog(@"Cancelled - searchDisplayControllerDidEndSearch");
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RackStockTakeStatus" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *rackNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"locName" ascending:YES];
NSArray *sortDescriptors = @[rackNameDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
[self performFetchForItemsInStore];
[self.tableView reloadData];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
NSInteger searchOption = controller.searchBar.selectedScopeButtonIndex;
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
NSString * searchString = controller.searchBar.text;
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString*)searchString searchScope:(NSInteger)searchOption {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"locName contains[cd] %@", searchString];
[self.fetchedResultsController.fetchRequest setPredicate:predicate];
[self.fetchedResultsController.fetchRequest setFetchLimit:100];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
TODO: "Error Handling/Error message";
}
return YES;
}
-(void)saveDataToCoreDataEntity:(RackStockTakeStatus *) rackStockTakeStatus
{
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *rackStockTakeStatusManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"RackStockTakeStatus" inManagedObjectContext:context];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.stockTakeLocId forKey:@"stockTakeLocId"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.stockTakeUuid forKey:@"stockTakeUuid"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.locId forKey:@"locId"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.locName forKey:@"locName"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.status forKey:@"status"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.stockTakeByUser forKey:@"stockTakeByUser"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.stockTakeByUserId forKey:@"stockTakeByUserId"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.beginTime forKey:@"beginTime"];
[rackStockTakeStatusManagedObject setValue:rackStockTakeStatus.percentCompleted forKey:@"percentCompleted"];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Save Failed for Data %@! %@ %@", rackStockTakeStatus, error, [error localizedDescription]);
}
}
我創建rackStockTakeStatusObj只是爲了將它傳遞給幫助保存數據到核心數據實體的函數。數據正確保存到核心數據實體。問題在於fetchedresultscontroller。這很重要嗎? – saif
我看不到你創建它。正如我指定你只是聲明它。然後你進一步創建一個新的對象,並用來自非初始化對象的數據填充它。 – DisableR
此外,您正在創建每個新對象,而不檢查是否已經爲此類stockTakeLocId保存對象。 – DisableR