I am using coredata to load a sqllite DB that has mainly static data. I make sure through code that the sqlite DB exists, and then do a
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *e = [[model entitiesByName] objectForKey:#"Item"];
[request setEntity:e];
NSError *error;
// Here I never get any data
NSArray *result = [context executeFetchRequest:request error:&error];
if (error) {
[NSException raise:#"Fetch failed"
format:#"Reason: %#", [error localizedDescription]];
}
However I never get any data out of the DB!! I get no errors either, all I get is an empty array for result.
I know the sqliteDB has data in it, what could be going wrong?
Update :
So the DB file does have values, but the behavior is inconsistent, It works fine the first time I run the app in a simulator , but If I reset Content And Settings on the simulator and then do another build, the app cannot load any data from the DB, no error or anything, it just cannot find any entries in the DB!!
The problem was intenral, I was not loading data properly.
Related
I have a project that uses core data and this error happens intermittently. I know that the entity is there because most the time, the app opens and displays the content of the entityName.
1. this is happening in the app delegate and not being segue'd
2. when i do [self.managedObjectModel entities], the entityName is there but app crashes
3. It is not miss-spelled.
4. It occurs the same place, the same time (app start)
NSManagedObjectContext *contOBJ = self.managedObjectContext;
NSEntityDescription *entity;
NSString * entityForNameString = #"MessageLists";
#try {
entity = [NSEntityDescription entityForName:entityForNameString
inManagedObjectContext:contOBJ];
}
#catch (NSException* exception) {
NSLog(#"DANGER DANGER - ERROR FOUND");
NSLog(#"Uncaught exception: %#", exception.description);
// ditch effort to reset manageObject BUT DOES NOT WORK...
[self.managedObjectContext reset];
// ditch effort to reset manageObject BUT DOES NOT WORK...
return nil;
NSLog(#"Stack trace: %#", [exception callStackSymbols]);
// Reset the store
}
#finally {
NSLog(#"finally");
}
NSFetchRequest *fetcher = [[NSFetchRequest alloc] init];
// need to define a predicate that will institute weather a message thread is deleted or NOT
[fetcher setEntity:entity];
NSError *error;
NSLog(#"All Records is %#",[contOBJ executeFetchRequest:fetcher error:&error]);
return [contOBJ executeFetchRequest:fetcher error:&error];
Don't use that old stringly typed stuff, just do this
NSFetchRequest *fetchRequest = [MessageLists fetchRequest];
NSError *error;
NSLog(#"All Records is %#",[context executeFetchRequest:fetchRequest error:&error]);
The reason why my issue was intermittent is not because of my codes but rather changes to iOS 10. Apparently, apple made changes to the way core data is init and declared in the AppDelegate.
Starting in iOS 10 and macOS 10.12, the NSPersistentContainer handles
the creation of the Core Data stack and offers access to the
NSManagedObjectContext as well as a number of convenience methods.
Prior to iOS 10 and macOS 10.12, the creation of the Core Data stack
was more involved.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/InitializingtheCoreDataStack.html
As it turns out, even if I implemented:
NSFetchRequest *fetchRequest = [MessageLists fetchRequest];
NSError *error;
NSLog(#"All Records is %#",[context executeFetchRequest:fetchRequest error:&error]);
I would still arrive at the same issue. Besides, I haven't updated my AppDelegate's Core Data codes since iOS 8...
I have a relatively simple entity. When I create it, set its attributes, and save it, it saves successfully. I can later retrieve it and it is not nil and I get a successful save message from MagicalRecord.
When I retrieve it and try to access any attribute though the attribute is nil. The entity itself is fine but the attributes are all nil. I have checked they are all definitely set correctly before I save.
I haven't encountered this problem before. Why could it be occurring?
NB: This doesn't happen every time. Most times I call the method to create and save this entity it can later be retrieved without any issues. The problem is intermittent but possible to replicate on every run.
Code:
Entity1 *entity1 = [Entity1 MR_createEntityInContext:localContext];
[entity1 setUpEntity:myobject];
EntityChild *entityChild=[EntityChild MR_createEntityInContext:localContext];
[entityChild setUpEntityChild:entity.child withContext:localContext];
[entityChild setEntity1:entity1];
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
}];
Update:
If I look in the sqlite database and search for the entity it actually doesn't exist at all. So MagicalRecord tells me it saves, CoreData lets me retrieve a non-nil object (albeit with nil attributes) but no record exists in the database.
I did not understand ur code standards. As I am new to IOS Development. I Used below code for retrieving.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityRef = [NSEntityDescription entityForName:#"Entity1" inManagedObjectContext:appDelegate.managedObjectContext];//localContext
[fetchRequest setEntity:entityRef];
NSError *error=nil;
NSArray *detailsArray = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(#"Unable to execute fetch request.");
NSLog(#"%#, %#", error, error.localizedDescription);
}
Saving the data
NSManagedObjectContext *context = [appDelegate managedObjectContext];//localContext
NSManagedObject *objectRef = [NSEntityDescription
insertNewObjectForEntityForName:#"Entity1" inManagedObjectContext:context];
[objectRef setValue:#"IOS" forKey:#"Name"];
[objectRef setValue:#"positive" forKey:#"Attitude"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
Hope it helps you...!
Ok, I got to the bottom of this. It wasn't a problem with the code when I did the save. It was actually a problem with some code in another class that was retrieving the data from the wrong context. When I changed the context it worked correctly.
I'm still not sure why this only happened occasionally and not every time the code was run but it's working now.
Thanks for your help anyway everyone.
In my app, I use Core Data foundation to store my data (some images). I need to fetch images from my data base and display them in a table view. When my app is loading, it will fetch some images from database. However, I am quite confused that sometimes the method
[context executeFetchRequest: request error: &error]
would fail to fetch data from my database while sometimes it works well (I am quite sure the data is indeed in the database). I add some test code here:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Album" inManagedObjectContext:context]];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"number" ascending:YES];
request.sortDescriptors = #[sortDescriptor];
NSArray *matches = [context executeFetchRequest:request error:&error];
for (int i = 0; i < 10; i++) {
if ([matches count]) {
break;
}
matches = [context executeFetchRequest:request error:&error];
NSLog(#"try one more fetch for my data");
}
If the database is empty, the loop will exist after trying 10 times. But when my database is not empty, from NSLog method, I find that sometimes it fetched data successfully after trying 2 times and sometimes after 5 times, and sometimes after trying 10 times it still failed to fetch data. To be more specific, this phenomenon only happens when the first few [context executeFetchRequest: request error: &error] get executed. After that, the method works well.
So I want to know why does this happen, can anyone help me?
Your question is very generic. You should add details (what do you mean with fail, share your model, share the fetch request, etc)
Few tips here.
First of all executeFetchRequest:error: takes an error as param. So you have check it for errors.
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// log error here
} else {
// log results here
}
Second, if you are using a SQLite persistent store you can see logs Core Data creates in the following way: XCode4 and Core Data: How to enable SQL Debugging.
Finally, if you are using a SQLite persistent you can also inspect saved data. A possible path could be:
/Users/NAME/Library/Application Support/iPhone
Simulator/VERSION/Applications/APP ID/Documents/DB FILE.sqlite
In addition to Dan Shelly's comment, are you performing any background operation to display images?
I have seen this link where countforfetch is always 1. But doesn't give the solution.
When i do a fetch request as given in the link it gives me the data i was about to save every time. So since its already present it wont re-save. So the database is empty. But surprisingly the data comes on the table.
This seems like a very weird behaviour. Can some please help ?
here is my code
NSFetchRequest *fetchRequest12 = [[NSFetchRequest alloc] init];
NSError *error;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"orderNumber = %#",orderList.orderNumber];
[fetchRequest12 setPredicate:predicate];
[fetchRequest12 setEntity:[NSEntityDescription entityForName:#"OrderList" inManagedObjectContext:appDelegate.managedObjectContext]];
NSLog(#"The fetch was successful! %#", [appDelegate.managedObjectContext executeFetchRequest:fetchRequest12 error:&error]);
if ([appDelegate.managedObjectContext countForFetchRequest:fetchRequest12 error:&error] ==0 ) { // Somethings to be done
}
Use setIncludesPendingChanges: to NO if you want the fetch request to ignore any changes that you have made in the MOC but not yet saved. By default all unsaved changes are fetched (hence you see unsaved changes displayed in your UI).
i've created an app that uses Core-data. Now i want to see the data that i've stored in various entities in that app. App has been installed in iOS-simulator (7.0.3)
This did not help
ScreenShot:
And here is how I am saving the data..
EffController *newController = [NSEntityDescription insertNewObjectForEntityForName:#"EffController" inManagedObjectContext:self.managedObjectContext];
newController.name=#"fgfghjfghj";
newController.uniqueUID= #"ffghfg";
newController.parentOutputID = #0;
newController.localIP=#"***.***.***.***";
newController.localPort= #XXXX;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:#"EffControllerType"];
NSError *requestError = nil;
/* And execute the fetch request on the context */
NSArray *types = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError];
for (EffControllerType *type in types) {
if ([type.name isEqualToString:#"***********"]) {
newController.type= type;
break;
}
}
NSError *error = nil;
if (![newController.managedObjectContext save:&error]) { //here is the mistake.
//It should be self.managedobjectContext
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
Edit After long discussion with #HaniIbrahim problem was solved… But still not clear about why the content was visible in app, not in sqlite file? & why context for managed object? Can anybody help to find real issue behind the topic?
After you insert, update or delete anything in CoreData you have to save context to actual apply your updates
NSError *error = nil;
[context save:&error]; // context is your managedObjectContext that you use to communicate with coreData
Edit
After you post your code I found that you are using two context self.managedObjectContext and newController.managedObjectContext ?
You can view the data by using SQLite Manager plugin for Firefox. Open firefox -> Install the plugin -> Open the plugin -> navigate to the below path using Open File option
Library/Application Support/iPhone Simulator/VERSION_OF_YOUR_SIMULATOR/Applications/YOUR_PROJECT(Usually in alphanumeric)/YOUR_DB_FILE.sqlite
That should do.
There are number of plugins and applications available similar to SQLite Manager. You may choose that as per your desire.