30

I'm creating an NSManagedObject subclass in Swift and I get an error when I make an Optional property that's of type Int, Float or Double (and maybe others that I didn't try out).

@NSManaged var number: Float? //error:Property cannot be marked @NSManaged because its type cannot be represented in Objective-C
@NSManaged var anotherNumber: Float //no error
@NSManaged var array: NSArray? //no error
@NSManaged var anotherArray: Array<String>? //no error

Which optional types can be represented in Objective-C? Why does the error not appear when I'm using a Swift Array or String (and when I'm not using an Optional Int or Double)?

Moon Cat
  • 2,029
  • 3
  • 20
  • 25

1 Answers1

32

You cannot assign arbitrary types to Core Data properties because the accessor methods are created dynamically at runtime. If you create an Objective-C managed object subclass in Xcode then you will see the proper data types used by Core Data, e.g.

  • NSNumber for Boolean, Integer, Float and Double attributes,
  • NSString for String attributes,
  • NSSet for (unordered) to-many relationships.

You have to choose the same data type in Swift.

Theoretically, scalar accessors for primitive data types should work as well, but there seems to be a problem in the current Swift version, compare How to use Core Data Integer 64 with Swift Int64? or EXC_BAD_ACCESS error when trying to change Bool property.

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks for the answer. Do you mean that primitive data types can be used, but don't work in the current Swift version? Also, why does the error appear only when the type is optional? – Moon Cat Jun 30 '14 at 13:00
  • 1
    @NSHeffalump: 1) Yes. Primitive data types work if you create the MO subclass in Objective-C and use them from Swift. Only if you create the MO subclass in Swift then you get a runtime exception at some point. - 2) There is no corresponding (Objective-)C type for `Float?`. `Float` translates to `float` in Objective-C, and both `NSArray?` and `Array?` translate to `NSArray *`. But it *makes no sense* to define `@NSManaged var number: Float?`, even if `Float?` were representable in Objective-C. CoreData creates the accessors at runtime, so you *have to* declare the types that CD chooses. – Martin R Jun 30 '14 at 13:16
  • (Cont.) If you declare a property as `@NSManaged var array: NSArray?` then it will most probably crash at runtime, when you try to assign a value. – Martin R Jun 30 '14 at 13:17
  • Thanks for clarifying. I just tested an app with a property in the MO subclass `@NSManaged var array: NSArray?`. It crashes when the attribute is not set to Optional in the xcdatamodeld, but otherwise it doesn't. Does that mean that only primitive data types as optionals cannot be represented in Objective-C? – Moon Cat Jun 30 '14 at 14:05
  • @NSHeffalump: It seems to me that you have actually two different questions here: 1) Which Swift types (in particular which Swift optional types) can be represented in Objective-C? - 2) Which Swift types can be used for Core Data properties. - I have tried to answer #2 because you explicitly mention Core Data and NSManagedObject in your question. In that context, both `NSArray` and `NSArray?` make no sense simply because Core Data does not use arrays for relationships, it uses NSSet. (Or did you define a "transformable" attribute?) – Martin R Jun 30 '14 at 14:14
  • (Cont.) *"Which Swift types (in particular which Swift optional types) can be represented in Objective-C?"* is a more general question and unrelated to Core Data. If that is your real question then I misunderstood your question. You could either clarify this question or post that as a separate question. – Martin R Jun 30 '14 at 14:16
  • I defined a transformable attribute. And yes, my question is #1 but I wasn't able to phrase it well. I'll try to make it clearer. – Moon Cat Jun 30 '14 at 15:55
  • 6
    If you want an NSManaged attribute to be optional, you'll need to use NSNumber instead of boolean, integer, float and double. Scalar types don't appear to be optional when using NSManaged. – Mark Krenek Jul 24 '15 at 19:14
  • @MarkKrenek: You are right. Unfortunately, it never become apparent (to me) what the *actual* problem was. – Martin R Jul 24 '15 at 19:39