55

I have a coredata entity named Record and has a property dateUpdated. I noticed that the generated NSManagedObject subclass has no optional mark (?)

CoreData Editor:

enter image description here

Generated Subclass:

enter image description here

Expected:

enter image description here

UPDATED: It's tedious in my part, because each time I want to regenerate the subclasses, it means I also need to update all optional values manually. Having a non-optional (without '?') in subclass lead me to check evalue before assigning, like example below:

// sample value:
// serverDateFormatter = "yyyy/MM/dd"
// dateString = ""    

// Branch is a subclass of Record (see above images)

var date = self.coreData.serverDateFormatter.dateFromString(dateString)
if date != nil
{
   branch.dateUpdated = date 
}

But if xcode can automatically set optional value in subclass with (?) I just need to do like this:

branch.dateUpdated = self.coreData.serverUTCDateFormatter.dateFromString(dateString)

In my case, I have bunch of properties I need to mark as optional manually.

Allan Macatingrao
  • 2,071
  • 1
  • 20
  • 28

2 Answers2

56

The optional checkbox in the Core Data Model Editor has been existing before Swift and its optionals where introduced. Apple states about it in its Core Data Programming Guide:

You can specify that an attribute is optional — that is, it is not required to have a value. In general, however, you are discouraged from doing so — especially for numeric values (typically you can get better results using a mandatory attribute with a default value — in the model — of 0). The reason for this is that SQL has special comparison behavior for NULL that is unlike Objective-C's nil. NULL in a database is not the same as 0, and searches for 0 will not match columns with NULL.

Thus, using Swift and Xcode 8, optional checkbox is (still) not related to the fact that you defined your properties as optionals or not in your managedObject subclasses. And don't expect optional checkbox to have any impact on your NSManagedObject subclasses properties optional type when you create them using Editor > Create NSManagedObject Subclass.

That said, every time I need a property to have its optional checkbox checked in the Model Editor, I immediately put its NSManagedObject Subclass declaration as an optional.


Addendum

Mogenerator is able to automatically toggle your NSManagedObject subclass properties from non-optional to optional every time you change this option for each of your Entity's attribute in the Data Model Inspector and rebuild your project.

Community
  • 1
  • 1
Imanou Petit
  • 89,880
  • 29
  • 256
  • 218
  • please see my updated question. I understand your point. I hope the released version of xcode6 will support this case. Thank you. Will mark your answer as correct. – Allan Macatingrao Aug 26 '14 at 03:37
  • 9
    This is a pain. I have lots of optional fields. – Daniel Dec 10 '14 at 23:34
  • I can't see how the quoted paragraph from Core Data Programming Guide is related to the rest of the answer. – Luke Jan 18 '20 at 05:32
  • @Daniel Have you ever had a legit workaround in your development career. I am trying to learn iOS after Android and this is really pain in the ass. There are workarounds like force unwrapping while mapping the entity to other layer models but things can easily go shit if you decide to make your params optional (in Swift model class not in Core Data) in your model. I do not wanna create subclass of NSManagedObject because I lose nice functionality like "Cascade" deletion – Farid Dec 23 '22 at 13:48
9

Workaround:

Yes this seems like a bug / limitation. Use non-scalar types to workaround this problem.

Optional attributes

  • Check the optional check box
  • Uncheck scalar check box

Non-Optional attributes

  • Uncheck the optional check box
  • Check scalar check box

Probable reason:

The Swift code gets translated into Objective-C and Objective-C doesn't support nil values for non-class types.

Community
  • 1
  • 1
user1046037
  • 16,755
  • 12
  • 92
  • 138
  • 2
    I think you meant to say Objective-C doesn't support _nil_ values for non-class (primitive) types. To clarify: the NSNumber class may be nil, primitive types can't - precisely as you say why for optional attributes you must uncheck the scalar checkbox. – wardw Jul 28 '17 at 10:25
  • Thanks corrected as per your suggestion. For optional attributes uncheck the scalar checkbox so that you can use non-scalar types such as `NSNumber` – user1046037 Jul 28 '17 at 16:34
  • Swift does not get translated into Objective-C, it compiles directly to a binary. Swift isn't a wrapper for Objective-C, but its own language. – Alec O Mar 10 '18 at 23:14
  • @AlecO, Swift is not yet a complete language. There are many things that are still Objective-C under the hood. This is why, for example, attributes such as `@objc` and `@nonobjc` are required in some instances (such as Core Data class files). Also, anything you see with `NS` in front is still Objective-C-based, such as `NSFetchRequest` and `NSManagedObject`. Server-side Swift (which can be used in Linux) consists of the completed Swift frameworks, with no underlying Objective-C. You don't see Core Data there, yet... – leanne Jul 07 '18 at 16:26
  • Leanne, you are referencing the Cocoa framework, which in many cases is built on Obj C. Please note that Swift and Cocoa are two very separate things. Some attributes such as @objc allow the compiler to cross compile with Objective-C. Swift itself is not compiled into Objective-C, so I stick to my comment above. – Alec O Jul 07 '18 at 16:31
  • 3
    I'm not really sure how to make use of this workaround. I want my Doubles to be optional, but if I untick `Use Scalar Types` then I have to use NSNumber for everything and that's a monster in itself. – willbattel Dec 29 '18 at 23:32
  • And downside of using this is that, we will have to use NSNumber instead of Int. Right? – Salmaan Jan 16 '20 at 10:47