iPhone: Save boolean into Core Data

IphoneCore DataBooleanUiswitch

Iphone Problem Overview


I have set up one of my core data attributes as a Boolean. Now, I need to set it, but XCode keeps telling me that it may not respond to setUseGPS.

[ride setUseGPS: useGPS.on];

What is the method for setting a boolean in core data? All my other attributes are set this way, and they work great. So, not sure why a boolean does not work to be set this way?

Iphone Solutions


Solution 1 - Iphone

Core Data "does not have" a Boolean type (it does, but it is an NSNumber).

So to set the equivalent of useGPS = YES.

[entity setUseGPS:[NSNumber numberWithBool:YES]];

And the other way around:

BOOL isGPSOn = [[entity useGPS] boolValue];

Update: As pointed out by SKG, With literals in Objetive-C you can now do it in a simpler way:

[entity setUseGPS:@YES];

BOOL isGPSOn = entity.useGPS.boolValue;

Solution 2 - Iphone

As an alternative approach to the accepted answer, you can simply change the typing from an NSNumber* to a BOOL in the managed object interface definition, such as:

@property (nonatomic) BOOL useGPS;   // Notice that the 'retain' is also removed as we're now dealing with a scalar rather than an NSObject

Various alternative approaches are discussed here, but Chris Hanson's response was most illuminating for me, especially:

> If you have a numeric attribute > (including a boolean attribute) that's > required, you can just type it as a > scalar instead, and Core Data will do > the right thing: > > @property (nonatomic) BOOL isDone; > > Even if the attribute is optional, > that'll still work - it'll just > conflate "not present" with "false."

and for a more aligned Cocoa implementation:

> One other thing you might want to do > is name the property "done" and just > specify the getter as "isDone." That's > the usual Cocoa naming convention: > > @property (nonatomic, getter=isDone) > BOOL done; > > Then you can write "if (item.done) { > ... }" or "item.done = NO;" and the > compiler will still generate -isDone > for accesses of the property.

Thanks Chris, and hope that this helps someone.

Solution 3 - Iphone

Just to complement @RickiG answer, the way to create a NSNumber from a Booland vice-versa in Swift (at least since v4.2) is:

let nsNumberFromBool = NSNumber(booleanLiteral: true) // or false
let boolFromNSNumber = nsNumberFromBool.boolValue

Solution 4 - Iphone

The "fix" for this (IMHO, it's a bug in Apple's SDK) is to add the following code to your CoreData-generated class. NB: if you do this in a category, in a separate file, then you don't have to re-copy/paste it each time you regenerate the CoreData classes inside Xcode

- (BOOL)useGPS
{
    [self willAccessValueForKey:@"useGPS"];
    BOOL myuseGPS = [[self primitiveUseGPS] boolValue];
    [self didAccessValueForKey:@"useGPS"];
    return myuseGPS;
}

- (void)setUseGPS:(BOOL)newValue
{
    [self willChangeValueForKey:@"useGPS"];
    [self setPrimitiveUseGPS:[NSNumber numberWithBool:newValue]];
    [self didChangeValueForKey:@"useGPS"];
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNic HubbardView Question on Stackoverflow
Solution 1 - IphoneRickiGView Answer on Stackoverflow
Solution 2 - IphonepaulkmooreView Answer on Stackoverflow
Solution 3 - IphoneNicolás Carrasco-StevensonView Answer on Stackoverflow
Solution 4 - IphoneAdamView Answer on Stackoverflow