Выполнить функцию при изменении времени устройства - PullRequest
0 голосов
/ 20 января 2019

Я пытаюсь выполнить функцию, когда часы устройства меняются. Эта функция вернет следующий курс студента, все курсы в массиве.

если я правильно понимаю, мы не можем выполнить функцию, когда часы устройства меняются. Я читал некоторые темы, в которых люди говорят, что нужно сделать таймер 60-х или других, но если пользователь запустит приложение 08:05:07, функция будет выполняться с 7-ми секундами позже. Я подумал использовать do некоторое время, но думаю, что он будет сильно загружать процессор и батарею. нет?

У кого-нибудь есть идея?

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Я сделал это

    private var secondesActuelles : Int = 0
    private var timer = Timer()

    private func récuperLesSecondes(date : Date) -> Int {
        let date = date
        let calendar = Calendar.current
        let second = calendar.component(.second, from: date)
        return second
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        secondesActuelles = récuperLesSecondes(date: Date())

        timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(60 - secondesActuelles), repeats: false, block: { (timer) in
            print("l'heure a changé")
            self.secondesActuelles = self.récuperLesSecondes(date: Date())
            print("secondesActuelles : \(self.secondesActuelles)")

        })
}

Это работает один раз.но после timeInterval не меняется.

0 голосов
/ 20 января 2019

Если вы просто говорите, что хотите запустить таймер в каком-то определенном будущем Date, вы должны просто рассчитать количество времени между настоящим моментом и временем (используя timeIntervalSince), а затем использовать это.

Например, в настоящее время это «2019-01-20 17:11:59 +0000», но если я хочу, чтобы оно сработало в 17:15, вы можете сделать:

weak var timer: Timer?

func startTimer() {
    let futureDate = ISO8601DateFormatter().date(from: "2019-01-20T17:15:00Z")!
    let elapsed = futureDate.timeIntervalSince(Date())   // will be roughly 180.56 in this example at this moment of time

    timer?.invalidate() // invalidate prior timer, if any

    timer = Timer.scheduledTimer(withTimeInterval: elapsed, repeats: false) { [weak self] _ in
        // whatever you want to do at 17:15
    }
}

Ясно, что вы придумали futureDate, в вашем случае все будет иначе, но это иллюстрирует идею. Просто рассчитайте время, прошедшее между будущей целевой датой и сейчас, и используйте его для таймера.

Теперь, если вы действительно беспокоитесь об изменениях часов, в iOS вы можете наблюдать significantTimeChangeNotification, например,

NotificationCenter.default.addObserver(forName: UIApplication.significantTimeChangeNotification, object: nil, queue: .main) { [weak self] _ in
    // do something, maybe `invalidate` existing timer and create new one
    self?.startTimer()       
}

Я подумал использовать do некоторое время, но думаю, что он будет сильно загружать процессор и батарею. нет?

Да, вращение в цикле, ожидание в течение некоторого времени, всегда плохая идея. Обычно вы просто устанавливаете таймер.

Эта функция вернет следующий курс студента, все курсы в массиве.

Возникает вопрос, будет ли приложение работать на переднем плане или нет. Если вы хотите уведомить пользователя в будущем, независимо от того, запускает ли оно приложение прямо сейчас или нет, рассмотрите « уведомления пользователя ». Например, запросите разрешение на уведомление:

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
    if !granted {
        // warn the user that they won't be notified after the user leaves the app unless they grant permission for notifications
        DispatchQueue.main.async {
            let alert = UIAlertController(title: nil, message: "We need permission to notify you of your class", preferredStyle: .alert)
            if let url = URL(string: UIApplication.openSettingsURLString) {
                alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
                    UIApplication.shared.open(url)
                })
            }
            alert.addAction(UIAlertAction(title: "Cancel", style: .default))
            self.present(alert, animated: true)
        }
    }
}

А затем, предполагая, что разрешения были предоставлены, затем запланировать уведомление:

let content = UNMutableNotificationContent()
content.title = "ClassTime"
content.body = "Time to go to math class"

let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: futureDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
let request = UNNotificationRequest(identifier: "Math 101", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...