Swift 3: Date unconditionallyBridgeFromObjectiveC exception
alexburtnik opened this issue · 4 comments
I am using Genome to parse server response to CoreData entity. Exception is thrown when non-optional Date field is parsed:
libswiftFoundation.dylib`static Foundation.Date._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDate>) -> Foundation.Date:
extension BaseNote {
@NSManaged var date: Date
@NSManaged var text: String?
}
override func sequence(_ map: Map) throws {
//...
try date <~> map["date"]
.transformFromNode {
return Date(timeIntervalSince1970: $0)
}
.transformToNode { return $0.timeIntervalSince1970 }
}
Note that the problem disappears if I use NSDate in NSManagedObject subclass or make the field optional (Date?). It worked fine before migration to Swift 3.
Please correct me if I'm doing it wrong.
@alexburtnik not sure here, it sounds like something under the hood in Swift. If using NSDate solves the problem, I'd opt for that, but maybe there's some way to create NSDate and then convert it to the newer Date
Closing this for workaround until someone comes back w/ the issue still in 8.1
Not sure if this is the same issue but I ran into something similar when using moc.object(with: NSManagedObjectID) where the objectID was a temp id. The solution was to simply save the context before grabbing the objectID and passing it along.
New objects inserted into a managed object context are assigned a temporary ID which is replaced with a permanent one once the object gets saved to a persistent store.
Like @loganwright said this is indeed something happening under the hood related to swift and core data I left an answer on stackOverflow covering how I solved this issue here.
In short is due to core data and the default behaviour of NSFetchRequest
it has a property called returnsObjectsAsFaults
that defaults to true
and basically what it does is that it doesn't retrieve the actual NSManagedObject
fully, but instead tries to fetch its properties when they are accessed.
Picture this scenario:
Thread 1
- [step 1] let values = Fetch [NSManagedObject]
- [step 3] let values[0].someDate // here app will crash
Since returnsObjectsAsFaults
is true
[by default] someDate
property was not fetched until you tried to access it.
Thread 2
- [step 2] update coreData - hence removing objects fetched on Thread 1 - step 1
Solution: if you do need all your properties from the beginning from your NSManagedObject make sure to set on your fetchRequest:
let request = NSFetchRequest<T>(entityName: "someEntity")
...
request.returnsObjectsAsFaults = false