Use Swift's Date with CoreData
Asked Answered
T

2

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?

Thackeray answered 29/9, 2016 at 19:3 Comment(0)
D
32

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.

Dissonance answered 29/9, 2016 at 20:10 Comment(6)
It's the only way, in Xcode 8. File an enhancement request with Apple, and maybe it'll get into a future update.Dissonance
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.Thackeray
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.Bezique
+! - I spent ages looking for a way to convert Date to NSDate. Ping Apple Core Data TeamGregggreggory
Setting Codegen to Category/Extension creates <className>+CoreDataProperties.swift file with Date? (instead of NSDate) in Xcode 9.Speedway
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?Savitt
K
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

Kassa answered 2/11, 2017 at 15:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.