CoreData - could not locate an NSManagedObjectModel - objective-c

I'm getting the error below, I don't know what I'm doing wrong.
I guess there is the managedobject which cannot be located, but... arf !
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Boxes''
here is my .m ( only the two main functions )
- (void)loadCoreData
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"Test" object:self];
context = [app managedObjectContext];
NSError *err;
// GET THE JSON
NSString *urlString = [NSString stringWithFormat:#"http://localhost:8888/json.txt"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
NSMutableArray *json = (NSMutableArray* )[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
// FILL THE ENTITY
for (int i = 0; i != 7; i++)
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes" inManagedObjectContext:context];
boxes.name = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"name"] ;
boxes.sexe = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"sexe"] ;
boxes.topic = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"topic"] ;
boxes.number = [NSNumber numberWithInt:[[[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"number"] intValue]];
}
request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Boxes" inManagedObjectContext:context];
[request setEntity:entity];
arrayForPredicate = [context executeFetchRequest:request error:&err];
}
- (void) fillSexArray:(NSString *)sexe
{
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH SEXE EQUAL TO
NSPredicate *sex;
if ([sexe isEqualToString:#"both"])
{
sex = [NSPredicate predicateWithFormat:#"sexe = %# OR sexe = %#", #"female", #"male"];
}
else
{
sex = [NSPredicate predicateWithFormat:#"sexe = %#", sexe];
}
NSArray *BoxWithSex = [arrayForPredicate filteredArrayUsingPredicate:sex];
NSMutableArray *mutableArray = [self createMutableArray:BoxWithSex];
// NSLog(#"%#", [[mutableArray objectAtIndex:1] valueForKey:#"name"]);
// NSUInteger numObjects = [mutableArray count];
}
my .h :
#interface AddViewController : UIViewController
{
IBOutlet UIButton *male;
IBOutlet UIButton *female;
IBOutlet UIButton *couple;
UIButton *maleBtn;
BOOL flag;
NSArray *arrayForPredicate;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *context;
NSFetchRequest *request;
}
#property (nonatomic, retain) WonderAppDelegate *app;
- (void) fillSexArray:(NSString *)sexe;
- (NSMutableArray *)createMutableArray:(NSArray *)array;
- (void)loadCoreData;
- (void)sexeButtonPressed;
- (void)sexeArray;
#end
EDIT creating the managedObject :
+ (id)boxWithDictionary:(NSDictionary *)dict withManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes"
inManagedObjectContext:managedObjectContext];
boxes.name = [dict objectForKey:#"name"];
boxes.sexe = [dict objectForKey:#"sexe"];
boxes.topic = [dict objectForKey:#"topic"];
boxes.number = [dict objectForKey:#"number"];
return boxes;
}
This is my .m and it is working like that but i don't want the code of the function Add there i want it on loadCoreData.
//
// AddViewController.m
// CoreDataTuto
//
// Created by Clement Yerochewski on 30/04/12.
// Copyright (c) 2012 Weblib. All rights reserved.
//
#import "AddViewController.h"
#import "Boxes.h"
#implementation AddViewController
#synthesize app, context;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 768, 44)];
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:#"Add Detail"];
[navBar pushNavigationItem:navItem animated:NO];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancel)];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonItemStyleBordered target:self action:#selector(add)];
navItem.leftBarButtonItem = cancelButton;
navItem.rightBarButtonItem = addButton;
[self.view addSubview:navBar];
app = [[UIApplication sharedApplication] delegate];
}
return self;
}
- (void) add{
[self dismissModalViewControllerAnimated:YES];
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH A LENGTH NAME <= 5
// NSPredicate *length;
// length = [NSPredicate predicateWithFormat:#"name.length <= 5"];
// NSArray *BoxWithCheapPrice = [array filteredArrayUsingPredicate:length];
// NSLog(#"Box %#", BoxWithCheapPrice);
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH PRICE BETWEEN $MIN AND $MAX
// NSNumber *min = [NSNumber numberWithInteger:30];
// NSNumber *max = [NSNumber numberWithInteger:100];
// NSPredicate *between;
// between = [NSPredicate predicateWithFormat:#"number BETWEEN %#", [NSArray arrayWithObjects:min, max, nil]];
// NSArray *BoxWithPriceBetween = [array filteredArrayUsingPredicate:between];
// NSLog(#"Box %#", BoxWithPriceBetween);
// NSLog(#"%#", [BoxWithPriceBetween valueForKey:#"name"]);
}
- (NSMutableArray *)createMutableArray:(NSArray *)array
{
return [NSMutableArray arrayWithArray:array];
}
- (IBAction) sexeChoosen: (id) sender
{
switch ( ((UIButton*)sender).tag ){
case 0:
[self fillSexArray:#"male"];
break;
case 1:
[self fillSexArray:#"female"];
break;
default:
[self fillSexArray:#"both"];
}
[self sexeButtonPressed];
}
- (void)sexeButtonPressed
{
if (flag)
{
UIImage * maleImg2 = [UIImage imageNamed:#"pressed.png"];
[maleBtn setImage:maleImg2 forState:UIControlStateNormal];
flag = NO;
[self sexeArray];
}
else
{
UIImage * maleImg1 = [UIImage imageNamed:#"unpressed.png"];
[maleBtn setImage:maleImg1 forState:UIControlStateNormal];
flag = YES;
[self sexeArray];
}
}
- (void)sexeArray
{
}
- (void)loadCoreData
{
}
- (void) fillSexArray:(NSString *)sexe
{
context = [app managedObjectContext];
// GET THE JSON
NSString *urlString = [NSString stringWithFormat:#"http://localhost:8888/json.txt"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
NSError *err;
NSMutableArray *json = (NSMutableArray* )[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
// FILL THE ENTITY
for (int i = 0; i != 7; i++)
{
Boxes *boxes = [NSEntityDescription insertNewObjectForEntityForName:#"Boxes" inManagedObjectContext:context];
boxes.name = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"name"] ;
boxes.sexe = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"sexe"] ;
boxes.topic = [[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"topic"] ;
boxes.number = [NSNumber numberWithInt:[[[[json valueForKey:#"boxesDetail"] objectAtIndex:i] valueForKey:#"number"] intValue]];
}
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Boxes" inManagedObjectContext:context];
[request setEntity:entity];
arrayForPredicate = [context executeFetchRequest:request error:&err];
NSPredicate *sex;
// PREDICATE TO GET AN ARRAY OF PRODUCT WITH SEXE EQUAL TO
if ([sexe isEqualToString:#"both"])
{
sex = [NSPredicate predicateWithFormat:#"sexe = %# OR sexe = %#", #"female", #"male"];
}
else
{
sex = [NSPredicate predicateWithFormat:#"sexe = %#", sexe];
}
NSArray *BoxWithSex = [arrayForPredicate filteredArrayUsingPredicate:sex];
NSMutableArray *mutableArray = [self createMutableArray:BoxWithSex];
NSLog(#"SEXE CHOOSEN %#", mutableArray);
// NSLog(#"%#", [[mutableArray objectAtIndex:1] valueForKey:#"name"]);
NSUInteger numObjects = [mutableArray count];
NSLog(#"%d", numObjects);
}
- (void) cancel{
[self dismissModalViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
flag = YES;
maleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
maleBtn.frame = CGRectMake(40, 47, 107, 75);
[maleBtn setTitle:#"male" forState:UIControlStateNormal];
UIImage * maleImg1 = [UIImage imageNamed:#"unpressed.png"];
[maleBtn setImage:maleImg1 forState:UIControlStateNormal];
[maleBtn addTarget:self action:#selector(sexeChoosen:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:maleBtn];
[self loadCoreData];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

Have you updated your model after creating the persistent store? Try to delete your app from the simulator (or the database file) and run it again..

Related

UICollectionViewController with NSFetchedResultsController broke, when update property of all objects, if controller sorted on this property

I have UICollectionViewController , It is collection view for some Objects at the map. So, I can update one item in fetched result (for example set LIKE for one of this Object). It is work well. I see changes immediately.
But if trying to update property "Distance" of all Objects, and same time controller are sorted on this property. Fetched result doesn't updated automatically. And then, while scrolling, reused Cells not updated, and I can see only Cells, that was on display, before I was started update property for all Objects. If I TouchUpInside first Cell in a row, for example it would be Object 123, controller open detail page of different Object, that Object, that should stay at this position after collectionView reloadData.
Incase I'm change Sort Descriptors from [fetchRequest setSortDescriptors:#[distanceAscending]];
to [fetchRequest setSortDescriptors:#[titleAscending]];
or [fetchRequest setSortDescriptors:#[titleAscending, distanceAscending]];
It is work well.
Incase I'm change property "Distance" of only one Object.
It is work well. Controller sort Cells as it should.
Incase I'm change property "Distance" of Objects not fetched this time.
It is work well.
Incase I'm close this controller, and open again [fetchRequest setSortDescriptors:#[distanceAscending]]; working as it should
I'm tying to reload CollectionViewController different ways,
[self.collectionView reloadData]; and reloadwithPredicateDefault. But same result.
I'm tying to change Managed Object Context NSPrivateQueueConcurrencyType and NSMainQueueConcurrencyType. But same result.
MapObjectCollectionViewController.h
#interface MapObjectCollectionViewController : UICollectionViewController
MapObjectCollectionViewController.m
#interface MapObjectCollectionViewController ()<NSFetchedResultsControllerDelegate>
#property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
#property (strong, nonatomic) NSManagedObjectContext* managedObjectContext;
#property (strong, nonatomic) NSPredicate * predicate1;
#property (strong, nonatomic) NSPredicate * predicate2;
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription* description =
[NSEntityDescription entityForName:#"MapObj"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:description];
_predicate1 = [NSPredicate predicateWithFormat:#"types.typeObjValue IN %#", self.selectionsTypes];
_predicate2 = [NSPredicate predicateWithFormat:#"wiFi >= %i", 0];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[_predicate1, _predicate2]];
[fetchRequest setPredicate:predicate];
NSSortDescriptor* titleAscending = [[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES];
NSSortDescriptor* distanceAscending = [[NSSortDescriptor alloc] initWithKey:#"distance" ascending:NO];
[fetchRequest setSortDescriptors:#[distanceAscending]];
// [fetchRequest setSortDescriptors:#[titleAscending, distanceAscending]];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSMutableDictionary *change = [[NSMutableDictionary alloc] init];
switch(type) {
case NSFetchedResultsChangeInsert:
change[#(type)] = newIndexPath;
break;
case NSFetchedResultsChangeDelete:
change[#(type)] = indexPath;
break;
case NSFetchedResultsChangeUpdate:
change[#(type)] = indexPath;
break;
case NSFetchedResultsChangeMove:
change[#(type)] = #[indexPath, newIndexPath];
break;
}
[_itemChanges addObject:change];
}
- (void)reloadwithPredicateDefault {
[NSFetchedResultsController deleteCacheWithName:nil];
self.fetchedResultsController = nil;
[self.fetchedResultsController performFetch:nil];
[self.collectionView reloadData];
}
#pragma mark - UICollectionViewDataSource
- (NSManagedObjectContext*) managedObjectContext {
if (!_managedObjectContext) {
_managedObjectContext = [[DataManager sharedManager] managedObjectContext];
}
return _managedObjectContext;
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{
[self.collectionView performBatchUpdates:^{
for (NSDictionary *change in self->_sectionChanges) {
[change enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSFetchedResultsChangeType type = [key unsignedIntegerValue];
switch(type) {
case NSFetchedResultsChangeInsert:
[self.collectionView insertSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]];
break;
case NSFetchedResultsChangeDelete:
[self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]];
break;
case NSFetchedResultsChangeMove:
break;
case NSFetchedResultsChangeUpdate:
break;
}
}];
}
for (NSDictionary *change in self->_itemChanges) {
[change enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSFetchedResultsChangeType type = [key unsignedIntegerValue];
switch(type) {
case NSFetchedResultsChangeInsert:
[self.collectionView insertItemsAtIndexPaths:#[obj]];
break;
case NSFetchedResultsChangeDelete:
[self.collectionView deleteItemsAtIndexPaths:#[obj]];
break;
case NSFetchedResultsChangeUpdate:
[self.collectionView reloadItemsAtIndexPaths:#[obj]];
break;
case NSFetchedResultsChangeMove:
[self.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]];
break;
}
}];
}
} completion:^(BOOL finished) {
self->_sectionChanges = nil;
self->_itemChanges = nil;
}];
}
DataManager.h
#property (readonly, strong, nonatomic) NSManagedObjectContext *mainPrivateManagedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
+ (DataManager*)sharedManager;
DataManager.m
#implementation DataManager
#synthesize mainPrivateManagedObjectContext = _mainPrivateManagedObjectContext;
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
+(DataManager*) sharedManager{
static DataManager* manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[DataManager alloc] init];
});
return manager;
}
#pragma mark - Core Data stack
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"ProjectName" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"ProjectName.sqlite"];
NSError *error = nil;
// NSString *failureReason = #"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES} error:&error]) {
NSLog(#"error = %#", error);
// Report any error we got.
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]; //Удалить старую базу
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]; //Создать базу заново
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
// . NSLog(#"get managedObjectContext");
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_mainPrivateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_mainPrivateManagedObjectContext setPersistentStoreCoordinator:coordinator];
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setParentContext:_mainPrivateManagedObjectContext];
// . NSLog(#"get return managedObjectContext");
return _managedObjectContext;
}
- (NSManagedObjectContext *)getContextForBGTask {
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:self.managedObjectContext];
return context;
}
- (NSArray*) allMapObj {
NSFetchRequest* request = [[NSFetchRequest alloc] init];
NSEntityDescription* description =
[NSEntityDescription entityForName:#"MapObj"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:description];
NSError* requestError = nil;
NSArray* resultArray = [self.managedObjectContext executeFetchRequest:request error:&requestError];
if (requestError) {
NSLog(#"%#", [requestError localizedDescription]);
}
return resultArray;
}
- (void)calculateDistanceWithCurrentLoaction:(CLLocation*) currentLoaction{
NSFetchRequest* request = [[NSFetchRequest alloc] init];
NSManagedObjectContext * bgcontext = [self getContextForBGTask];
NSEntityDescription* description =
[NSEntityDescription entityForName:#"MapObj"
inManagedObjectContext:bgcontext];
[request setEntity:description];
NSError* requestError = nil;
NSArray* resultArray = [bgcontext executeFetchRequest:request error:&requestError];
if (requestError) {
NSLog(#"%#", [requestError localizedDescription]);
}
for (MapObj *mapObject in resultArray) {
CLLocation *endLocation = [[CLLocation alloc] initWithLatitude:[mapObject.latitude doubleValue] longitude:[mapObject.longitude doubleValue]];
CLLocationDistance distance = [currentLoaction distanceFromLocation:endLocation];
mapObject.distance = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%f", distance]];
}
[bgcontext updatedObjects];
[self saveContextForBGTask:bgcontext];
}
- (void)saveContextForBGTask:(NSManagedObjectContext *)bgTaskContext {
if (bgTaskContext.hasChanges) {
[bgTaskContext performBlockAndWait:^{
NSError *error = nil;
[bgTaskContext save:&error];
}];
// Save default context
[self saveDefaultContext:YES];
}
}
- (void)saveDefaultContext:(BOOL)wait {
if (_managedObjectContext.hasChanges) {
[_managedObjectContext performBlockAndWait:^{
// . NSLog(#"managed context = %#", _managedObjectContext);
NSError *error = nil;
[self->_managedObjectContext save:&error];
}];
}
void (^saveMainPrivateManagedObjectContext) (void) = ^{
NSError *error = nil;
[self->_mainPrivateManagedObjectContext save:&error];
};
if ([_mainPrivateManagedObjectContext hasChanges]) {
if (wait){
// . NSLog(#"main context = %#", _mainPrivateManagedObjectContext);
[_mainPrivateManagedObjectContext performBlockAndWait:saveMainPrivateManagedObjectContext];
} else {
[_mainPrivateManagedObjectContext performBlock:saveMainPrivateManagedObjectContext];
}
}
}
Error in console:
2019-09-28 12:35:14.951873+0400 ProjectName[15695:4020487] *** Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore/UIKit-3698.140/UICollectionView.m:5972
CoreData: fault: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to perform an insert and a move to the same index path (<NSIndexPath: 0xa945f4d4afea737e> {length = 2, path = 0 - 4}) with userInfo (null)
What did I missed?
As a simple solution, was added:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{
[self.collectionView performBatchUpdates:^{
......
if(self->_itemChanges.count > 1){
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} else {
for (NSDictionary *change in self->_itemChanges) {
...
}
}
......
}

Implementing Spotlight feature using NSMetaDataQuery and NStableView Data Source Method

I have implemented spotlight feature in my project using NSMetadataQuery. On receiving NSMetadataQueryDidFinishGatheringNotification Notification I am calling reloadData method of tableView method after formatting the NSMetadataItem of NSMetadataQuery. I am facing below two issues.
[query startQuery] is taking too much time when there is huge data in mac.
Not getting NSMetadataQueryDidUpdateNotification;
Search is fast when I ma using NSArrayController instead of NStableViewDataSource and binding it with query.results. As I need to format the NSMetadataItem so i can't use it.
Can anyone answer how to receive batch notification for better performance of NSMetaDataQuery. or any other way to improve the performance of [query startQuery]
Below is code which I have implemented.
- (void)initiateSearch:(NSString *)seString
{
self.metadataSearch=[[[NSMetadataQuery alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(queryDidUpdatesfsdf:)
name:NSMetadataQueryDidUpdateNotification
object:metadataSearch];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(initalGatherComplete:)
name:NSMetadataQueryDidFinishGatheringNotification
object:metadataSearch];
NSArray *terms = [seString componentsSeparatedByString:#","];
NSMutableArray *pridicateArray = [NSMutableArray array];
NSPredicate *searchPredicate;
for(NSString *term in terms) {
if([term length] == 0)
{
continue;
}
NSString *trimmedString = [[NSString alloc] initWithFormat:#"*%#*",[term stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSPredicate *p = [NSPredicate predicateWithFormat:#"(kMDItemFSName like[cd] %#)",trimmedString];
[pridicateArray addObject:p];
[trimmedString release];
}
if ([pridicateArray count] == 1) {
searchPredicate= [pridicateArray objectAtIndex:0];
}
else
{
searchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:pridicateArray];
}
[metadataSearch setPredicate:searchPredicate];
NSArray *searchScopes;
searchScopes=[NSArray arrayWithObjects:NSMetadataQueryUserHomeScope,nil];
[metadataSearch setSearchScopes:searchScopes];
NSSortDescriptor *sortKeys=[[[NSSortDescriptor alloc] initWithKey:(id)kMDItemDisplayName
ascending:YES] autorelease] ;
[metadataSearch setSortDescriptors:[NSArray arrayWithObject:sortKeys]];
[metadataSearch setNotificationBatchingInterval:5.0];
[metadataSearch startQuery];
}
- (void)queryDidUpdatesfsdf:sender;
{
NSLog(#"A data batch has been received");
}
- (void)initalGatherComplete:sender;
{
[metadataSearch stopQuery];
p_Thread = [[NSThread alloc] initWithTarget:self selector:#selector(dosome:) object:metadataSearch];
[p_Thread start];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidUpdateNotification
object:metadataSearch];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:metadataSearch];
}
-(void)dosome: (NSMetadataQuery *)metadataresult
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
fileListArray = [[NSMutableArray alloc] init];
[fileListArray removeAllObjects];
NSUInteger i=0;
for (i=0; (i < [metadataresult resultCount] && ![p_Thread isCancelled]); i++) {
NSMetadataItem *theResult = [metadataresult resultAtIndex:i];
NSString *displayName = [theResult valueForAttribute:(NSString *)kMDItemFSName];
NSString *displayPath = [theResult valueForAttribute:(NSString *)kMDItemPath];
NSString *fileSize = [theResult valueForAttribute:(NSString *)kMDItemFSSize];
FileList *fileList = [[FileList alloc] init];
[fileList setName:displayName];
[fileList setIsChecked:NO];
[fileList setPath:displayPath];
[fileList setLastModified:[dateFormatter stringFromDate:[theResult valueForAttribute:(NSString *)kMDItemContentModificationDate]]];
[fileList setFileSize:[IBUtility formatedFileSizeForOutlineView:fileSize]];
[fileList setMSize:[fileSize longLongValue]];
[[self fileListArray] addObject:fileList];
if (i%50 == 0 && ![p_Thread isCancelled]) {
[searhFinderTableView performSelectorOnMainThread:#selector(reloadData) withObject:Nil waitUntilDone:YES];
}
}
self.metadataSearch=nil;
if ([[self fileListArray] count] == 0) {
[mSearchingLabel setStringValue:#"Items not found"];
NSRect textFieldFrame = [mSearchingLabel frame];
[mSearchingLabel setFrame:NSMakeRect(mContinuousProgress.frame.origin.x,textFieldFrame.origin.y, textFieldFrame.size.width,textFieldFrame.size.height)];
}
else if(![p_Thread isCancelled])
{
[searhFinderTableView performSelectorOnMainThread:#selector(reloadData) withObject:Nil waitUntilDone:YES];
[mSearchingLabel setHidden:YES];
}
[mContinuousProgress stopAnimation:self];
[dateFormatter release];
[pool release];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [fileListArray count];
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
FileList *fileList = [fileListArray objectAtIndex:rowIndex];
if ([[aTableColumn identifier] isEqualToString:#"filePath"])
{
return [fileList valueForKey:#"path"];
}
else if([[aTableColumn identifier] isEqualToString:#"isSelected"])
{
return [NSNumber numberWithBool:fileList.isChecked];
}
else if([[aTableColumn identifier] isEqualToString:#"fileSize"])
{
return [fileList valueForKey:#"fileSize"];
}
else if([[aTableColumn identifier] isEqualToString:#"lastModified"])
{
return [fileList valueForKey:#"lastModified"];
}
return nil;
}

Page View Controller: UILabel and UIImageview empty on first page

I'm using a UIPageViewController to display items from a JSON file. It works fine except for the first page which displays nothing on loading, but if I come back, it works.
Code is as follows:
#import "SJPagesViewController.h"
#import "SJChildViewController.h"
#interface SJPagesViewController ()
#end
#implementation SJPagesViewController
#synthesize urlToFollow, data,articlesArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
...
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
CGFloat window_height = ([self window_height]-30.0);
CGFloat window_width = [self window_width];
CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);
self.pageController.dataSource = self;
[[self.pageController view] setFrame:pageFrame];
SJChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
//Download JSON
NSError *error=nil;
NSURL *url = [NSURL URLWithString:urlToFollow];
data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *response = [dictionary objectForKey:#"items"];
articlesArray = [[NSArray alloc] initWithArray:response];
//NSLog(#"articlesArray = %#", articlesArray);
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [(SJChildViewController *)viewController index];
if (index == 0) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(SJChildViewController *)viewController index];
index++;
if (index == articlesArray.count) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (CGFloat) window_height {
return [UIScreen mainScreen].applicationFrame.size.height;
}
- (CGFloat) window_width {
return [UIScreen mainScreen].applicationFrame.size.width;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (SJChildViewController *)viewControllerAtIndex:(NSUInteger)index {
SJChildViewController *childViewController = [[SJChildViewController alloc] initWithNibName:#"SJChildViewController" bundle:nil];
childViewController.index = index;
childViewController.arrayCount = self.articlesArray.count;
childViewController.model = [[self.articlesArray objectAtIndex:index]objectForKey:#"modelo"];
childViewController.price = [[self.articlesArray objectAtIndex:index]objectForKey:#"precio"];
childViewController.make = [[self.articlesArray objectAtIndex:index]objectForKey:#"marca"];
childViewController.imageUrl = [[self.articlesArray objectAtIndex:index]objectForKey:#"photoUrl"];
return childViewController;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
if (articlesArray.count >5) {
return 5;
}else return [articlesArray count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
#end
And ChildViewController to display items:
#implementation SJChildViewController
#synthesize activityIndicator,imageUrl,price,model,make;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
....
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Activity indicator
activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
}
-(void)viewDidAppear:(BOOL)animated{
self.scrrenNumber.text = [NSString stringWithFormat:#"Artículo %ld de %ld", ((long)self.index+1), (long)self.arrayCount];
self.lblMake.lineBreakMode = NSLineBreakByWordWrapping;
self.lblMake.text = [NSString stringWithFormat:#"%#",make];
//Donload image
//Download image from url
NSURL *url_1= [NSURL URLWithString:imageUrl];
NSURLRequest *request_1 = [NSURLRequest requestWithURL:url_1];
[NSURLConnection sendAsynchronousRequest:request_1
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
UIImage *img = [UIImage imageWithData:data];
[self.articleImage performSelectorOnMainThread:#selector(setImage:) withObject:img waitUntilDone:YES];
}];
//Activity indicator
self.lblPrice.text = [NSString stringWithFormat:#"%#",price];
self.lblModel.lineBreakMode = NSLineBreakByWordWrapping;
self.lblModel.text = [NSString stringWithFormat:#"%#",model];
[activityIndicator stopAnimating];
}
How can I make it work from the first moment?
Luis, I don't have access to xcode right now but it appears your issue is that you are instantiating childViewController while articlesArray is empty.
In viewDidLoad you are downloading your json file and populating articlesArray after you call your helper method viewControllerAtIndex.
Try downloading your json file and populating the array first like you have here.
//Download JSON
NSError *error=nil;
NSURL *url = [NSURL URLWithString:urlToFollow];
data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *response = [dictionary objectForKey:#"items"];
articlesArray = [[NSArray alloc] initWithArray:response];
Then create your pageViewController and populate it like you did here.
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
CGFloat window_height = ([self window_height]-30.0);
CGFloat window_width = [self window_width];
CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);
self.pageController.dataSource = self;
[[self.pageController view] setFrame:pageFrame];
SJChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];

NSRangeException error... NSDictionary, NSArray, UISearchBar

I am quite new with Objective C and I have been having trouble a a little while and I have been looking over answers, watching tutorials, and I have not been able to find a solution to my problem. Maybe its right in front of my face and I am not seeing it...I think it has something that has to do with the NSRange of my UISearch Bar. But I am not 100% sure.
I am trying to search through array that has the keys of my dictionary of countries, I have set up several NSLogs and I see that the keys are going into the array I have setup to save them in and then i get the error below...
So to my understanding of this, it is counting countryKeys which has 5, so index 4 should exist, should it not? but then it shows 0 .. 3, So I this is why I am thinking i am using NSRange incorrectly. I have watched some UISearchBar and For loop tutorials so far and i am understanding For loops and them better i guess I need to figure out NSRange then.
Let me know if you don't understand my thought process or anything that I mentioned..
Filtered Countries (
ATE,
ARE,
USA,
JAP,
CAN
)
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 3]'
-
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize dictTableView, mySearchBar, countriesInRegion, filteredCountries, isFiltered, regionCodes, countryKey, countryKeys, countryInfo, sortedKeysArray, regionCode, dict1;
- (void)viewDidLoad
{
[super viewDidLoad];
dict1 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"United States",#"US",#"USA", #"NAC", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"USA"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Canada", #"CA", #"CAN", #"NAC", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"CAN"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Japan", #"JP", #"JAP", #"EAS", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"JAP"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"United Arab Emirates", #"AE", #"ARE", #"MEA", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"ARE"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Antigua and Barbuda", #"AG", #"ATE", #"LCN", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"ATE"];
regionCodes = [[NSMutableDictionary alloc] init];
countryKeys = [dict1 allKeys];
NSLog(#"countryKeys %#", countryKeys);
sortedKeysArray = [countryKeys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
for (int i = 0; i < [sortedKeysArray count]; i++) {
countryKey = [sortedKeysArray objectAtIndex:i];
countryInfo = [dict1 objectForKey:countryKey]; // NSLog(#"returning countryKey to countryInfo %#", countryInfo);
regionCode = [countryInfo objectForKey:#"countryRegion"]; // NSLog(#" adding countryRegion Key to regionCode %#", regionCode);
// NSLog(#"the contents of countryInfo is %#", countryInfo);
if (![regionCodes objectForKey:regionCode]) {
countriesInRegion = [[NSMutableArray alloc] init];
[regionCodes setObject:countriesInRegion forKey:regionCode];
[countriesInRegion addObject:countryInfo]; // NSLog(#"if adding countryInfo to initialCountries %#", countryInfo);
}
else{
countriesInRegion = [regionCodes objectForKey:regionCode];
[countriesInRegion addObject:countryInfo]; // NSLog(#"else adding countryInfo to initialCountries %#", countryInfo);
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (isFiltered == NO)
{
return countryInfo.count;
}
else
{
return filteredCountries.count;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *sortKey = [regionCodes allKeys];
sortedKeysArray = [sortKey sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
return [sortedKeysArray objectAtIndex:section];
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
NSString *regionKey = [[regionCodes allKeys] objectAtIndex:section];
countriesInRegion = [regionCodes objectForKey:regionKey];
if (isFiltered == NO)
{
return countriesInRegion.count;
}
else
{
return filteredCountries.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"Cell"];
UILabel *countryNameLabel = [[UILabel alloc] initWithFrame:(CGRectMake(10, 0, 220, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
UILabel *countryAbbrevLabel = [[UILabel alloc] initWithFrame:(CGRectMake(230, 0, 75, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
UILabel *countryIDLabel = [[UILabel alloc] initWithFrame:(CGRectMake(275, 0, 50, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:countryNameLabel];
[cell.contentView addSubview:countryAbbrevLabel];
[cell.contentView addSubview:countryIDLabel];
}
NSArray *regionKeys = [regionCodes allKeys];
NSString *regionKey = [regionKeys objectAtIndex:indexPath.section];
countriesInRegion = [regionCodes objectForKey:regionKey];
NSLog(#"Countries in Region %#", countriesInRegion);
countryInfo = [countriesInRegion objectAtIndex:indexPath.row];
NSArray *subviews = [cell.contentView subviews];
UILabel *nameLabel = [subviews objectAtIndex:0];
UILabel *abbrevLabel = [subviews objectAtIndex:1];
UILabel *idLabel = [subviews objectAtIndex:2];
// NSLog(#"6 - Countries in Region %#", countriesInRegion);
if (isFiltered == NO)
{
nameLabel.text = [countryInfo objectForKey:#"countryName"];
abbrevLabel.text = [countryInfo objectForKey:#"countryAbbrev"];
idLabel.text = [countryInfo objectForKey:#"countryID"];
// NSLog(#"5 - Our list of countries: %#", nameLabel.text);
// NSLog(#"Country Info %#",countryInfo);
}
else
{
nameLabel.text = [filteredCountries objectAtIndex:2];
abbrevLabel.text = [filteredCountries objectAtIndex:1];
idLabel.text = [filteredCountries objectAtIndex:0];
NSLog(#"4 - Here are your results: %#", filteredCountries);
}
return cell;
}
#pragma mark - UISearchBarDelegate Methods
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length == 0) {
isFiltered = NO;
}
else
{
isFiltered = YES;
NSLog(#"You entered %#", searchText);
filteredCountries = [[NSMutableArray alloc] init];
countryKeys = [dict1 allKeys];
NSLog(#"countryKeys %#", countryKeys);
for (int i = 0; i < countryKeys.count; i++) {
countryKey = [countryKeys objectAtIndex:i];
NSLog(#"country key is %#", countryKey);
{
NSRange countryNameRange = [countryKey rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (countryNameRange.location !=NSNotFound)
{
[filteredCountries addObject:countryKey];
NSLog(#"Filtered Countries %#", filteredCountries);
}
}
}
}
[dictTableView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[mySearchBar resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
That error simply means that you are exceeding the bound of an array.
Specifically at a first sight, I think you got wrong the number of sections and that it doesn't match the number of elements in your array.
I noticed that when filtered is equal to YES you are returning filteredCountries.count for both number of rows and number of sections.
It doesn't look right and I think you should double check you indexes.

NSManagedObjectContext outside the PersistentDocument

I've created a Document Application for Mac OSX to work with CoreDataModel.
Now I'm trying to programmatically save a value in the coredata when a button is clicked.
I'm able to save a value when the app start:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSManagedObjcetContext *moc = [self managedObjectContext];
NSSet *session = [moc fetchObjectsForEntityName:#"Sessions" withPredicate:nil];
NSLog(#"%d", (int)[session count]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:112700] forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
but I want to save a value of a counter inside a NSObject. So I've tried to create a function in the PersistentDocument like the previous passing a value, but the count of the coredata elements is 0, so I think that is not referencing to the correct Entity.
Can anyone explain me how to do that or how this can works?
Thanks
Ale
EDIT:
I'll try to be more clear.
I've a chrono counter with START and STOP button. I want to save the value of the timer, when is stopped, in the coredata using another button SAVE. The managing of the counter is in an NSObject CounterObject.
How can I do it? Now I'm able to write in the core data only from the PersistentDocument caling a function from windowControllerDidLoadNib. I want to call a function that write in the coredata my counter value, but if I call the function in the PersistentDocument from the CounterObject the log that I've inserted show 0 elements instead of 4. So it's not correctly passed.
Here is the code:
// Document
#import "Document.h"
#import "NSManagedObjectContext.h"
#implementation Document
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return #"Document";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[self saveTimeMOC:[NSDate dateWithString:#"11:23:34"]];
}
-(IBAction)saveTimeMOC:(NSDate *)time {
NSManagedObjectContext *moc = [self managedObjectContext];
NSSet *session = [moc fetchObjectsForEntityName:#"Sessions" withPredicate:nil];
NSLog(#"%d", (int)[session count]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:time forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
+ (BOOL)autosavesInPlace
{
return YES;
}
#end
// CounterObject
#import "CounterObject.h"
#import "Document.h"
#implementation CounterObject
#synthesize contText, startButton, stopButton;
-(id)init {
self = [super init];
if (self) {
}
return self;
}
- (IBAction)startContatore:(id)sender {
stopButton.title = #"Stop";
[stopButton setEnabled:YES];
[startButton setEnabled:NO];
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(gestioneTimer) userInfo:nil repeats:YES];
}
- (IBAction)stopContatore:(id)sender {
if (timer != nil) {
[timer invalidate];
timer = nil;
}
if (stopButton.title != #"Reset") {
[startButton setEnabled:YES];
stopButton.title = #"Reset";
startButton.title = #"Continue";
} else if (stopButton.title == #"Reset") {
stopButton.title = #"Stop";
[stopButton setEnabled:NO];
startButton.title = #"Start";
timerCont = 0;
contText.stringValue = [NSString stringWithFormat:#"00:00"];
}
}
- (void)gestioneTimer {
timerCont += 1;
int minutes = floor(timerCont/60);
int seconds = trunc(timerCont - minutes * 60);
contText.stringValue = [NSString stringWithFormat:#"%02i:%02i", minutes, seconds];
}
- (IBAction)saveTime:(id)sender {
Document *moc = [[Document alloc] init];
[moc saveTimeMOC:[NSDate dateWithString:#"13:45:22"]];
}
If you want to add an Object to core data, you can do this :
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSManagedObjcetContext *moc = [self managedObjectContext];
// But be sure that [self managedObjectContext] is the correct one; you can do this to see if //it's not a null value : NSLog(#"%#",[self managedObjectContext]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:112700] forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
And a request for Core Data is :
-(voi)testRequestCoreData {
NSError *error =nil;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Sessions" inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
....
}