Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 - Cannot assign value of type 'NSDate' to type 'Date?' ONLY on Physical Device

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?

like image 340
thephatp Avatar asked Oct 01 '17 02:10

thephatp


2 Answers

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

like image 131
Максуд Даудов Avatar answered Nov 15 '22 04:11

Максуд Даудов


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.

like image 39
Mitch Cohen Avatar answered Nov 15 '22 03:11

Mitch Cohen