Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type for boolean attributes in Core Data entities?

I am using Core Data programmatically (i.e. not using .xcdatamodel data model files) in much the same manner as depicted in Apple's Core Data Utility Tutorial. So my problem is that when I try to add an attribute to an entity with the type NSBooleanAttributeType, it gets a bit buggy. When I add it to my NSManagedObject subclass header file (in the tutorial, that would be Run.h) as

@property (retain) BOOL *booleanProperty;

compiling fails, saying error: property 'booleanProperty' with 'retain' attribute must be of object type.

It seems like some places in Cocoa use NSNumber objects to represent booleans, so I tried setting it to

@property (retain) NSNumber *booleanProperty;

instead. However, this evokes the following runtime errors:

*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470'

Using GDB, I am able to trace this back to the line in my source code where I add my entity to the managed object model:

[DVManagedObjectModel setEntities:[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]];

So my question is this: what type should I set booleanProperty to in my custom class header?

like image 824
Michael Victor Zink Avatar asked Jun 20 '09 19:06

Michael Victor Zink


People also ask

What is attribute in Core Data?

You can think of attributes as the columns of a table in a database. Attributes store the values of a Core Data record. There are several types of attributes, such as String, Date, Integer, Float, and Boolean.

Which is Core Data type?

Core Data provides different attributes, including those common for all databases, such as Date or Decimal type, and non-standard attributes handled with Transformable type. It also provides Transient and Derived attributes so apps can derive one piece of data from the other.

What is an entity in Core Data?

An entity describes an object, including its name, attributes, and relationships.


2 Answers

Try:

@property (nonatomic) BOOL booleanProperty;

The problem was that you used the retain in the property definition. For that you must have a property for an Objective-C class (it should be able to understand the 'retain' method). BOOL is not a class but an alias for signed char.

like image 63
diederikh Avatar answered Oct 15 '22 19:10

diederikh


I wouldn't recommend the method suggested by Diederik Hoogenboom (i got an error even though my core data attribute was set as Boolean).

It's worth pointing out that although this line will work for a custom object, it will not work for a subclass of NSManagedObject:

@property (nonatomic) BOOL booleanProperty;

Your property should be set as this:

@property (nonatomic, retain) NSNumber *booleanProperty;

When i copy the method declarations for a Boolean type (using the technique suggested by Jim Correia), the getter and setter are typed as:

NSNumber:-(NSNumber *)booleanProperty; 
-(void)setBooleanProperty:(NSNumber *)value;

...this is what a Boolean property in core data is set as, and you need to validate your property with something like this:

-(BOOL)validateBooleanProperty:(NSNumber **)toValidate error:(NSError **)outError 
{
    int toVal = [*toValidate intValue];

    if ( (toVal < 0) || (toVal > 1) )
    {
        NSString *errorString = NSLocalizedStringFromTable(@"Boolean Property", @"TheObject", @"validation: not YES or NO");
        NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString forKey:NSLocalizedDescriptionKey];

        NSError *error = [[[NSError alloc] initWithDomain:NSCocoaErrorDomain code:-1 userInfo:userInfoDict] autorelease];
        *outError = error;
        return NO;
    }
    return YES;
}//END

…remember to include the validateBooleanProperty declaration in the header file. The setter and getter methods store and retrieve your property using -(id)primitiveValueForKey:(NSString *)key.

Finally you need to explicitly call the validate method from whatever view controller / app delegate you're setting the object from:

    NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease];
    NSError *valError = nil;        
    if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES)
    {
        [TheObject setBooleanProperty :boolProp];   
    }       
like image 27
PostCodeism Avatar answered Oct 15 '22 20:10

PostCodeism