Search code examples
xcodetimernstimerswift4

Swift 4 and Xcode 9: Cannot invoke 'dateComponents' with an argument list of type '(NSCalendar.Unit.Type, from: NSData, to: Date?)'


Trying to create a countdown timer, but I can't get past this error:

Cannot invoke 'dateComponents' with an argument list of type '(NSCalendar.Unit.Type, from: NSData, to: Date?)'

my code:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var TimerLable: UILabel!



    let formatter = DateFormatter()
    let userCleander = Calendar.current;
    let CalenderComponent : NSCalendar.Unit = [
        NSCalendar.Unit.year,
        NSCalendar.Unit.month,
        NSCalendar.Unit.day,
        NSCalendar.Unit.hour
    ]


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }
    func printTime()
    {
        formatter.dateFormat = "dd/MM/yy hh:mm a"
        let StartTime = NSData()
        let EndTime = formatter.date(from: "10/08/19 12:00 a")

        let TimeDifference = userCleander.dateComponents(NSCalendar.Unit, from: StartTime, to: EndTime)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



}

Solution

  • The main issue which causes the error is just a typo. StartTime is supposed to be NSDate not NSData.

    Basically don't use NS... classes if there is a Swift native counterpart (Calendar, Date etc).

    The Swift 3+ code is

    let formatter = DateFormatter()
    let userCalendar = Calendar.current
    
    let calendarComponents : Set<Calendar.Component> = [ .year, .month, .day, .hour]
    
    func printTime()
    {
        formatter.dateFormat = "dd/MM/yy hh:mm a"
        let startTime = Date()
        let endTime = formatter.date(from: "10/08/19 12:00 am")!
    
        let timeDifference = userCalendar.dateComponents(calendarComponents, from: startTime, to: endTime)
    }
    

    Two notes:

    • According to the naming guidelines variable names start with a lowercase letter
    • The date format does not match the date string and the created date needs to be unwrapped.