Какой самый эффективный способ обновить tableView каждый раз, когда приложение отодвигается на передний план? - PullRequest
0 голосов
/ 03 декабря 2018

В настоящее время у меня есть следующее:

AppDelegate.applicationDidBecomeActive ():

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    guard let vc = self.window?.rootViewController?.children.first as! AlarmTableViewController? else {
        fatalError("Could not downcast rootViewController to type AlarmTableViewController, exiting")
    }
    vc.deleteOldAlarms(completionHandler: { () -> Void in
        vc.tableView.reloadData()
    })
}

deleteOldAlarms ():

func deleteOldAlarms(completionHandler: @escaping () -> Void) {

    os_log("deleteOldAlarms() called", log: OSLog.default, type: .default)
    let notificationCenter = UNUserNotificationCenter.current()
    var activeNotificationUuids = [String]()
    var alarmsToDelete = [AlarmMO]()
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
        return
    }
    let managedContext = appDelegate.persistentContainer.viewContext

    notificationCenter.getPendingNotificationRequests(completionHandler: { (requests) in
        for request in requests {
            activeNotificationUuids.append(request.identifier)
        }
        for alarm in self.alarms {
            guard let alarmUuids = alarm.value(forKey: "notificationUuids") as! [String]? else {
                os_log("Found nil when attempting to unwrap notificationUuids in deleteOldAlarms() in AlarmTableViewController.swift, cancelling",
                       log: OSLog.default, type: .default)
                return
            }
            let activeNotificationUuidsSet: Set<String> = Set(activeNotificationUuids)
            let alarmUuidsSet: Set<String> = Set(alarmUuids)
            let union = activeNotificationUuidsSet.intersection(alarmUuidsSet)
            if union.isEmpty {
                alarmsToDelete.append(alarm)
            }
        }
        os_log("Deleting %d alarms", log: OSLog.default, type: .debug, alarmsToDelete.count)
        for alarmMOToDelete in alarmsToDelete {
            self.removeNotifications(notificationUuids: alarmMOToDelete.notificationUuids as [String])
            managedContext.delete(alarmMOToDelete)
            self.alarms.removeAll { (alarmMO) -> Bool in
                return alarmMOToDelete == alarmMO
            }
        }
        completionHandler()
    })

}

, но это отвратительно.Кроме того, я вызываю tableView.reloadData () в фоновом потоке (поток, выполняющий обработчик завершения).Какой лучший способ обновить пользовательский интерфейс после того, как пользователь снова откроет приложение?То, к чему я стремлюсь, - это удалить эти старые тревоги и перезагрузить представление.Тревога считается старой, если в центре уведомлений нет ожидающих уведомлений (то есть уведомление уже выполнено).

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Вы можете использовать NSNotification

NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)

В didBecomeActive вызов tableView.reloadData(), это должно быть все.Не забудьте отменить регистрацию в deinit.

NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
0 голосов
/ 03 декабря 2018

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

Добавьте это в viewDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(enteringForeground), name: UIApplication.willEnterForegroundNotification, object: nil)

Затем добавьте:

@objc func enteringForeground() {
    deleteOldAlarms {
        DispatchQueue.main.async {
            tableView.reloadData()
        }
    }
}
...