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

У меня есть таблица, и я хочу очищать ее в определенное время (пользователь вводит в пике) дня каждый день.Вот код, который в основном работает, но предположим, что пользователь открыл приложение в 7 вечера, а время обновления - в 8 вечера, данные не удаляются (что правильно), но когда время в 9 вечера того же дня, и приложение открываетсяданные не удаляются (что неверно).Я думаю, что это как-то связано с обновлением lastRefreshDate в любое время, когда приложение открыто, и приходится ждать 24 часа с lastRefreshDate, а не с userPickedHour.Приложение должно работать так, что есть установленное время 7 вечера.Таким образом, приложение должно удалить данные на следующий день в 19:00 или после 19:00, когда пользователь откроет приложение, но если пользователь откроет приложение до 19:00 следующего дня, оно не должно удалять данные,

Вот код:

class RefreshManager: NSObject {

static let shared = RefreshManager()
private let defaults = UserDefaults.standard
private let defaultsKey = "lastRefresh"
private let calender = Calendar.current



func loadDataIfNeeded(completion: (Bool) -> Void) {

    if isRefreshRequired() {
        // load the data
        defaults.set(Date(), forKey: defaultsKey)
        print("xxxxxx")
        completion(true)
    } else {
        print("yyyyyy")
        completion(false)
    }
}

private func isRefreshRequired(userPickedHour: Int = 16) -> Bool {
    let SleepPickerdate = UserDefaults.standard.object(forKey: "SleepDate") as? Date
    let userPickedHour = Calendar.current.component(.hour, from: (SleepPickerdate)!)
    print(userPickedHour)

    guard let lastRefreshDate = defaults.object(forKey: defaultsKey) as? Date else {
        return true
    }

    if let diff = calender.dateComponents([.hour], from: lastRefreshDate, to: Date()).hour,
        let currentHour =  calender.dateComponents([.hour], from: Date()).hour,
        diff >= 24, userPickedHour >= currentHour {

        print("Delete TableView")
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Delete"), object: nil)
        print(diff)
        return true

    } else {

        print("Don't Delete TableView")

        return false


      }
    }
  }



class ViewController: UIViewController {

let refreshManager = RefreshManager.shared

override func viewDidLoad() {
    super.viewDidLoad()

    refreshManager.loadDataIfNeeded() { success in
        print(success)
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Вы не можете гарантировать, что ваше приложение работает в это время, каждый день.телефон может потерять весь заряд батареи, приложение может не работать ... и т. д. и т. д.

Но это просто логическая проблема ... Если вы хотите обновлять данные после определенного времени каждыйдень, вы должны просто сохранить последнее время обновления в UserDefaults, и если это время было больше, чем ваше требуемое время истечения (в данном случае 24 часа), то обновите данные и обновите последнее обновленное время.

Так что если у вас есть активный пользователь, как только истечет 24-часовая разница во времени, он обновится, или если пользовательский телефон отключится на несколько дней (по какой-либо причине), ваше приложение все равно будет знать, что ему нужнообновить данные, как только пользователь вернется в приложение.

РЕДАКТИРОВАТЬ: Добавлен пример кода

class RefreshManager: NSObject {

    static let shared = RefreshManager()
    private let defaults = UserDefaults.standard
    private let defaultsKey = "lastRefresh"
    private let calender = Calendar.current

    func loadDataIfNeeded(completion: (Bool) -> Void) {

        if isRefreshRequired() {
            // load the data
            defaults.set(Date(), forKey: defaultsKey)
            completion(true)
        } else {
            completion(false)
        }
    }

    private func isRefreshRequired() -> Bool {

        guard let lastRefreshDate = defaults.object(forKey: defaultsKey) as? Date else {
            return true
        }

        if let diff = calender.dateComponents([.hour], from: lastRefreshDate, to: Date()).hour, diff > 24 {
            return true
        } else {
            return false
        }
    }
}

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

Так что это сработает, если дата обновления не указана или если число часов с момента последнего больше 24, то обновит данные и обновит дату / время последнего обновления.используя завершение, он также возвращает обновленные данные или нет.

Вы также можете добавить здесь проверку, что текущий час дня равен >= 16, если требуется.

РЕДАКТИРОВАТЬ 2: Выбираемый пользователем час

private func isRefreshRequired(userPickedHour: Int = 16) -> Bool {

    guard let lastRefreshDate = defaults.object(forKey: defaultsKey) as? Date else {
        return true
    }

    if let diff = calender.dateComponents([.hour], from: lastRefreshDate, to: Date()).hour,
        let currentHour =  calender.dateComponents([.hour], from: Date()).hour,
        diff >= 24, userPickedHour <= currentHour {
        return true
    } else {
        return false
    }
}  

В этой измененной функции isRefreshRequired вы можете передать значение часа и посмотреть, прошло ли оно не менее 24 часов с момента последнего обновления, а текущий час больше или больше выбранного часа.

Это не значит, что он будет работать, например, ровно в 16:00.он запускается, когда пользователь загружает этот экран и проходит правила (мин. 24 часа, текущий час> = выбранный пользователем час)

РЕДАКТИРОВАТЬ 3: как позвонить

class ViewController: UIViewController {

    let refreshManager = RefreshManager.shared

    override func viewDidLoad() {
        super.viewDidLoad()

        refreshManager.loadDataIfNeeded() { success in
            print(success)
        }
    }
}

РЕДАКТИРОВАТЬ: измененная логика

if let diff = calender.dateComponents([.day], from: lastRefreshDate, to: Date()).day,
    let currentHour =  calender.dateComponents([.hour], from: Date()).hour,
    diff >= 1, userPickedHour <= currentHour {
    return true
} else {
    return false
}
0 голосов
/ 10 июня 2018

Вы не можете использовать такие длительные таймеры в iOS.Фактически, вы не можете заставить свое приложение вызывать функцию в определенное время суток.

Через короткое время пользователь блокирует свой телефон, и ваше приложение приостанавливается для экономии заряда аккумулятора.

Невозможно сделать то, о чем вы просите, если только вы не пишете для взломанного телефона.

РЕДАКТИРОВАТЬ:

Вы сказали: «Я просто хочу, когдаПользователь открывает приложение через определенное время, чтобы увидеть, что данные таблицы просмотра удалены. "

Хорошо, это другое.Когда приложение открыто, рассчитайте дату, на которую вы хотите удалить записи.

Сохраните эту дату в UserDefaults.Затем реализуйте метод applicationDidBecomeActive() и в этом методе прочитайте сохраненную дату из UserDefaults, и, если она прошла, удалите данные, которые вы отображаете в табличном представлении.

...