9

I've seen the other questions related to this error, but I've not seen anyone mention what I'm currently experiencing. Note that before converting to Swift 4, I had no problems with this code.

Below is the offending code:

let verseNotification = NSManagedObject(entity: entity, insertInto: self.managedObjectContext) as! VerseNotification
verseNotification.date_scheduled = NSDate(timeIntervalSinceNow: finalTimeToScheduleSinceNow)

Note that the attribute date_scheduled is of type Date:

@NSManaged public var date_scheduled: Date?

When I build my app to deploy in DEBUG on my physical iPhone (an iPhone 7), I get the following error (after converting from Swift 3 to Swift 4):

Cannot assign value of type 'NSDate' to type 'Date?' - Insert 'as Date'

Doing as it says fixes the problem... So, now my code is this:

verseNotification.date_scheduled = NSDate(timeIntervalSinceNow: finalTimeToScheduleSinceNow) as Date

...Until I switch the target to the simulator. When I switch the target to be the Simulator iPhone 7 device, I now get the following error:

'NSDate' is not implicitly convertible to 'Date'; did you mean to use 'as' to explicitly convert?

The confounding thing about this error is, as you can see above, I AM explicitly converting to type Date. Ironically, the only way I can get rid of this error for the Simulator iPhone 7 is to remove the as Date that I added in the first step.

What is going on? What am I missing?

I'm concerned about building a release version to "Generic Device," not knowing why I'm getting the conflicting errors.

UPDATE I've discovered something new and quite interesting.

When I build to deploy to my physical iPhone 7 device, the generated Core Data definition of my data model object creates the date_scheduled attribute as Date.

However, when I build to deploy on the Simulator iPhone 7, the generated Core Date definition of my data model object creates the date_scheduled attribute as NSDate.

Is this new in Swift 4 or Xcode 9? Is there a new setting that I'm missing after the conversion from Swift 3 to Swift 4?

thephatp
  • 1,479
  • 1
  • 20
  • 37
  • I think you should use `Date(timeIntervalSinceNow: finalTimeToScheduleSinceNow)` instead of `NSDate(timeIntervalSinceNow: finalTimeToScheduleSinceNow)` in swift – 3stud1ant3 Oct 01 '17 at 02:53
  • @3stud1ant3 - I tried that, which is how I discovered what I posted in the "Update" -- Core Data is generating different types based on which target device I choose. I'm very confused. – thephatp Oct 01 '17 at 02:54
  • Here this problem is described and "solved". https://stackoverflow.com/questions/46370566/xcode-9-build-issue-with-date-vs-nsdate-for-nsmanagedobject Clearly, Xcode bug though. – Yevgeniy Leychenko Oct 03 '17 at 07:16
  • Possible duplicate of [Xcode 9 build issue with Date vs NSDate for NSManagedObject](https://stackoverflow.com/questions/46370566/xcode-9-build-issue-with-date-vs-nsdate-for-nsmanagedobject) – pbasdf Oct 26 '17 at 07:21

2 Answers2

2

It’s Xcode bug. Please, report or open radar on that to be fixed in future releases

2

Here's how I worked around this (Xcode 9.2, Swift 4.0, watchOS 4):

#if arch(i386) //watchOS Simulator needs this
    completionDate = newValue as NSDate?
#else //watchOS device needs this
    completionDate = newValue
#endif  

In my case I share code between my iOS and watchOS targets, so it looks like this:

#if os(watchOS)
    #if arch(i386) //watchOS Simulator needs this
            completionDate = newValue as NSDate?
        #else //watchOS device needs this
            completionDate = newValue
    #endif  
#else //iOS, simulator or device
        completionDate = newValue
#endif

In the above, completionDate is my Core Data Date attribute, and newValue is a Swift "Date?" value.

Mitch Cohen
  • 1,551
  • 3
  • 15
  • 29