NSFetchedResultsController change tracking across relationship - core-data

I have a model with two entities linked by a to-one relationship. I want to display in a TableView all EntityA objects where entityB.myIntAttribute equals a given value. This works when I create a FetchRequest for EntityA with the predicate #"entityB.myIntAttribute == aValue".
My problem is with change tracking. I have set a NSFetchedResultsControllerDelegate delegate on the NSFetchedResultsController associated to the previous FetchRequest. This delegate works because it gets notified of a deletion if I set a new entityB that doesn't match the predicate on one of the results. But if I change directly the value of myIntAttribute on the entityB object so that the predicate result changes, my delegate is not notified of the change.
Does NSFetchedResultsController change tracking work with a predicate that goes across a relationship ? How can the FetchedResultController recompute the predicate after modification of an attribute of the relationship ?

Are you implementing all of the following methods in your delegate:
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

Related

UIViewController viewDidLoad not call

I am new in ios development. I want to develop custom navigation button method.
-(void) handleNext:(id)sender
{
MRGAppDelegate *appDelegate = (MRGAppDelegate*)
[[UIApplication sharedApplication]delegate];
[appDelegate.viewController GotoDirectoryView:self.restListViewController calledView:self.view];
}
in MRGViewController.m
-(void) GoToDirectoryView:(RestaurantListViewController*) resViewContrller calledView:(UIView*)viewControllerView
{
self.resListViewController = resViewController;
[resViewController release];
[viewControllerView removeFromSuperview];
[self.resListViewController viewDidLoad];
[self.view addSubview:self.resListViewController.view];
}
But Don't call to RestaurantListViewController viewDidLoad don't call. No error appear. I don't know why? Please help me.
viewDidLoad, viewWillAppear etc are view controller life cycle method, these are called automatically when view is loaded on navigation stack. You won't need to call these method at all.
Currently you are simply adding a view on existing view controller, while you need to load a new view controller if you want view controller life cycle methods to get called.
Use like -
[self.navigationController pushViewController:restListViewController animated:YES];
[restListViewController release];
EDIT 1 -
restListViewController = [[RestaurantListViewController alloc] init];
[self presentModalViewController:restListViewController animated:YES];
[restListViewController release];

+entityForName: could not locate an NSManagedObjectModel for entity name 'Ditloide' in a second view

I try to explain my problem.
I have a first view in which I have some buttons. Pressing a button the app open a tableview. I have those files in my project:
AppDelegate.h/m
viewcontroller.h/m to control the first view
Entity1TableViewController.h/m to control the tableview opened by that
button in 1st view
an .xcdatamodel
so, until I'm in the tableview all is right. I putted this
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:#"Ditloide" inManagedObjectContext:context];
and when I tab on the button I receive the error:
+entityForName: could not locate an NSManagedObjectModel for entity name 'Ditloide' in a second view
I read other posts in which I found something like this:
MainViewController *controller = (MainViewController *)self.window.rootViewController;
controller.managedObjectContext = self.managedObjectContext;
to put in the rootcontroller. but in my case, where can I put this? I have to create a new controller? if yes, I cant insert the
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method.
So, how can I solve the problem?
I'm not pretty sure I understand your question.
The error is due to the fact you didn't set up the MOC correctly. See insertNewObjectForEntityForName: for further details.
The question is: did you set up the core data stack correctly? Could you share some code?
Then, about the code you have seen, it has the goal to inject the context wherever it is needed. For example, suppose you have a controller, called YourController, that needs the context. You can create a property in YourController like the following:
//.h
#property (nonatomic, retain) NSManagedObjectContext* context; // or strong if you ARC
//.m
#synthesize context;
Then, from a different element, for example the app delegate (if you have set up the core data stack there), you could just create YourController and inject it.
YourController* yourCtr = // alloc-init
yourCtr.context = [self managedObjectContext];
Finally, what do you mean with if yes, I cant insert the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method?

How to add initial UIViewController to existing COreData app?

I am using model "Master-detail application" for my app and would like to set different initial view. Is it possible? I want to display UIViewController with menu buttons and one of these buttons should load the Navigation controller of the previous original initial view.
When I change the initial view in storyBoards UI to ViewController and link the button to NavigationController , the app crushes.
What would be the right thing to do?
Thank you for your time!
Include this code to the AppDelegate:
- (void)tellDelegateToFlip{
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
masterViewController.managedObjectContext = self.managedObjectContext;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
[UIView setAnimationTransition:UIViewAnimationOptionTransitionFlipFromLeft forView:self.window cache:YES];
[self.navigationController pushViewController:masterViewController animated:YES];
[UIView commitAnimations];
}
And this method to the Initial view to call the master view:
-(IBAction)flipToMaster:(id)sender{
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate tellDelegateToFlip];
}
And You're done!

NavigationController as 2nd View

On my main view controller I have a button that shows a new view.
- (IBAction)showInformation:(id)sender {
InfoViewController *controller = [[InfoViewController alloc] initWithNibName:#"InfoView" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[self.view addSubview:[controller view]];
}
On my InfoView.xib I added a UINavigationController and made the proper connections. However when I the InfoViewController loads is not showing the UINavigation as I want it to.
Currently I have this on viewDidLoad
self.view = [navController view];
And on the header file I have
IBOutlet UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UINavigationController *navController;
What am I missing?
UINavigation did not show you mean UINavigationController did not appear?
1 If you use UINavigationController, you need at least two views: one for the default view that appears with the controller and another that is pushed two.
I can only see one view here, which is InfoViewController.
If you use UINavigationController, you may want to use the pushViewController method.
2 If you use presentModalViewController method, no UINavigationCOntroller is needed.

Pushing UIWebView onto UIViewController

Almost all the examples I see are done with IB but I don't want to use IB.
What I want to do is, when a user selects a row in the table a UIWebView will be pushed onto the stack and load that particular page while keeping the tab bar and navigation bar. I don't want all the features of a browser rather just be able to scroll through a page beacause the rest of my app controls how a person can navigate through the website through tables.
So I've been able to push other viewcontrollers but pushing a UIWebView with the same method doesn't work.
Here is what I have so far..
This is the Threads.h file
#import "ThreadContent.h"
#import <UIKit/UIKit.h>
#interface Threads : UITableViewController {
NSMutableArray *threadName;
NSMutableArray *threadTitle;
UIActivityIndicatorView *spinner;
NSOperationQueue *operationQueue;
UILabel *loadingLabel;
NSMutableDictionary *cachedForum;
NSMutableArray *forumID;
NSInteger *indexPathRowNumber;
NSMutableArray *threadID;
ThreadContent *threadContent;
}
#property (nonatomic, assign) NSMutableArray *forumID;
#property (nonatomic, assign) NSInteger *indexPathRowNumber;
#end
Part of my Threads.m file where I am trying to push the UIWebView
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%i",indexPath.row);//get row number
NSLog(#"%#", [threadID objectAtIndex:indexPath.row]);//thread id
//forums.whirlpool.net.au/forum-replies.cfm?t=
//NSString *urlString = [NSString stringWithFormat:#"forums.whirlpool.net.au/forum-replies.cfm?t=%#", [threadID objectAtIndex:indexPath.row]];
threadContent = [[ThreadContent alloc] init];
[self.navigationController pushViewController:threadContent animated:YES];
}
My WebView files.. well i'm not sure how to do that? I did make it a "UIWebView" subclass but if i try to push it on to the stack i get a crash saying it needs it to be a "UIViewController" subclass.
UIWebView is a subclass of UIView not UIViewController.
You need to subclass UIViewController (call it for example WebViewController)
And in the viewDidLoad method create a UIWebView and add it to the view, using addSubview:
You can pass the URL to load in the webView as a property of the WebViewController
-(void)viewDidLoad {
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubView:webView];
[webView loadRequest:[NSURLRequest requestWithURL:self.urlToLoad]];
[webView release];
}
and in Threads
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"%i",indexPath.row);//get row number
NSLog(#"%#", [threadID objectAtIndex:indexPath.row]);//thread id
//forums.whirlpool.net.au/forum-replies.cfm?t=
//NSString *urlString = [NSString stringWithFormat:#"forums.whirlpool.net.au/forum-replies.cfm?t=%#", [threadID objectAtIndex:indexPath.row]];
threadContent = [[ThreadContent alloc] init];
threadContent.urlToLoad = [NSURL URLWithString:urlString];
[self.navigationController pushViewController:threadContent animated:YES];
}
(or make the webView a property and call the load method in just before or after you push the WebViewController in Threads, I'm not 100% sure if this way would work)

Resources