Saving and retrieving data from core data - iphone

I have a program where I save an int value as follows:
client.oldId = [clientDict objectForKey:#"oldId"];
At this point when debugging the value that is saved "supposely" is 31.
When I attempt to retrieve this item using the context, and i retrieve it as follows:
int oldId = [NSNumber numberWithInt:client.oldId];
It becomes 174806944, why could this happen?, there are no summation operations or anything like that for this item and right before it saves to the context it is 31.
Any help would be appreciated.

set your variable to 0 before you set it
int oldId = 0
oldid = [NSNumber numberWithInt:client.oldId];
sometimes you can get garbage in a memory location that can cause this.
Updated Answer: Though technically sometimes I have found that if you dont clear out the integer I get the same thing. In this case he was setting an int to an NSNumber. The correct way was to take the NSNumber and get its integerValue like this:
[client.oldId intValue]

Related

NSDictionary id key value

I recently try to change the Json library in my applicaiton from SBJson to the NSJSONSerialization.
When I do this job, I find there are some key value that I can not get out.
Here is an example of the NSDictionary I get after NSJSONSerialization:
{
id = 4028;
"novel_author" = "XYZ";
"novel_pub" = "ABC";
"novel_title" = "DATE LIVE";
updatedate = "2013-01-13 22:31:13";
"vol_click" = 7563;
}
The original Json data string is:
{
"id":"4028",
"vol_click":"7563",
"updatedate":"2013-01-13 22:31:13",
"novel_author":"XYZ",
"novel_pub":"ABC",
"novel_title":"DATE LIVE"
}
I can not get the value of the key "id" out.
[NSDictionary objectForKey#"id"] is useless.
Is there anyone have idea how to get the value out?
As you can tell by the output of what looks like NSLog("%#", dict);, the JSON deserialization process works fine.
The dictionary contains a key called "id", so [dict objectForKey:#"id"] should also work fine.
I can only conclude that this isn't the actual cause of the trouble you're having.
Either of these should work:
[yourDictName valueForKey:#"id"]
[yourDictName objectForKey:#"id"]
If you can see the value using NSLog to display the dictionary, then it is there. Beyond that, make sure your object is not getting nil'd or released or freed.

xcode iPhone array and dictionary [noob]

I'm sorry for this (probably very) noob question, but i've been asked about this and can't see what's wrong (i'm java tought..)
This is what I have, data is loaded via JSON:
NSDictionary *myvalues = [myres objectForKey:#"0"];
this is the content if I output via NSLog:
({id = "1a";myval = 5;},
{id = "2b";myval="24.6";})
how do I iterate through myvalues and how do I get the values id and myval? Something like this i'm getting stuck:
for (NSArray* myvals_array in myvalues)
First it looks like the returned value is an Array, the content inside of the parentheses() denotes this. So I would try and set it as such instead of a Dictionary. Then you can enumerate through the array of dictionary's and get each dictionary inside:
for (id object in myvalues) {
NSDictionary *currentObject = (NSDictionary*)object;
NSString *myID = [currentObject valueForKey:#"id"];
NSString *myValue = [currentObject valueForKey:#"myval"];
NSLog(#"ID:%# VALUE:%#",myID,myValue);
}
This will enumerate through the array and create a dictionary for each entry, then get the values for each of the two elements inside. I just NSLog() them here but you can do whatever you want with the values.

Correct way to modify results array from NSFectchRequest without changing Core Data objects

I am retrieving a fetch from my core data database and trying to iterate through the data and make changes to the data, if necessary. When I change the data in the results array, it turns out that my database is changing in the back end as well, without doing a save. I am wondering what would be a good practice to use to change the data without affecting the back end data.
Here is the code I change the data with:
self.singleDayDataPointsForGraph = [[self fuelPurchaseDataForTimePeriodInMonths:self.numberOfMonthsForGraphView] mutableCopy];
for (int i = 0; i < self.singleDayDataPointsForGraph.count; i++) {
FuelPurchase *currentFuelPurchase = [self.singleDayDataPointsForGraph objectAtIndex:i];
if (i < self.singleDayDataPointsForGraph.count + 1 && self.singleDayDataPointsForGraph.count >= 2) {
FuelPurchase *purchaseToCompare = [self.singleDayDataPointsForGraph objectAtIndex:i + 1];
NSDate *firstDate = currentFuelPurchase.dateTimeStamp;
NSDate *secondDate = purchaseToCompare.dateTimeStamp;
NSDateFormatter *dateComparisonFormatter = [[NSDateFormatter alloc] init];
[dateComparisonFormatter setDateFormat:#"yyyy-MM-dd"];
if([[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) {
float firstValue = [purchaseToCompare.fillSavings floatValue];
float secondValue = [currentFuelPurchase.fillSavings floatValue];
purchaseToCompare.fillSavings = [NSNumber numberWithFloat:(firstValue + secondValue)];
[self.singleDayDataPointsForGraph removeObjectAtIndex:i];
}
}
The fuelPurchaseDataForTimePeriodInMonths: method is what performs the fetch and returns an NSArray of results. self. singleDayDataPointsForGraph is an NSMutableArray that stores the results array as a mutable copy. This method basically checks two entries in the database to see if they are the on the same day and if they are, then it adds the fuel purchase amounts to each other and deletes one of the records. I don't want this to change my back end data, but it is.
Thanks very much.
It is doing the right thing. If you take a core data object and modify it, it will reflect immediately whether you save it ot not. The saving part ensures, that if you quit the application and come back the data is saved as well.
So for your situation, I would avoid modifying the actual core data object. Rather create a structure which imitates the core data object and modify that structure.
Example, say my coredata object is Person with attributes name and age.
The object a get from a fetch is say
person1.
You have a class PersonSub with same attributes.
Now you can create
PersonSub *personSub = [[PersonSub alloc] init]; //You can create a custom init to initilize from Person core data if you like.
personSub.name = person1.name;
personSub.age = person1.age;
Now you can modify as follows
personSub.age = personSub.age + 1;

Getting count of children in NSDictionary when sometimes the element is an array and sometimes it's not

I have an NSDictionary that looks kind of like this:
list
{{
-> id
-> name
-> color
},
{
-> id
-> name
-> color
}}
which works great when I loop through it! But unfortunately, sometimes, the structure looks like this:
list {
-> id
-> name
-> color
}
Where there's only one result returned. So I need to know if there's one or if there's more than one result returned.
I tried checking for the number of results by seeing if the ID key exists in "list" but unfortunately when I do valueForKey I get back something like this for multiple results: (429, 24) and just 429 if there's only one result.
But I can't do a count on the 429 value obviously.
Here's one of the things I was trying to do, which works great for multiple results, but not if there's one.
NSInteger numResults = [[list valueForKeyPath:#"id.#count"] intValue];
Any idea how to find out if it's an set of results or just a single result? I don't have any control over the data as it comes from a JSON object via a web service.
I also tried using [list mutableArrayValueForKey:#"id"]; and that seems to still only return an array if there's more than one result. I assumed I'd get back an array with one element if there was only one element...but apparently not?
You can check which kind of object you are dealing with using isKindOfClass:
NSInteger numResults = 1;
if ([list isKindOfClass:[NSArray class]]) {
numResults = [list count];
}
If I understand correctly, one result will actually give you an NSDictionary, but multiple results will give you an NSArray of NSDictionaries?
Assuming that is the case, you could check the type of object you have like this:
if ([list isKindOfClass:[NSDictionary class]]) {
// Must be single result
}
else {
// Multiple results case
}
Otherwise, if I've misunderstood, perhaps you could clarify.

Core Data: Save failing on mandatory field, but value should be set!

I have an abstract entity called Block which contains two attributes: column and order (which are not optional), and one relationship, thing, where it is the detail of a 1->M. I have another entity, Whatever, that has Block as its parent, and adds one attribute, someNumber.
My code looks like this:
Whatever *block = (Whatever *)[NSEntityDescription insertNewObjectForEntityForName:#"Whatever" inManagedObjectContext:managedObjectContext];
block.order = 0;
block.column = 0;
block.thing = self.thing;
When I try to save, I get this error:
Failed to save to data store: Operation could not be completed. (Cocoa error 1560.)
DetailedError: {
NSLocalizedDescription = "Operation could not be completed. (Cocoa error 1570.)";
NSValidationErrorKey = column;
NSValidationErrorObject = <Whatever: 0x5124890> (entity: someWhatever; id: 0x511b4e0 <x-coredata:///Whatever/t718B63A4-927B-4D88-A9E6-7F61CF9621675> ;
data: {
column = nil;
thing = 0x54367a0 <x-coredata://E6648244-E5FC-4202-B5F9-C7A91BACF8DA/Thing/p2>;
order = nil;
someNumber = 0;
});
I don't understand why it says that column and order are nil, as I've just set them the line before, so this shouldn't be a problem.
I've tried using the [block setColumn:0] style as well, without success.
Any help would be appreciated. Thanks!
You are setting them to nil since nil is just a null or zero pointer value.
Core Data properties must be set to objects (as opposed to primitive types).
Integers and floating point numbers are NSNumber objects.
I like to use the numberWith* convenience constructors.
For example:
block.order = [NSNumber numberWithInteger:0];
block.column = [NSNumber numberWithInteger:0];
To expand on gerry3's answer, a great way to ease coding with Core Data is to use Rentzsch's mogenerator. It would allow you to do:
block.orderValue = 0;
block.columnValue = 0;