+entityForName: could not locate an NSManagedObjectModel for entity name - iphone

I was chugging along just fine with a project that uses core data for months now since I wired in the core data stack and migrated the database and last night just started getting an error on the Managed Object Model.
I know that what it is doing is trying to establish a managed object context in this line
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Question" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
The program is crashing in the first view controller when it tries to get the Question entity. I declare/create the AppDelegate
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"PSQ" ofType:#"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
//managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}
When I set a breakpoint in the app delegate, it never gets there before the app crashes. It goes to the view controller first.
The weird thing is, I did not change my core data functionality for about 6 weeks since it was finished and working.
Any ideas what I might be doing?
This began happening while i was adding NSUSerdefaults for an NSSwitch to toggle the option to display an into screen or not.
Update: The app crashes at the point mentioned only in the iPhone version and goes through the managed object issues just fine in iPad. What would be in the .xib files that would be different causing the flow to error at the managedObjectContext?

Ok got it fixed.
Turns out that somehow the app delegate got rewired in my iphone nib. I guess that is what Xcode was trying to tell me when it would hit up the mainViewController before the app delegate for the managed object context.
I set the class back to UIApplication, then wired the delegate to the app delegate in IB and all is well.

Related

iPhone refreshing tabcontroller and content

I have two problems I am trying to solve, one is refreshing the tab controller itself and the other is refreshing the content of the tabcontroller.
The reason I wish to refresh the tab controller itself is that my application has a web call which returns a JSON which sets up the order of the tabs and also sets up the content of each tab. I have got it so that when you back out of the application and reenter the application the tab controller is refreshed by putting
exit(0)
in the AppDelegates ApplicationDidEnterBackground so that when the user backs out and in again the controller will be refreshed. In the applicationDidFinishLaunchingWithOptions, I have set up a web call which calls the JSON which is then used to set up the tab order. I know this is not a good way of doing this, but for the time being, its the only solution I can think of. How else can I refresh the TabController?
As for the tab content, it is refreshed using using this code
becomeActiveObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
queue: nil
usingBlock:^(NSNotification *note){
[self refresh];
[self viewDidUnload];
}];
I have set this type of code up for each of the 5 tabs. This works very well, but the problem is the content only refreshes when the application is exited and accessed again. The web call will be periodic and I would like it when the web call is made that the content will refresh itself without me having to back out and in to the application again.
For testing purposes I have set up a button in my settings screen (settings screen is just a another view within one of my tabs) that when clicked with read JSON is stored in the iPhone directory which is different from the JSON retrieved from the web call (saves me having to go to the server and keep changing the JSON there). When this button is clicked, it should read this new JSON, update the content and then refresh the view. I have tested this and the JSON is being read and the data is being updated (I set up a button on each screen which would read out the JSON it is using to confirm this) but the view is not refreshing until I exit and enter the application again.
The temp code I have set up in the settings screen to read the JSON stored on the device is
-(IBAction)RefreshApp:(id)sender{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"widgjson" ofType:#"json"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: #"json.txt"];
[fileManager removeItemAtPath:docFile error:NULL];
[responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding
DashboardVC *db = [[DashboardVC alloc] init];
[db refresh];
[db viewDidUnload];
}
At the bottom you can see I tried to call refresh from one of the tabs to refresh one of the views do see if that worked, but no luck. The refresh code only seems to work when you call it from inside the class itself, I can't seem to get it to refresh when accessing it from another class.
When a web call is made, I want every single tab to be refreshed at once. Any ideas on how I would do this?
Would be very grateful if someone could point me in the right direction.
UITabBarController's setViewControllers: animated: method is what you want to use here.
When you receive a notification where you want to re-order the tabs, use that function to pass along the various view controllers owned (and referred to) in your tab bar in an array which is in the order of how you want your tabs to appear.

how do i remove coredata from iphone

You know how you can Reset the coredata store on an iPhone simulator when you've changed your entity structure?
Do I need to perform a similar process when I've created a new version of my core data store that is different from what I last ran on my iPhone? If so, how, please?
Thanks
Just for convenience, until you code a way to remove the persistent store through your app, you can just delete the app off the phone. (Hold your finger on the home screen until icons get wiggly, then click the x on your app.) Then with your phone connected to your Mac, choose Product > Run in XCode and it will reinstall your app on the phone, but with empty data directories.
For deployment, of course, you need to come up with a way to do it without deleting the app, if you will ever change your data model after deployment (assume you will). Data migration is the best option, but if all else fails delete the persistent store file. It would be preferable to prompt for the user's approval before doing that. If they have important data they can decline and maybe get the old version of your app back to view the data and migrate it by hand, or they can wait until you release version 2.0.1 that fixes your data migration bug.
Here is the routine I use to reset my App content. It erases the store and any other file stored.
- (void) resetContent
{
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSString * rootDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *rootURL = [NSURL fileURLWithPath:rootDir isDirectory:YES];
NSArray *content = [localFileManager contentsOfDirectoryAtURL:rootURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:NULL];
for (NSURL *itemURL in content) {
[localFileManager removeItemAtURL:itemURL error:NULL];
}
[localFileManager release];
}
If you only want to erase the store, since you know its file name, you can refrain from enumerating the document directory content:
- (void) resetContent
{
NSFileManager *localFileManager = [[NSFileManager alloc] init];
NSString * rootDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *rootURL = [NSURL fileURLWithPath:rootDir isDirectory:YES];
NSURL *storeURL = [rootURL URLByAppendingPathComponent:#"myStore.sqlite"];
[localFileManager removeItemAtURL:storeURL error:NULL];
[localFileManager release];
}
But please note that in many cases, its better to migrate your store when you change your model, rather than to delete it.
locate your app in /Users/username/Library/Application Support/iPhone Simulator/4.3.2 (iOS Version may be different) and delete the .sqlite file
You can look at the path that is being sent to the persistentStoreCoordinator on setup, and remove that file. Usually the approach I have taken is that I set up the store to auto migrate, and if that fails I delete the store and attempt one more time to create the persistentStoreCoordinator which will use the now empty path.
Don't forget you may need to repopulate anything stored in the old database.

Could not locate an NSManagedObjectModel for entity name - Universal App

I have a strange error in my app, which says:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Book'
I know, there are hundrets of "Could not locate an NSManagedObjectModel for entity name" topis here and on the web, but the strange thing is, it's a universal app and the iphone app always works fine, only the ipad app is crashing on startup.
In the main AppDelegate, there is some code in two methodes and in the iphone / ipad AppDelegate I'm calling this code in applicationdidFinishLaunchingWithOptions like this:
if ([self modelExists] == NO) {
[self buildModel];
}
So it's the same way I call the code, but the ipad version crashes and the iphone version does not.
The only different is that the iPhone version uses a TabBarContoller (set up in IB) and the iPad version uses a single viewController (also set up in IB).
It happens on both, simulator and device.
I have no idea what to do. Hope you can understand what I mean ...
Thx a lot
Sebastian
EDIT:
I found out, when I run the iPhone Version, the code in the main AppDelegate is called as it should be, but when I run the iPad Version NONE code of the main appDelegate is called at all, so there is no managedObject created and that's the reason for the error. But why is no code run in the main AppDelegate ? Thx
EDIT2:
This is the code in my main AppDelegate now:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([self modelExists] == NO) { // Checks if the model is allready filled up or not. (Uses CoreData stuff of course)
// iPhone Version is fine here. iPad Version crashes.
[self buildModel];
}
[self buildInterface]; // Called in the iPhone or iPad AppDelegate to make the window visible etc.
return YES;
}
So didFinishLaunchingWithOptions is called in the iphone and in the ipad version. The iPad version just doesn't run the coredata stuff anyway, whereas the iphone version does run the coredata stuff as it should. Any idea what could be wrong? THX!
Maybe the app delegate is not running any code if it's just not set as an delegate of the application.
Look in your main NIB for the iPad version and make sure the "AppName App Delegate" is set as the delegate of the File's owner of that NIB.
I found my problem. Really strange ...
It was the code of "modelExists"
- (BOOL)modelExists {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:#"Book" inManagedObjectContext:__managedObjectContext]; //<- Crashed. Had to change it to self.managedObjectContext
request.predicate = nil;
NSError *error = nil;
...
Sebastian
I had this same problem. My app had been working fine for weeks in development, then suddenly it was crashing with this error. Changing managedObjContect to [self managedObjectContext] solved the problem.
I would love to know why....any experts out there? Why would the original code be able to resolve the call to managedObjectContext to the member function's implementation....and suddenly not be able to? There is no other static implementation visible to this code as far as I know.
Thank for posting this, save me many hours of messing around.
In my project, I had a navigation controller and I was getting this error when I tried to segue into a child view control.
The problem was that I needed to pass set the managedObjectContext. This is taken from the CoreDate Master/Detail example.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailItem:object];
// set the managedObjectContext, too, if you need it
[[segue destinationViewController] setManagedObjectContext:self.managedObjectContext];
}
}
Also, double check the segue identifier in Interface Builder matches what you have in this function (showDetail in this example).

UIWebView loadRequest causing a crash in simulator

So I'm trying to load a simple URL (http://www.google.com) into a web view. I had this in the application I was working with, but boiled it down to a basic application to remove other variables. I have an absolute minimal application setup, one view controller with a webview as its primary view. For code I have
-(void)viewDidLoad
{
[super viewDidLoad];
UIWebView *webView = (UIWebView*)self.view;
NSMutableString *urlString = [[NSMutableString alloc] initWithString:#"http://www.google.com"];
NSURL* url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
NSLog(#"Sending web request to %#", urlString);
[webView loadRequest:urlRequest];
[urlRequest release];
[url dealloc];
[urlString dealloc];
}
And when it loads, I get an EXC_BAD_ACCESS crash within the Web Thread. I am unsure if this is a problem related to the fact that I am working in the simulator, or something I've just screwed up with the setup.
DO NOT CALL dealloc. Call release on url and urlString instead.
This is because other objects have references to those objects, and when you say dealloc, you are explicitly destroying them. This is causing the EXC_BAD_ACCESS, because when other objects try to access the url and string objects, they have already been destroyed.
This is the whole point of reference counting. YOU are done with those objects, so if you say:
[url release];
[urlString release];
You are declaring that. This decrements the count of references to those objects. But up above, you said:
NSURL* url = [[NSURL alloc] initWithString:urlString];
This means url probably has a reference to that string. So it would have retained it when you created it. So after you release the string, it does not get destroyed because url still has a reference to it. When IT is done with it, it too will release it, and then (if no one else has claim to the object), it will automatically be dealloced, because its count will have dropped to zero.
Always keep in mind who else might be using your objects when you are dealing with this sort of memory management. You can read more about it in Apple's docs.

UIWebView leak? Can someone confirm?

I was leak-testing my current project and I'm stumped. I've been browsing like crazy and tried everything except chicken sacrifice. I just created a tiny toy project app from scratch and I can duplicate the leak in there. So either UIWebView has a leak or I'm doing something really silly.
Essentially, it boils down to a loadRequest: call to a UIWebView object, given an URLRequest built from an NSURL which references a file URL, for a file in the app bundle, which lives inside a folder that Xcode is including by reference. Phew.
The leak is intermittent but still happens ~75% of the time (in about 20 tests it happened about 15 times). It only happens on the device -- this does not leak in the simulator. I am testing targeting both iPhone OS 3.1.2 and 3.1.3, on an original (1st Gen) iPod Touch that is using iPhone OS 3.1.3.
To reproduce, just create a project from scratch. Add a UIWebView to the RootViewController's .xib, hook it up via IBOutlet. In the Finder, create a folder named "html" inside your project's folder. Inside that folder, create a file named "dummy.html" that has the word "Test" in it. (Does not need to be valid HTML.) Then add the html folder to your project in Xcode by choosing "Create Folder References for any added folders"
Add the following to viewDidLoad
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* filePath = [[resourcePath stringByAppendingPathComponent:#"html"] stringByAppendingPathComponent:#"dummy.html"];
NSURL* url = [[NSURL alloc] initFileURLWithPath:filePath];
NSURLRequest* request = [NSURLRequest requestWithURL:url]; // <-- this creates the leak!
[browserView loadRequest:request];
[url release];
I've tried everything from setting delegate for the UIWebView and implementing UIWebViewDelegate, to not setting a delegate in IB, to not setting a delegate in IB and explicitly setting the web view's delegate property to nil, to using alloc/init instead of getting autoreleased NSURLRequests (and/or NSURLs)...
I tried the answer to a similar question (setting the shared URL cache to empty) and that did not help.
Can anyone help?
Try:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"WebKitCacheModelPreferenceKey"];
}
From http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest
Forgot about this question.
The leak is not present in 4.1. I would assume the same for 4.2.