views:

326

answers:

3

In my application i am using core-data to store information and saving these data to the server using web-connectivity i have to use MySql.
Basically what i want to do is to keep track of number of NSManagedObject already created and Whenever i am adding new NSManagedObject, based on that counting it will assign the class a Int_value which will act as primary_key in MySql.
For examaple, there are already 10 NSManagedobjects, and when i will add new one it will assign it "11" as primary_key. these value will have to be increasing because there is no deleting of NSManagedObject. From my approach its about static member in applicationDelegate whose initial value can be any integer but should be incremented by one(like auto-increment) everytime new NSManagedObject is created and also it should be persistent. I am not clear how to do this, please give me suggestions. Thanks in advance.

+1  A: 

Create a subclass and implement the -awakeFromInsert and calculate the new value in there and set the property. -awakeFromInsert is only called once in the life of that NSManagedObject instance.

Update

There is a cleaner way to perform this. Consider this code:

- (void)awakeFromInsert
{
  [super awakeFromInesrt];

  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  [request setEntity:[self entity]];
  [request setFetchLimit:1];

  NSArray *propertiesArray = [[NSArray alloc] initWithObjects:@"index", nil];
  [request setPropertiesToFetch:propertiesArray];
  [propertiesArray release], propertiesArray = nil;

  NSSortDescriptor *indexSort = [[NSSortDescriptor alloc] initWithKey:@"index" ascending:YES];
  NSArray *array = [[NSArray alloc] initWithObjects:indexSort, nil];
  [request setSortDescriptors:array];
  [array release], array = nil;
  [indexSort release], indexSort = nil;

  NSError *error = nil;
  NSManagedObject *maxIndexedObject = [[moc executeFetchRequest:request error:&error] lastObject];
  [request release], request = nil;
  NSAssert1(error == nil, @"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]);

  NSInteger myIndex = 1;
  if (maxIndexedObject) {
    myIndex = [[maxIndexObject valueForKey:@"index"] integerValue] + 1;
  }

  [self setValue:[NSNumber numberWithInteger:myIndex] forKey:@"index"];
}

In this example we are fetching the one row which is sorted to be the largest index and telling Core Data to only populate the single property. This makes it the cheapest fetch possible.

As for validation, that is more useful for user entered values as opposed to things you are doing internally. Therefore I would recommend not adding any validation to this property.

Marcus S. Zarra
Thanks Marcus for suggesting my the perfect way for assigning property a unique value, but i am wondering how to calculate new value, means how this subclass will know how many similar managedObjects already have been created(auto incrementing logic).
KayKay
I tried like this- (void)awakeFromInsert { [super awakeFromInsert]; NSNumber *defaultID = [NSNumber numberWithInteger:1]; NSNumber *validID = defaultID; while ( ![self validateValue:} [self setPrimaryKey:validID];}- (BOOL)validatePrimaryKey: (id *)valueRef error:(NSError **)Error{/* i dont have logic to check whether calculated value already exists or not, here i want your help */}
KayKay
Many many thanks Marcus.You are my Savior, if i m getting bit emotional please pardon me as i am hanging with this problem from last one week. It worked for first entry, then second entry and after that it keep repeating index having value 2. I know there is a little bit of lapse and it will work fine.
KayKay
+1  A: 

In NSSortDescriptor set ascending "NO" and it will work 100%.

NSSortDescriptor *indexSort = [[NSSortDescriptor alloc] initWithKey:@"index" ascending:NO];
Kundan Pandit
No thanks..for my omission and for pointing very minor slip and yeah it worked, i appreciate your confidence.
KayKay
+1  A: 

I think there is also a corrigendum or typo error. put NSAssert2 in place of NSAssert1 and it will work all-right.

Kundan Pandit