Making an "NSManaged public var" an Optional Boolean

Viewed 2548

How can I make an NSManaged public var an optional boolean? When I type the following:

import Foundation
import CoreData
import UIKit

extension SomeClass {

    @NSManaged public var isLiked: Bool?
    @NSManaged public var isDisliked: Bool?

}

I get the error:

Property cannot be marked @NSManaged because its type cannot be represented in Objective-C

What I want is a property that can be neither liked or disliked.

3 Answers

Tom Harrington's answer is correct that the @NSManaged types must work with ObjC. However, the issue is not with the optional type. @NSManaged types may be optional, e.g.:

@NSManaged var someProperty: String?

The issue here is with the Swift Bool type. Swift's Bool is an object and is not the same as ObjC primitive type BOOL. For a CoreData entity with a Boolean property, you should use the NSNumber? type as the @NSManaged property in your code. Then, similar to Tom's answer you could setup a separate Bool accessor property to get/set the @NSManaged NSNumber property, for example:

// the "liked" property is a Boolean attribute in your CoreData entity
@NSManaged var liked: NSNumber?

var isLiked: Bool? {
    get { return Bool(exactly: liked) }
    set { liked = NSNumber(booleanLiteral: newValue) }
}

The isLiked property will allow you to use it in your code like a Bool, but under the hood CoreData stores the value as an NSNumber for the Boolean attribute in your CoreData entity.

This can possibly be a reason you get that issue, if you have your Codegen set to manual. You have to make sure when you create an NSObject Subclass that all attributes are preset and no other attributes need to be added afterwards.

If you try adding a new attribute after already creating the NSObject Subclass then you will get this error.

Solution for me: Delete you subclass and properties file and go back to your .xcdatamodeld file and regenerate them with all the attributes that you want.

Related