13

I have a lot of date fields in my database model. CoreData allows to use NSDate or TimeInterval to save dates depending on "Use Scalar Type" option.

enter image description here

However both these options are bad for me since I want to use dates as Date objects. Since NSDate is not implicitly convertible to Date I have to cast/convert values to Date or to implement a lot of custom setters/getters in my NSManagedObject classes.

I have tried to use ValueTransformer but it does not work with non-@objc classes like Date.

So is there a simple way to save and get Date values to/from CoreData?

Avt
  • 16,927
  • 4
  • 52
  • 72

2 Answers2

31

Yes, but you might not like it. If you declare the property using a Core Data "Date" type and let Xcode generate the NSManagedObject subclass for you, the property will be an @NSManaged property of type NSDate. As you've figured out, you'd then have to deal with Date vs. NSDate yourself.

If you don't let Xcode generate the subclass for you (in Xcode 8 set "Codegen" to "Manual/None"), you can declare the Core Data "date" property as something like

@NSManaged public var timestamp: Date?

It'll just work. You can read and write Date values, and Core Data will do the right thing. But you become completely responsible for the code in the NSManagedObject subclass. You'll have to create the whole class. If you update the Core Data model, you'll have to update the class as well. Whether this seems worthwhile is up to you but it's the only solution that seems to exist right now.

Update: In Xcode 9, generated code uses Date, so this shouldn't be necessary any more.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • 1
    It's the only way, in Xcode 8. File an enhancement request with Apple, and maybe it'll get into a future update. – Tom Harrington Sep 29 '16 at 20:30
  • I have just noticed you have written a book about CoreData. So it seems there is no sense to wait for another solution :) Thanks one more time. – Avt Oct 02 '16 at 17:18
  • 4
    What about the option to set "Codegen" to "Manual/None" then instead of creating the whole class yourself, just selecting your model on the left and from the menu choosing "Editor -> Create NSManagedObjectSubclass"? Which creates the class for you, then all you have to do is change NSDate's to Date's. You'll have to do this each time you update the model. – oyalhi Jan 19 '17 at 06:36
  • +! - I spent ages looking for a way to convert Date to NSDate. Ping Apple Core Data Team – redPanda Mar 08 '17 at 19:46
  • Setting Codegen to Category/Extension creates +CoreDataProperties.swift file with Date? (instead of NSDate) in Xcode 9. – fivewood Oct 09 '17 at 15:45
  • 4
    I just tried to regenerate a Swift class in Xcode 9 but the overwritten file still uses `NSDate`? I manually generate the class using the editor `Create Managed Subclass`. Wat am I missing? – Peterdk Oct 15 '17 at 21:56
10

There is a workaround here that works, if you set it as transformable and set its custom class to Date it simply works.

Transformable date