NSCalendarDayChanged публикуется без изменения дня

#ios #arrays #swift

#iOS #массивы #swift

Вопрос:

Предполагается, что следующий код в делегате приложения добавляет новое назначение в массив назначений один раз в день. Проблема в том, что при каждом открытии приложения добавляется новое назначение, даже если день не изменился. Похоже, что NSCalendarDayChanged публикуется при каждом открытии приложения.

 var assignments = [Assignment]()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if let _ = loadHW(){
        assignments = loadHW()!
    }

    if let assignment = NSKeyedUnarchiver.unarchiveObject(withFile: Assignment.ArchiveURL.path) as? [Assignment]{
        assignments = assignment
    }

    // Define identifier
    let notificationName = Notification.Name("NSNotification.Name.NSCalendarDayChanged")

    // Register to receive notification
    NotificationCenter.default.addObserver(self, selector: #selector(calendarDayDidChange(notification:)), name: notificationName, object: nil)

    // Post notification
    NotificationCenter.default.post(name: notificationName, object: nil)


    // Override point for customization after application launch.NSNotification.Name.NSCalendarDayChanged
    return true
}
func calendarDayDidChange(notification : NSNotification)
{
    let currentDate = Date()
    let dateFormatter = DateFormatter()

    let dayOfTheWeek = Calendar(identifier: Calendar.Identifier.gregorian).component(.weekday, from: Date())
    print(dayOfTheWeek)

    dateFormatter.dateFormat = "M/dd/YY"
    let convertedCurrentDate = dateFormatter.string(from: currentDate)
    print(convertedCurrentDate)

    //Adds an assignment based on date comparisons
    if let dates = NSKeyedUnarchiver.unarchiveObject(withFile: SettingsViewController.datesURL.path) as? [Date] {
        print(1)
        if currentDate >= dates[0] amp;amp; currentDate <= dates[1] {
            print(2)
            if let weekendHW = NSKeyedUnarchiver.unarchiveObject(withFile: SettingsViewController.weekendURL.path) as? Bool {
                print(3)
                if(weekendHW || (!weekendHW amp;amp; dayOfTheWeek != 1 amp;amp; dayOfTheWeek != 7)){
                    print(4)
                    if assignments.count > 0{
                        assignments.insert(Assignment(hw: assignments[0].hw, date: convertedCurrentDate)!, at: 0)
                        print(5)
                    }else if assignments.count == 0 {
                        assignments.append(Assignment(hw: "", date: convertedCurrentDate)!)
                        print(6)
                    }
                    saveHW()
                    print("save complete")
                }
            }
        }
    }


    //adds assignment on first launch of app
    if assignments.count == 0 {
        assignments.append(Assignment(hw: "", date: convertedCurrentDate)!)
        saveHW()
    }

}
func saveHW() {
    let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(assignments, toFile: Assignment.ArchiveURL.path) //saves array grades to file defined in Assignment class

    if !isSuccessfulSave { //Diagnostic
        print("Save failed")
    }
}

func loadHW() -> [Assignment]? {
    return NSKeyedUnarchiver.unarchiveObject(withFile: Assignment.ArchiveURL.path) as? [Assignment] //gets array grades from file where saved, defined in Assignment class

}
  

Что я могу изменить, чтобы гарантировать, что в день создается только одно назначение?

Комментарии:

1. Запишите, когда вы в последний раз получали уведомление (или используйте дату последнего назначения), и сравните это с текущей датой, прежде чем делать что-либо еще?

2. На самом деле, проблема, скорее всего, заключается в том, что сразу после добавления наблюдателя… вы публикуете уведомление об этом событии!

3. Почему вы разархивируете один и тот же Assignment объект до трех раз?

4. @jcaron ВЕРНО! Упс … извините…

Ответ №1:

Публикуется не NSCalendarDayChanged, а вы публикуете уведомление. Удалите строку

 NotificationCenter.default.post(name: notificationName, object: nil)
  

и удалить также

 if let _ = loadHW(){
    assignments = loadHW()!
}
  

Это избыточно. Следующее if - let выражение делает то же самое.