Core Data Issue - Unable to store NSNumber - objective-c

I am trying to use Core Data in my application. I want to store an attribute "totalKM".
to store my attribute I use these lines:
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
int number = 4;
[event setTotalKM:[NSNumber numberWithDouble:number]];
to read my attribute I use these:
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
NSNumber *number = [event totalKM];
My attribute "totalKM" is always default value, O. And I have no exception. Am i missing something?
Thanks.

insertNewObjectForEntityForNamethis method use to put model to context.
this is a new object.
the right way is:
Set new one
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
int number = 4;
[event setTotalKM:[NSNumber numberWithDouble:number]];
//save change if need
NSError *error = nil;
if (![self.manageObjectContext save:&error]) {
NIDERROR(#"save managedContext error :%#",error);
}
fetch object progress
When you need to get a model form coredate.u need 2 fetch use fetch
like this dome
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Board"
inManagedObjectContext:self.manageObjectContext]];
//set fetch conditions
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"board_id == %#", aBoardID];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *results = [self.manageObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NIDERROR(#"fetch board error.\n board id: %# \n error:%#", aBoardID, error);
return nil;
}
Model *model = results[0];
NSLog(#"%#",model.totalKM)

Related

Core Data update does not save and does not give any error, why?

I am using a very simple piece of code to update an NSManagedObject, but the save does not make it to the persistent store (SQLite). There are no error messages and the logs look ok so I am a little lost.
I have scaled down the code as much as possible to try and isolate the problem as shown below.
The logs tell me that the orderNumber and status are set correctly and also the debug output of the arrays are all correct, but my simple update still fails without any error at all.
+ (int) synchOrderWithStatusUpdate:(NSString *)orderNumber : (int)status {
if ([NWTillHelper isDebug] == 1) {
NSNumber *statusCheck = [NSNumber numberWithInt:status];
NSLog(#"WebServices:synchOrderWithStatusUpdate:ordernumber = %#, status = %d, status2 = %#", orderNumber, status, statusCheck);
}
synchOrderErrorCode = 0;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.persistentContainer.viewContext;
// *** The query for all tables uses orderNumber as selection so we set that up first for re use
NSPredicate *predicateOrderNumber =[NSPredicate predicateWithFormat:#"orderNumber like[cd] %#", [NWTillHelper getCurrentOrderNumber]];
NSFetchRequest *fetchRequestOh = [[NSFetchRequest alloc] initWithEntityName:#"OrderHead"];
NSFetchRequest *fetchRequestOrp = [[NSFetchRequest alloc] initWithEntityName:#"OrderRow"];
NSFetchRequest *fetchRequestTender = [[NSFetchRequest alloc] initWithEntityName:#"Tender"];
fetchRequestOh.predicate = predicateOrderNumber;
fetchRequestOrp.predicate = predicateOrderNumber;
fetchRequestTender.predicate = predicateOrderNumber;
fetchRequestOh.resultType = NSDictionaryResultType;
fetchRequestOrp.resultType = NSDictionaryResultType;
fetchRequestTender.resultType = NSDictionaryResultType;
NSError *errorOh = nil;
NSMutableArray *orderHeads = [[context executeFetchRequest:fetchRequestOh error:&errorOh] mutableCopy];
NSError *errorOrp = nil;
NSArray *orderRows = [[context executeFetchRequest:fetchRequestOrp error:&errorOrp] mutableCopy];
NSError *errorTender = nil;
NSArray *tenderRows = [[context executeFetchRequest:fetchRequestTender error:&errorTender] mutableCopy];
if ([NWTillHelper isDebug] == 1) {
NSLog(#"WebServices:synchOrderWithStatusUpdate:orderHeadsArray: %#", [orderHeads objectAtIndex:0]);
NSLog(#"WebServices:synchOrderWithStatusUpdate:orderRowsArray: %#", orderRows);
NSLog(#"WebServices:synchOrderWithStatusUpdate:tenderRowsArray: %#", tenderRows);
}
// *** Set the status before upload since this dictates what will happen in backend
// *** regardless if synch is successful or not
NSManagedObject *orderHeadObject = nil;
orderHeadObject = [orderHeads objectAtIndex:0];
[orderHeadObject setValue:[NSNumber numberWithInt:status] forKey:#"status"];
// Save the objects to persistent store
NSError *error = Nil;
[context save:&error];
NSLog(#"Jongel Error = %#", error);
if(error !=nil) {
if([NWTillHelper isDebug] == 1) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
synchOrderErrorCode = 99;
}
return 10101;
The orderHeads are fetched as dictionaries. The NSManagedObjectContext will not be aware of any changes made to a dictionary. Only NSManagedObjects will be managed by the NSManagedObjectContext, hence the name ;-)
Try to fetch the orderHeadObject as an NSManagedObject as this will allow you to save the changes back into the store. If you need the dictionary for JSON serialisation: Just fetch it again as a dictionary after you have made the changes. That second fetch will be very fast since all values of the object are already cached, so CoreData won't have to reload from the database.

Core data delete single record from to many relation ship

I have created 4 entities.
User, Mobile, Email, Address.
User have to many relationship (name as numbers) with Mobile.
I have subclass for all of above. How to delete single mobile number from particular user? How to update single mobile number from particular user?,what Predicate use for that?
code is here:
NSManagedObjectContext *context = [self managedObjectContext]; NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:NSStringFromClass([User class])];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY numbers.number == %#",self.textField.text];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [context executeFetchRequest:request error:&error]; Mobile *objMobile;
User *objUser;
objUser = [array objectAtIndex:0];
for (User *obj in [objUser.numbers valueForKey:#"number"]) {
NSLog(#"%#",obj);
NSString *str1 = [NSString stringWithFormat:#"%#",obj];
NSString *str2 = [NSString stringWithFormat:#"%#",self.textDelete.text];
if ([str1 isEqualToString:str2] ) {
[objUser removeNumbersObject:objMobile]; }
}
NSLog(#"%#",[objUser.numbers valueForKey:#"number"]); self.textAddUserDetail.text = #"";
if (![context save:&error]) { }
Basically, don't search based on the user and the relationship. Instead, search directly for the number and then delete it or edit it:
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:NSStringFromClass([Number class])];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"number == %#", self.textField.text];
Then you also don't need a loop and extra consideration of what to do.
It will be useful to use "Magical Records" Library.it work with Key value coding need not to maintain Relationships.it will Automatically get the unique Key From all the Entitys

NSDictionary won't fill up

I have the following piece of code.
-(NSDictionary *)getPlayers
{
NSManagedObjectContext *context = self.genkDatabase.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Team"
inManagedObjectContext:context];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"position ==[c] %#", #"Doelman"];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
}else
for (Team *info in fetchedObjects) {
[_photos setObject:info.image forKey:#"player_imgUrl"];
[_photos setObject:info.name forKey:#"player_name"];
}
NSLog(#"%#",_photos);
return _photos;
But for some reason or another my NSLog always gives (null) back. But when I do this
[_photos setObject:info.image forKey:#"player_imgUrl"];
[_photos setObject:info.name forKey:#"player_name"];
NSLog(#"name: %#",info.name );
NSLog(#"url: %#",info.image );
It gives the right data back.
Can somebody help?
Kind regards.
Make sure you have instantiated your _photos dictionary somewhere with the following line of code:
_photos = [[NSMutableDictionary alloc] init];
Just defining it as an instance variable or a property is not enough.
You have a mistake which may not be directly connected to the issue. In for loop you always reset name and image for the same key. so at the end of the loop your dictionary must have one name and one image, not all the ones from the array. You should change it
UPDATE:probably something like this:
int count = fetchedObjects.count;
for (int i = 0; i < count; i++)
{
NSString *image_key = [NSString stringWithFormat:#"player_imgUrl%d",i];
NSString *name_key = [NSString stringWithFormat:#"player_name%d",i];
[_photos setObject:[[fetchedObjects objectAtIndex:i] image] forKey:image_key];
[_photos setObject:[[fetchedObjects objectAtIndex:i] name] forKey:name_key];
}

Core Data attribute uniqueness

Let's suppose that I download data from a remote web service. To be more precise I download a list of news from a web service, each news have a newsID that we can consider a primary key for the service so we won't find two equal newsID.
How can I can be sure that i insert only the data with a newsID that doesn't already exist?
I've draft my solution with this method:
- (BOOL)validateNewsID:(NSNumber **)newsID error:(NSError **)error
{
NSError *countError = nil;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[self entity]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"newsID == %#", *newsID];
[fetchRequest setPredicate:predicate];
NSUInteger resultCount = [SharedManagedObjectContext countForFetchRequest:fetchRequest error:&countError];
if (countError) {
OLog(countError);
*error = countError;
return NO;
}
if (resultCount > 0) {
NSString *errorString = #"NewsID should be unique";
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString
forKey:NSLocalizedDescriptionKey];
NSError *uniquenessError = [[[NSError alloc] initWithDomain:kNewsValidationDomain
code:kNewsValidationUniquenessCode
userInfo:userInfoDict] autorelease];
*error = uniquenessError;
return NO;
}
return YES;
}
but doesn't works as expect because, I suppose, when i perform the fetch request i find my same object previously insert in the context. Am I wrong?
How can i fix it?
Seems like you would find the same object you're trying to validate. Try one of these:
Execute the fetch request and remove the current object from the result array before checking for other entries.
Adjust the predicate so it excludes the current object, if possible.
Change resultCount > 0 to resultCount > 1.

Core Data & Generating Model Entities

Standard newbie question. I've created a data model for an iOS application. I am able to create, update and delete entities within the model from various views by using the NSEntityDescription object.
Say if I had a mutable array of objects returned from a fetch request. How can I loop through each one when I do not have a generated object definition from the entity model? By generated object definition I mean, a header and body class definition of the entity described in the data model package.
All CoreData entities derive from NSManagedObject and all the database data from those can be accessed via key value encoding. The minimum you need to know can be gained from the Model. You don't necessarily require the headers.
For example an entity PersonEntity which has a relationship to NameEntity with attribute firstname
NSArray *results = [managedObjectContext queryEntityForName:#"PersonEntity" predicateFormat:nil argumentArray:nil];
for(NSManagedObject *object in results)
{
NSString *name = [object valueForKeyPath:#"nameobject.firstname";
[self doSomething:name];
}
queryEntityForName is my own category. You might find it useful.
#implementation NSManagedObjectContext(VMQueryAdditions)
-(NSArray *)queryEntityForName:(NSString *)name predicateFormat:(NSString *)pstring argumentArray:(NSArray *)arr
{
NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:self];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
[fetch setEntity:entity];
NSPredicate *pred;
if(pstring)
{
if(arr) pred = [NSPredicate predicateWithFormat:pstring argumentArray:arr];
else pred = [NSPredicate predicateWithFormat:pstring];
[fetch setPredicate:pred];
}
NSError *error = nil;
NSArray *results = [self executeFetchRequest:fetch error:&error];
if (error) {
NSLog(#"MOC Fetch - Unresolved error %#, %#", error, [error userInfo]);
return [NSArray array];
}
return results;
}
#end