Hi,
I have two entities which I modeled as classes and core data model entities too/ The classes look as follows:
Class: StateManager
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "StateManager.h"
#import "Constants.h"
@implementation StateManager
@synthesize deviceID, physicalID, applicationName, applicationVersion;
@synthesize userName, userPassword, server, port, client, language, protocol;
-(bool)checkCompleteness{
if (physicalID == nil) {
return false;
}
if (applicationName == nil) {
return false;
}
if (applicationVersion == nil) {
return false;
}
if (userName == nil) {
return false;
}
if (userPassword == nil) {
return false;
}
if (port == nil) {
return false;
}
if (server == nil) {
return false;
}
return true;
}
-(void)preserveState:(NSManagedObjectContext *)managedObjectContext{
// Step 1: Create Object
StateManager *inMemoryState = (StateManager *)[NSEntityDescription
insertNewObjectForEntityForName:ENTITY_STATE
inManagedObjectContext:managedObjectContext];
// Step 2: Set Properties
[inMemoryState setDeviceID:self.deviceID];
[inMemoryState setPhysicalID:self.physicalID];
[inMemoryState setApplicationName:self.applicationName];
[inMemoryState setApplicationVersion:self.applicationVersion];
//[inMemoryState setAutoRegister:[self getAutoRegister]];
[inMemoryState setUserName:self.userName];
[inMemoryState setUserPassword:self.userPassword];
[inMemoryState setServer:self.server];
[inMemoryState setPort:self.port];
[inMemoryState setClient:self.client];
[inMemoryState setLanguage:self.language];
[inMemoryState setProtocol:self.protocol];
// Step 3: Save Object
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(StateManager *)loadState:(NSManagedObjectContext *)managedObjectContext{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:ENTITY_STATE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *items = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
if ([items count] > 0) {
StateManager *inDatabaseState = (StateManager *)[items objectAtIndex:0];
deviceID = [inDatabaseState valueForKey:@"deviceID"];
physicalID = [inDatabaseState valueForKey:@"physicalID"];
applicationName = [inDatabaseState valueForKey:@"applicationName"];
applicationVersion = [inDatabaseState valueForKey:@"applicationVersion"];
//autoRegister = [inDatabaseState valueForKey:@"autoRegister"];
userName = [inDatabaseState valueForKey:@"userName"];
userPassword = [inDatabaseState valueForKey:@"userPassword"];
server = [inDatabaseState valueForKey:@"server"];
port = [inDatabaseState valueForKey:@"port"];
client = [inDatabaseState valueForKey:@"client"];
language = [inDatabaseState valueForKey:@"language"];
protocol = [inDatabaseState valueForKey:@"protocol"];
[inDatabaseState release];
}
[fetchRequest release];
[entityState release];
[items release];
/*
deviceID = @"1234";
physicalID = @"12312";
applicationName = @"erwerw";
applicationVersion = @"applicationVersion";
//autoRegister = [inDatabaseState valueForKey:@"autoRegister"];
userName = @"userName";
userPassword = @"userPassword";
server = @"server";
port = @"port";
client = @"client";
language = @"language";
protocol = @"protocol";*/
return self;
}
-(void)dealloc{
[deviceID release];
[physicalID release];
[applicationName release];
[applicationVersion release];
[userName release];
[userPassword release] ;
[server release];
[port release];
[client release];
[language release];
[protocol release];
[super dealloc];
}
@end
Class: InboundQueueState
#import "InQueueState.h"
@implementation InQueueState
@dynamic top;
@dynamic read;
@dynamic last;
@end
Now I am trying to load these objects data from DB into my application at two different places as shown below:
If you look into the class StateManager you will see a method loadState which tries to read the entity "StateManager" using a managed object context. This context was passed to this class from the main class.
Another method "readQueue" as shown below in class "InboundQueue" tries to follow the same paradigm of loading the entity "InboundState" using the global managed object context but fails with an error given below: Error: [NSFetchRequest objectID]: unrecognized selector sent to instance 0x3a1a300 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '** -[NSFetchRequest objectID]: unrecognized selector sent to instance 0x3a1a300'*
Class:InboundQueue
#import "InboundQueue.h"
#import <CoreData/CoreData.h>
#import "Constants.h"
#import "InQueueItem.h"
@implementation InboundQueue
-(int)last{
return [queueState last];
}
-(int)top{
return [queueState top];
}
-(int)read{
return [queueState read];
}
-(InboundQueue *)initInboundQueue:(NSManagedObjectContext *)managedObjectContext{
//load the inbound queue counters and initialize the inbound queue object with the values
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:INQUEUE_STATE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *msgs = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
if ([msgs count] > 0) {
queueState = [msgs objectAtIndex:0]; //contains the values of the counters related to inbound queue at any point in time
}
[fetchRequest, entityState, msgs release];
return self;
}
-(NSMutableArray *)readQueue:(NSManagedObjectContext*) managedObjectContext{
//load the inbound queue counters and initialize the inbound queue object with the values
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityState = [NSEntityDescription entityForName:INQUEUE
inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityState];
NSError *error;
NSArray *queueContent = [managedObjectContext
executeFetchRequest:fetchRequest error:&error];
[queueData setArray:queueContent];
[fetchRequest, entityState, error release];
return queueData;
}
-(void)confirm:(int)msgID managedObjectContext:(NSManagedObjectContext*) managedObjectContext{
if (msgID < [queueState top]) {
return;
}
if (msgID > [queueState last]) {
return;
}
//remove items from queue which are lower than the confrmed message ID
for (InQueueItem *item in queueData) {
int currentMsgId = [item MSG_ID];
if ( currentMsgId <= msgID) {
//delete the item from queue and adjust counters
[queueData removeObject:item];
}
}
[queueState setTop:(msgID + 1)];
if ([queueState read] < [queueState top]) {
[queueState setRead:[queueState top]]; //realign the top counter
}
//persist the changes from context to database
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(void)add:(InQueueItem *)item managedObjectContext:(NSManagedObjectContext*) managedObjectContext{
//validate the message id
if (([queueState last] > ([item MSG_ID] - 1))) {
//ignore this message since we have already received a message with this message id
}else if (([queueState last] < ([item MSG_ID] - 1))) {
//raise an invalid message ID exception => data loss
}else {
if ([queueState last] == 0) {
//need to initialize counters as this is the first entry
[queueState setTop:[item MSG_ID]];
[queueState setLast:[item MSG_ID]];
}else {
//increment last
[queueState setLast:([queueState last] + 1)];
}
//now insert the item into queue
[queueData addObject:item];
}
//persist the changes from context to database
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"Unresolved Core Data Save error %@, %@", error, [error userInfo]);
exit(-1);
}
}
-(void)dealloc{
[queueData release];
[queueState release];
[super dealloc];
}
@end
My understanding is that same managed object context can load all the objects of the data model and allows manipulation, but i am not sure why in my case it only works for one object only.