65

I have a core data entity named Film which has properties title and date. I noticed that the generated NSManagedObject subclass contains optional NSManaged properties even though I marked the properties as non optional in the core data inspector.

enter image description here

enter image description here

Can I can manually change it as non-optional property or is it a better choice to leave it as optional? Why?

Marcus Leon
  • 55,199
  • 118
  • 297
  • 429
Davide
  • 673
  • 5
  • 9
  • related: https://stackoverflow.com/questions/25485273/swift-coredata-cannot-automatically-set-optional-attribute-on-generated-nsman – mfaani Dec 26 '18 at 15:35
  • In CoreData entity attributes panel, mark Codegen as Manual and declare your NSManagedObject manually – onmyway133 Feb 20 '20 at 06:27

4 Answers4

98

"Optional" means something different to Core Data than it does to Swift.

  • If a Core Data attribute is not optional, it must have a non-nil value when you save changes. At other times Core Data doesn't care if the attribute is nil.
  • If a Swift property is not optional, it must have a non-nil value at all times after initialization is complete.

Making a Core Data attribute non-optional does not imply that it's non-optional in the Swift sense of the term. That's why generated code makes these properties optional-- as far as Core Data is concerned, it's legal to have nil values except when saving changes.

Update: After writing this answer I wrote a deep dive blog post explaining things in more detail: https://www.atomicbird.com/blog/clash-of-the-optionals/

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • 3
    Make sure you at least assign any non-optional variable within `override func awakeFromInsert()`. – adamek Nov 17 '15 at 14:22
  • 7
    what is the solution to make it non-optional. Should I create manual files and make them non-optional as that works.? – megha Aug 23 '18 at 06:52
  • So how is this generally resolved? Is there any best practices? I can do this in mapper by force unwrapping but if in the future I decide to have that property to be optional, the whole project is fucked. – Farid Dec 23 '22 at 13:35
  • @adamek Makes no sense, what if my parameter is complex nested object? – Farid Dec 23 '22 at 13:36
  • 1
    @Farid You resolve it by assigning a value before saving changes. As with any optional, the fix is to provide a value. – Tom Harrington Dec 23 '22 at 16:59
4

This is a known issue. Some people change it to non-optional with no adverse effects, I keep it the way it was generated and hope for early fix.

It always helps if you submit a bug to Apple to increase visibility and priority.

MirekE
  • 11,515
  • 5
  • 35
  • 28
  • 2
    Still happening in Xcode 10.1. I guess, in case of Apple "early fix" means several years at best. – Stan Mots Feb 06 '19 at 19:31
  • 6
    Still happening in XCode 11.3.1. The year is 2020 now. – Luke Jan 18 '20 at 05:44
  • 3
    Still happening in Xcode Version 11.5. The year is 2020 (the pandemic happening now). – MGY Jun 22 '20 at 13:33
  • 1
    please read the accepted answer. this isn't a bug and no-one is going to fix it cause... well... there's nothing to fx – ramzesenok Sep 07 '21 at 10:01
  • Useless idea. Try it with relationships. How you will add deletion type "Cascade" to that parameter via code? – Farid Dec 23 '22 at 13:37
3

Create managedobject class and change the entity class type to manual and add these classes to your project scope.

Edit your managedObject to make them non-optional. This means you need to maintain this class yourself and do any changes both in the core data model and the class

If your data model is stable and won't be changed then you can use this.

megha
  • 473
  • 5
  • 18
  • That is right keep generating ugly and unmaintainable "workarounds". How are we supposed to add "Cascade" delete functionality to relationships given we do it all manually? – Farid Dec 23 '22 at 13:38
1

The Optional checkbox in the data model inspector has nothing to do with Swift optionals. The checkbox determines whether or not the attribute is required to have a value.

If you deselect the Optional checkbox for an attribute, you must give that attribute a value or you will get an error when saving. By selecting the Optional checkbox you can save without giving the attribute a value. Suppose you have a description attribute that's a string. If you select the Optional checkbox you could leave the description blank and still save the entity.

Here's another example. Suppose you have text fields to let a person enter their home, work, and cell phone numbers. These phone numbers should be optional attributes. You wouldn't want to require someone to have a home phone number, a work phone number, and a cell phone number just to save the person's data.

Mohamed AbdelraZek
  • 2,503
  • 4
  • 25
  • 36