how to import videos using coredata? - objective-c

I am developing one app named safekeep.I have to import videos using coredata by converting into data.
if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:#"public.movie"])
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"Q: video path: %#",[videoURL description]);
self.videoData=[NSData dataWithContentsOfURL:videoURL];
if(self.videoData)
{
NSLog(#"data is present");
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *imagetblObj= [NSEntityDescription insertNewObjectForEntityForName:#"VideoData" inManagedObjectContext:context];
[imagetblObj setValue:self.videoData forKey:#"videodata"];
[imagetblObj setValue:str forKey:#"date"];
NSError *err;
if (![context save:&err])
{
NSLog(#"Couldn't save history item into coredata");
}
NSLog(#"data saved");
[self videodatafromdb];
}
}
-(void)videodatafromdb
{
NSManagedObjectContext *context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"VideoData" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error;
NSArray *recordsData=[context executeFetchRequest:request error:&error];
self.videoarray=[[recordsData reverseObjectEnumerator]allObjects];
NSLog(#"Array count is %d",[self.videoarray count]);
if ([self.videoarray count]>0)
{
[self createScrollViewvideo];
}
}
-(void)createScrollViewvideo
{
NSLog(#"in create scrollviewvideo");
//add views to scrolview
int x=5;
int y=17;
for(int i=0;i<[videoarray count];i++)
{
UIImage *imag=[[UIImage alloc] init];
UIView *videoview=[[UIView alloc] initWithFrame:CGRectMake(x, y, 100, 100)];
videoview.tag=i;
UIButton *userButton=[[UIButton alloc]initWithFrame:CGRectMake(1, 1, 100,100)];
[userButton addTarget:self action:#selector(userVideoClicked:) forControlEvents:UIControlEventTouchUpInside];
userButton.tag=i;
imag=[UIImage imageWithData:videoData];
[userButton setBackgroundImage:imag forState:UIControlStateNormal];
[videoview addSubview:userButton];
[self.scrollview addSubview:videoview];
[userButton release];
[videoview release];
x+=104;
if ((i+1)%3==0)
{
y+=110;
x=5;
}
}
NSLog(#"10000in create scrollview");
if (y+110>self.scrollview.frame.size.height)
{
self.scrollview.contentSize=CGSizeMake(320, y+110);
}
else
{
self.scrollview.contentSize=CGSizeMake(320, self.scrollview.frame.size.height+60);
}
}
}
-(IBAction)userVideoClicked:(id)sender
{
NSLog(#"video clicked");
UIButton *button=(UIButton*)sender;
VideoData *videoobj=(VideoData *)[self.videoarray objectAtIndex:[button tag]];
NSLog(#"video data is %#",videoobj);
VidoesVIewController *videoviewcontroller=[[VidoesVIewController alloc] initWithNibName:#"VidoesVIewController" bundle:nil];
videoviewcontroller.videodata=[videoobj valueForKey:#"videodata"];
[self.navigationController pushViewController:videoviewcontroller animated:YES];
[videoviewcontroller release];
}
Videos are not showing in sroll view.But When click on video file it is navigating. When image is set to button, image is showing in view.Thanks in advance.

See my answer in:
Can I access the files used for external binary storage in Core Data?
I came up with a 'creative' solution (whether it best practice is anyones guess), but it will allow you to use Core Data to manage your files while still being able to access the REAL files by their path.
By using the 'Allows External Storage' option on a Binary field, you can allow core data to manage references to your files for you, abstracting out a fair amount of the busy work.

Related

CoreData and UITableView: display values in cells

I'm working with Core Data and web service, I want to add my data to my table,
but I don't know how should I call them, would you please help me, since when I used this way it's not working.
Here is my method for update database in my HTTP class
- (void)updateLocalCardsDataBase:(NSArray*) cardsArray
{
//check if current user has cards in local database
NSManagedObjectContext* managedObjectContext = [(AppDelegate*) [[UIApplication sharedApplication] delegate] managedObjectContext];
for(NSDictionary *cardDic in cardsArray)
{
Card *card = [NSEntityDescription insertNewObjectForEntityForName:#"Card" inManagedObjectContext:managedObjectContext];
card.remote_id = [NSNumber numberWithInt:[[cardDic objectForKey:#"id"] intValue]];
card.stampNumber = [NSNumber numberWithInt:[[cardDic objectForKey:#"stampNumber"] intValue]];
card.createdAt = [NSDate dateWithTimeIntervalSince1970:[[cardDic objectForKey:#"createdAt"] intValue]];
[managedObjectContext lock];
NSError *error;
if (![managedObjectContext save:&error])
{
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
NSLog(#"Failed to save to data store: %#", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError* detailedError in detailedErrors) {
NSLog(#" DetailedError: %#", [detailedError userInfo]);
}
}
else {
NSLog(#" %#", [error userInfo]);
}
}
[managedObjectContext unlock];
}
Here is my table:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
// NSManagedObjectContext* managedObjectContext = [(AppDelegate*) [[UIApplication sharedApplication] delegate] managedObjectContext];
static NSString *CellIdentifier = #"CardsCell";
CardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:#"CardCell" owner:nil options:nil];
for (id currentObject in objects)
{
if([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (CardCell *) currentObject;
break;
}
}
NSDictionary *f = [_cards objectAtIndex:indexPath.row];
cell.stampId.text = [f objectForKey:#"stampNumber"];
NSLog(#"%#fdssfdfddavds",[f objectForKey:#"stampNumber"]);
cell.createdAt.text = [f objectForKey:#"createdAt"];
cell.CardId.text = [f objectForKey:#"id"];
return cell;
}
Edit:
My problem is how I can show data in a UITableView
Before call [tableView reloadData], you need to get a data source first. You will get back an array of your data models, not an NSDictionary. You can place the my example method (or a variation that suits you best) where ever best suits your needs, but this one will not filter or sort the models, it will only get all of them. Also, I will place the method in your view controller that stores the table view:
-(NSArray*)getMycards {
NSManagedObjectContext *context = [(AppDelegate*) [[UIApplication sharedApplication] delegate] managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Card" inManagedObjectContext:context];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSError *error;
[request setEntity:entityDescription];
NSArray *cards = [context executeFetchRequest:request error:&error];
// now check if there is an error and handle it appropriatelty
// I usually return 'nil' but you don't have if you don't want
if ( error != nil ) {
// investigate error
}
return cards;
}
I recommend creating a property #property NSArray *cards in the view controller where you place your table, it will be easier to manage. One assumption I have made (since I have no other information about your view controller, a property named 'tableView' is declared in your view controller's header file (#property UITableView *tableView;), adjust the naming as needed.
With the above method, when you want to populate your array before loading the table's data:
// you put this block of code anywhere in the view controller that also has your table view
// likely in 'viewDidLoad' or 'viewDidAppear'
// and/or anywhere else where it makes sense to reload the table
self.cards = [self getMyCards];
if ( self.cards.count > 0 )
[self.tableview reloadData];
else {
// maybe display an error
}
Now, your cellForRowAtIndexPath should look like
-(UITableViewCell*tableView:tableView cellForRowAtIndexPath {
UITbaleViewCell *cell = ...;
// creating the type of cell seems fine to me
.
.
.
// keep in mind I don't know the exact make up of your card model
// I don't know what the data types are, so you will have to adjust as necessary
Card *card = self.cards[indexPath.row];
cell.stampId.text = [[NSString alloc] initWithFormat:#"%#",card.stamp];
cell.createdAt.text = [[NSString alloc] initWithFormat:#"%#",card.createdAt];
// you might want format the date property better, this might end being a lot more than what you want
cell.CardId.text = [[NSString alloc] initWithFormat:#"%#",card.id];
return cell;
}
Core Data is extremely powerful, I highly recommend the Core Data overview, followed by the Core Data Programming Guide.

NSFetchedResultController won't show data in IOS 5

I am new to IOS development. At the moment I'm building an iPad app, what gets data back from the webservice, saves it in a core database and shows it in a tableview using NSFetchedResultController.
What is the problem. In IOS6 it al works like a charm, in IOS 5.0 it saves the data but not showing it in the tableview. It gives the following error.
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. The NIB data is invalid. with userInfo (null)
And when I test in IOS 5.1 it does not do anything. It does not shows data in a tableview and data is not being stored in core database.
Here is what I do. In my view did appear I check if there is a document I can use.
if (!self.genkDatabase) { // we'll create a default database if none is set
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"Default appGenk Database"];
self.genkDatabase = [[UIManagedDocument alloc] initWithFileURL:url]; // setter will create this for us on disk
}
Then it goes to my setter. And next in usedocument gonna check in which state my document is.
- (void)setGenkDatabase:(UIManagedDocument *)genkDatabase
{
if (_genkDatabase != genkDatabase) {
_genkDatabase = genkDatabase;
[self useDocument];
}
NSLog(#"Comes in the setdatabase methode.");
}
- (void)useDocument
{
NSLog(#"Comses in the use document");
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.genkDatabase.fileURL path]]) {
// does not exist on disk, so create it
[self.genkDatabase saveToURL:self.genkDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(#"create");
[self setupFetchedResultsController];
NSLog(#"create 2");
[self fetchNewsIntoDocument:self.genkDatabase];
NSLog(#"create 3");
}];
} else if (self.genkDatabase.documentState == UIDocumentStateClosed) {
NSLog(#"closed news");
// exists on disk, but we need to open it
[self.genkDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.genkDatabase.documentState == UIDocumentStateNormal) {
NSLog(#"normal");
// already open and ready to use
[self setupFetchedResultsController];
}
}
Finally I fetch my data in my document using the following function.
- (void)fetchNewsIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchNews = dispatch_queue_create("news fetcher", NULL);
dispatch_async(fetchNews, ^{
NSArray *news = [GenkData getNews];
[document.managedObjectContext performBlock:^{
int newsId = 0;
for (NSDictionary *genkInfo in news) {
newsId++;
[News newsWithGenkInfo:genkInfo inManagedObjectContext:document.managedObjectContext withNewsId:newsId];
NSLog(#"news inserted");
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
}];
});
dispatch_release(fetchNews);
}
For the problem in IOS 5.0 is this my NSFetchResultController method.
- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"News"];
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES],nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.genkDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
I am doing this like the example from Paul Hegarty in stanford university. You can find the example Photomania over here.
Hope anyone can help me!
Kind regards

save records from WCF service in CoreData

I am new to iOS development and CoreData too. I am calling a .Net WCF service for displaying data in a UITableViewcontroller in my app.I am saving this data in CoreData. When I add a new record on the server,I want it to get displayed in the UITableViewController as well as saved in CoreData.But this doesnt happen.I have to do a "Reset Contents and Settings" on the Simulator and then run the application again. When I do this,the app displays the latest records from the service.It also saves the new record in CoreData.I am using SUDZC for interacting with the wcf service.The code for calling the service,displaying data in UITableViewController and saving it to CoreData looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
[my_table setDataSource:self];
[my_table setDelegate:self];
EDViPadDocSyncService *service = [[EDViPadDocSyncService alloc]init];
[service getAllCategories:self action:#selector(handleGetAllCategories:)];
}
-(void)handleGetAllCategories:(id)value
{
if([value isKindOfClass:[NSError class]])
{
NSLog(#"This is an error %#",value);
return;
}
if([value isKindOfClass:[SoapFault class]])
{
NSLog(#"this is a soap fault %#",value);
return;
}
NSMutableArray *result = (NSMutableArray*)value;
self.myData = [[NSMutableArray array] init];//array for storing 'category name'
self.catId = [[NSMutableArray array]init];//array for storing 'category ID'
self.myData=[self getCategories];
/*store data in Core Data - START*/
NSMutableArray *coreDataCategoryarray = [[NSMutableArray alloc]init];
NSManagedObjectContext *context = [self managedObjectContext];
Categories *newCategory;//this is the CoreData 'Category' object
for(int j=0;j<[result count];j++)
{
EDVCategory *edvCat = [[EDVCategory alloc]init];//this is the SUDZC 'Category' object
edvCat = [result objectAtIndex:j];
if ([self.catId count]>0) {
for (int i=0; i<[self.catId count]; i++) {
if ([edvCat categoryId] == [[self.catId objectAtIndex:i] integerValue]) {
checkFlag=TRUE;
}
}
}
if (checkFlag == FALSE) {
newCategory = [NSEntityDescription insertNewObjectForEntityForName:#"Categories" inManagedObjectContext:context];
[newCategory setCategoryId:[NSNumber numberWithInt:[edvCat categoryId]]];
[newCategory setCategoryName:edvCat.categoryName];
[newCategory setDocCount:[NSNumber numberWithInt:[edvCat docCount]]];
[newCategory setCategoryType:[NSNumber numberWithShort:[edvCat categoryType]]];
[newCategory setSubCategoryId:[NSNumber numberWithInt:[edvCat subCategoryId]]];
[coreDataCategoryarray addObject:newCategory];
}
}
/*store data in Core Data - END*/
NSError *error = nil;
if (![context save:&error])
{
[coreDataCategoryarray release];
}
else
{
//return [coreDataCategoryarray autorelease];
[coreDataCategoryarray autorelease];
}
self.myData=[self getCategories];
[my_table reloadData];
}
-(NSMutableArray *)getCategories
{
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
NSSortDescriptor *sortByName = [[[NSSortDescriptor alloc] initWithKey:#"categoryId" ascending:YES] autorelease];
[request setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[request setEntity:entity];
entity = nil;
NSError *error = nil;
NSMutableArray *fetchResults = [[__managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
[request setReturnsObjectsAsFaults:NO];
NSManagedObject *aTabrss;
NSMutableArray *arForGetCategory=[[NSMutableArray alloc]init];
for (aTabrss in fetchResults){
[arForGetCategory addObject:[aTabrss valueForKey:#"categoryName"]];
[self.catId addObject:[aTabrss valueForKey:#"categoryId"]];
}
return (arForGetCategory);
}
What changes should I make in my code so that it reflects the latest data from the service and saves it to CoreData(sqlite) at the same time?
It seems like the class that you really need is NSUserDefaults:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html

NSManagedObject fail to save it's attributes, but able to save when adding related objects

I'm developing an iOS app using Core Data. And I have a Log entity with one-to-many relationships with Audio, Photo entities, and one-to-one relationship with Status entity. The log also has text, longitude, latitude properties. I can create the log, change its properties, add status entity, these changes would display right, until I quit the App. All the changes would disappear, and I was looking at the sqlite database, all these changes were never persisted in the database. In the database, the status object will just be created, but not linked to the log object.
But if I add an audio or photo object into the log.audioSet or log.photoSet, the changes I made to log, including the changes to text or status, will suddenly be saved into the database.
So it seems the changes are only maintained in the NSManagedObjectContext, until a related one_to_many entity is added and the [[LTLogStore sharedStore] saveChanges] will suddenly start to work.
I am using a singleton to manage the NSManagedObjectContext. Any ideas?
I would post some code if it's relevant. Thanks.
UPDATE: I'm not sure these code is enough. But basically everything works, and displays, it just doesn't save to the database. I'm using the mogenerator to set the text and latitude, but since everything is in the context. I am not sure this is the code you might need.
CODE:
#interface LTLogStore : NSObject{
}
+ (LTLogStore *)sharedStore;
- (void)removeItem:(Log *)p;
- (Log *)createItem;
- (BOOL)saveChanges;
#property(nonatomic, strong) NSFetchedResultsController *resultsController;
#property(nonatomic, strong) NSManagedObjectModel *model;
#property(nonatomic, strong) NSManagedObjectContext *context;
#end
#implementation LTLogStore
#synthesize resultsController;
#synthesize context, model;
+ (LTLogStore *)sharedStore
{
static LTLogStore *sharedStore = nil;
if(!sharedStore){
sharedStore = [[super allocWithZone:nil] init];
}
return sharedStore;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [self sharedStore];
}
- (id)init
{
self = [super init];
if(self) {
model = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *psc =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// Where does the SQLite file go?
NSString *path = [self itemArchivePath];
NSURL *storeURL = [NSURL fileURLWithPath:path];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:nil
error:&error]) {
[NSException raise:#"Open failed"
format:#"Reason: %#", [error localizedDescription]];
}
// Create the managed object context
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:psc];
// The managed object context can manage undo, but we don't need it
[context setUndoManager:nil];
}
return self;
}
- (NSFetchedResultsController *)resultsController {
if (resultsController !=nil) {
return resultsController;
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *e = [[model entitiesByName] objectForKey:#"Log"];
[request setEntity:e];
NSSortDescriptor *sd = [NSSortDescriptor
sortDescriptorWithKey:#"created_at"
ascending:NO];
[request setSortDescriptors:[NSArray arrayWithObject:sd]];
[request setReturnsObjectsAsFaults:NO];
NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:nil cacheName:#"Root"];
NSError *error;
BOOL success = [fetchedResultsController performFetch:&error];
if (!success) {
//handle the error
}
return fetchedResultsController;
}
- (NSString *)itemArchivePath
{
NSArray *documentDirectories =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
// Get one and only document directory from that list
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
NSString *storePath = [documentDirectory stringByAppendingPathComponent:#"store.data"];
return storePath;
}
- (BOOL)saveChanges
{
NSError *err = nil;
BOOL successful = [context save:&err];
NSLog(#"Saving changes to the database");
if (!successful) {
NSLog(#"Error saving: %#", [err localizedDescription]);
}
return successful;
}
- (void)removeItem:(Log *)l
{
[context deleteObject:l];
[self saveChanges];
}
- (Log *)createItem
{
Log *p = [NSEntityDescription insertNewObjectForEntityForName:#"Log"
inManagedObjectContext:context];
[self saveChanges];
return p;
}
#end
#interface Log : _Log {
}
//these two are some custom convenience methods for location attributes, but it does the work of setting the longitude and latitude value in the log object, but calling the [[LTLogStore sharedStore] saveChanges] still won't save it into the database.
-(CLLocation*)location;
-(void)setLocation:(CLLocation*)location;
//this all works
-(Audio*)newAudio;
-(Audio*)newAudioWithPath:(NSString*)audioPath;
//after calling this method, even the log.text changes will be saved to the database.
-(void)addAudioWithPath:(NSString*)audioPath;
-(void)removeAudio:(Audio*)audio;
#end
#import "Log.h"
#import "Audio.h"
#import "LTLogStore.h"
#implementation Log
-(CLLocation*)location{
if (!self.longitude || !self.latitude) {
return nil;
}
CLLocation *l = [[CLLocation alloc] initWithLatitude:[self.latitude doubleValue] longitude:[self.longitude doubleValue]];
return l;
}
-(void)setLocation:(CLLocation*)location{
if (location==nil) {
self.latitude = nil;
self.longitude = nil;
}
self.latitude = [NSNumber numberWithDouble: location.coordinate.latitude];
self.longitude = [NSNumber numberWithDouble:location.coordinate.longitude];
[[LTLogStore sharedStore] saveChanges];
}
-(Audio*)newAudio{
Audio *a = [Audio new];
a.log = self;
return a;
}
-(Audio*)newAudioWithPath:(NSString*)audioPath{
Audio *new = [self newAudio];
[new setKey:audioPath];
return new;
}
-(void)addAudioWithPath:(NSString*)audioPath{
Audio *new = [self newAudio];
[new setKey:audioPath];
[[LTLogStore sharedStore] saveChanges];
}
-(void)removeAudio:(Audio*)audio{
[self.audiosSet removeObject:audio];
[[[LTLogStore sharedStore] context] deleteObject:audio];
[[LTLogStore sharedStore] saveChanges];
}
#end
UPDATE:
Problem solved, see answer.
UPDATE QUESTION: Why is my overriding causing the problem? Can someone explain the cause behind the magic of Core Data or maybe KVO behind scene?
Problem solved, I overrode the willChangeValueForKey method in the Log class, which caused the problem, I thought the code is irrelevant. But it IS:
- (void)willChangeValueForKey:(NSString *)key{
//I added the following line to fix my problem
[super willChangeValueForKey:key];
//this is the original line, I want to have this
//because I want to have a isBlank property
//so I can see if the user modified the log
_isBlank = false;
//I tried to also add the following line to be safe.
//turns out this line is not needed, and it will make the problem occur again
//[super didChangeValueForKey:key];
}

Updating a managedObject in Core Data

WHAT I HAVE SO FAR:
In one splitview, I have a a tableview as its master, and a UIView as the detail. The tableview has 2 columns: "Days" and then "Sessions". I get the data from the Core Data, the entities called "Sessions". When I click on a "Session" tableviewcell, the detailview gets updated.
In the detailview, I added an "Add" button in the navigation bar. When you click on this, I add a new entity called "NewSession" to the core data.
if ([_sessionData.added isEqualToNumber:[NSNumber numberWithBool:NO]]) {
[_sessionData setValue:[NSNumber numberWithBool:YES] forKey:#"added"];
SessionData *session = (SessionData*) [NSEntityDescription insertNewObjectForEntityForName:#"NewSessions" inManagedObjectContext:[DataSingleton sharedMySingleton].managedObjectContext];
session.startDate = _sessionData.startDate;
session.endDate = _sessionData.endDate;
session.sessionLocation = nil;
session.sessionTitle = _sessionData.sessionTitle;
session.sessionDescription = _sessionData.sessionDescription;
[session setValue: [NSNumber numberWithBool:YES] forKey:#"added"];
_addButton = [[[UIBarButtonItem alloc] initWithTitle:#"Remove" style:UIBarButtonSystemItemAdd target:self action:nil] autorelease];
NSError *error = nil;
if (![[DataSingleton sharedMySingleton].managedObjectContext save:&error]) {
DebugLog(#"Whoops, couldn't save:%#", [error localizedDescription]);
}
}
else {
NSLog(#"SESSION ALREADY ADDED");
}
ANOTHER splitview's tableview fetches the "NewSession" entity, and gets all the data and displays it.
THE PROBLEM:
Whenever I exit the application and relaunch it, the sessions in the other splitview are still there, BUT I can add the SAME session again.
In the "add" code, I have the following:
[_sessionData setValue:[NSNumber numberWithBool:YES] forKey:#"added"];
Now, my sessionData is an NSManagedObject; and I thought that just setting the values will update them in the core data.
Can anyone help?
I had similar problem, but similar doesn't mean the same. I don't know if it works for you but you can try it. This method was described to me by #macbirdie and it works for me.
First of all, import your AppDelegate header file:
#import "YourAppDelegate.h"
Then, update your code:
if ([_sessionData.added isEqualToNumber:[NSNumber numberWithBool:NO]]) {
[_sessionData setValue:[NSNumber numberWithBool:YES] forKey:#"added"];
NSManagedObjectContext *moc = [[DataSingleton sharedMySingleton] managedObjectContext];
SessionData *session = (SessionData*) [NSEntityDescription insertNewObjectForEntityForName:#"NewSessions" inManagedObjectContext:moc];
session.startDate = _sessionData.startDate;
session.endDate = _sessionData.endDate;
session.sessionLocation = nil;
session.sessionTitle = _sessionData.sessionTitle;
session.sessionDescription = _sessionData.sessionDescription;
session.added = [NSNumber numberWithBool:YES];
_addButton = [[[UIBarButtonItem alloc] initWithTitle:#"Remove" style:UIBarButtonSystemItemAdd target:self action:nil] autorelease];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveMoc:) name:NSManagedObjectContextDidSaveNotification object:moc];
NSError *error = nil;
if (![moc save:&error]) {
DebugLog(#"Whoops, couldn't save:%#", [error localizedDescription]);
}
} else {
NSLog(#"SESSION ALREADY ADDED");
}
And add this methode somewhere in your file:
- (void)saveMoc:(NSNotification *)notification {
YourAppDelegate *appDel = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDel.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}