Data gets deleted after closing the app [IOS] - iphone

I wrote an ios application in order to save a data to core data and then fetch it with the following code:
NSManagedObjectContext *context = [self managedObjectContext];
NSError *error;
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"UserData"
inManagedObjectContext:context];
[failedBankInfo setValue:[NSNumber numberWithInt:1] forKey:#"userId"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"UserData" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"Name: %#", [info valueForKey:#"userId"]);
}
There no problem in here. But After I close my application and modify the setvalue to 2, I only receive the last data which is 2. Earlier data (1) gets deleted.
What should I do to keep the data entries even after I close my application.
Thank You!

You need to create a UIManagedDocument to save the Core Data information. I usually create the UIManagedDocument as a property of the class. For the example I have created a UIManagedDocument called theManagedDocument:
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"DocumentName"];
self.theManagedDocument = [[UIManagedDocument alloc] initWithFileURL:url];
if([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[theManagedDocument openWithCompletionHandler:^(BOOL success){
if(success) [self documentIsReady];
if(!success) NSLog(#"Couldn't Open Document");
}];
}
else
{
[theManagedDocument saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
if(success) [self documentIsReady];
if(!success) NSLog(#"Couldn't Create Document");
}];
}
Then I create a method called documentIsReady that is called when the document has been successfully created or opened (opened if it is already present, created otherwise). I will also keep the context as a property. Here it is called context. I also added in your code:
- (void) documentIsReady
{
if(self.theManagedDocument.documentState == UIDocumentStateNormal)
{
self.context = self.theManagedDocument.managedObjectContext;
NSError *error;
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"UserData"
inManagedObjectContext:self.context];
[failedBankInfo setValue:[NSNumber numberWithInt:1] forKey:#"userId"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"UserData" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [self.context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"Name: %#", [info valueForKey:#"userId"]);
}
}
}
You will then want to close the document when you are done using:
[self.theManagedDocument closeWithCompletionHandler:^(BOOL success){
if(success) NSLog(#"Closed Successfully");
if(!success) NSLog(#"Error Closing Document");
}];

You did not save your new record.
[self.managedObjectContext save:nil];

Related

managedObjectContext deleteObject:matches not deleting data from Core data base?

Am trying to delete row from core data base in ios application buts its not working,
if (editingStyle == UITableViewCellEditingStyleDelete) {
appDelegate = [[UIApplication sharedApplication] delegate];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"PRODUCTTABLE" inManagedObjectContext:appDelegate.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSError *error;
NSManagedObject *matches = nil;
NSArray *objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"Array Count....%d",[objects count]);
matches=[objects objectAtIndex:([indexPath row])];
NSLog(#"...%#",[matches valueForKey:#"productID"]);
NSLog(#"...%#",[matches valueForKey:#"pName"]);
NSLog(#"...%#",[matches valueForKey:#"pPrice"]);
NSLog(#"...%#",[matches valueForKey:#"pDate"]);
[appDelegate.managedObjectContext deleteObject:matches];
}
the o/p for following code:
Array Count....12
...ABC1226
...ABC-005
...599.39
...2012-08-09 05:07:50 +0000
am getting data from core data with same NSManagedObject. why delete not updating on Core data?
Save the context after changes.
NSError * error = nil;
[appDelegate.managedObjectContext deleteObject:matches];
[appDelegate.managedObjectContext save:&error];

How do I load data using NSEntityDescription?

i am new in xcode. i hope someone will teach me more xcode.
i'm learning core data now, from what i learn, i can save my data from uitextfield using uibutton. this is my code.
- (IBAction)button1:(id)sender
{
TestSaveDataAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
Highscore *record = [NSEntityDescription insertNewObjectForEntityForName:#"Highscore" inManagedObjectContext:context];
record.highscore1 = textField.text;
NSLog(#"Saved for %#", textField.text);
NSError *error;
if (![context save:&error])
{
NSLog(#"Error");
}
now i have a UILabel call label and a button2 next to it. how do i load my data in my label when button2 is pushed? Please teach me.
i already wrote like this but i dont know how to put it in my label. any tutorial that i find only put it in tableview. i don't want to put it in tableview, i just want my data show in my label.
- (IBAction)button2:(id)sender
{
TestSaveDataAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Highscore" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error;
if (![context save:&error])
{
NSLog(#"Error");
}
}
You have to add NSPredicate to your request and execute it.
NSPredicate *predicate = <#create your predicate here#>;
[request setPredicate:predicate];
NSError *error;
NSArray *results = [context executeFetchRequest:request error:&error];
if (error) {
//inform user
}
//if you found something, you can set text for your UILabel
if ([results count]) {
Highscore *record = [results objectAtIndex:0];
label.text = record.highscore1;
}

Core data with to-many relationship

Hello I am saving number of lyrics paragraph for song Entity. now I want to update that lyrics
I used below code to update value. but it is creating new record.. and also tell to delete
- (void)editLyrics {
[editBarbutton setTitle:#"Save"];
lyrics = [NSEntityDescription insertNewObjectForEntityForName:#"Lyrics" inManagedObjectContext:managedObjectContext];
lyrics.songLyrics = lyricsTextview.text;
lyrics.startTime = startTimeText.text;
lyrics.endTime = endTimeText.text;
lyrics.lyricsSong = song;
NSError *error;
// here's where the actual save happens, and if it doesn't we print something out to the onsole
if (![managedObjectContext save:&error])
{
NSLog(#"Problem saving: %#", [error localizedDescription]);
}
}
You have to get present object before:
NSError *error = nil;
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:#"Lyrics"
inManagedObjectContext:self.moc]];
[request setPredicate:[NSPredicate predicateWithFormat:#"something what u like to filter"]];
NSArray *lyrics = [self.moc executeFetchRequest:request error:&error];
if (error) NSLog(#"Failed to executeFetchRequest to data store: %# in function:%#", [error localizedDescription],NSStringFromSelector(_cmd));
lyrics = [lyrics lastObject]

Trouble saving Core Data objects via iOS

I was saving core data objects successfully until now. In this code, I'm searching for some objects and want to update or add a property to the saved object.
Apparently it won't save the changes, any idea why?
NSManagedObjectContext *managedObjectContext = ((VentoAppDelegate*) [[UIApplication sharedApplication] delegate]).managedObjectContext;
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:EntityNameString inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"Error - Events=nil - %#", [error localizedDescription]);
}
if ([objects count] > 0) {
for (NSManagedObject* object in objects) {
if (distance <= maxDistance) {
if (bla-bla-bla) {
[object setValue:[NSNumber numberWithBool:YES] forKey:#"notification"];
[self saveContext];
}
}
}
}
Thank you!
If you change managed object it is changed only in memory. You need to save managed context after changing anything. Add something like this:
NSError *error;
if (![object.managedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort(); // Fail
}

Core data storage is repeated

I am trying to use Core Data in my application and I have been succesful in storing data into the entity.The data storage is done in the applicationDidFinishLaunchingWithOptions() method.But when I run the app again,it again gets saved.So how do I check if the data is already present or not??
Here is the code(Saving):
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[failedBankInfo setValue:#"Test Bank" forKey:#"name"];
[failedBankInfo setValue:#"Testville" forKey:#"city"];
[failedBankInfo setValue:#"Testland" forKey:#"state"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
(Retrieving):-
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"FailedBankInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"Name: %#", [info valueForKey:#"name"]);
}
`
Another thing I want to know that if I have thousands of records to store,then is there any other way to do it or can it be done through coding only???
Thanks
from what i understand you want to add all the data once only one time?
if so, move the inserting to the persistentStoreCoordinator method, and check if this is the first time the app lunches, by checking :
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path] isDirectory:NULL]) {
firstRun = YES;
}
if it does then load the data. if not do nothing. this is how it look's at the end :
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"your_app.sqlite"];
BOOL firstRun = NO;
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path] isDirectory:NULL]) {
firstRun = YES;
}
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
if (firstRun) {
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[failedBankInfo setValue:#"Test Bank" forKey:#"name"];
[failedBankInfo setValue:#"Testville" forKey:#"city"];
[failedBankInfo setValue:#"Testland" forKey:#"state"];
NSError *error;
[moc save:&error];
}
return persistentStoreCoordinator_;
}
a.the way i do that is to create a plist with all the data.
b.import the plist as array of dictionaries (each dictionary is an entity".
c. set a function that iterates throw the array and adds the entities to the context.
something like that:
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"recordsList" ofType:#"plist"];
NSArray *recordsArray = [[NSArray alloc] initWithContentsOfFile:thePath];
for (int i=0;i<[recordsArray count];i++)
{
//add the objects to the context
}
}
I have tried to simplify the answer, but you should know there are alot of thing you can do to better the process.
good luck