在特定时间Swift每天调用一次函数

Cod*_*J13 -1 timer uitableview delete-row ios swift

我有一个tableview,我想在每天的特定时间(用户输入一个选择器)清空它.以下是它主要使用的代码,但是让我们说用户在晚上7点打开应用程序,更新时间是晚上8点,数据不会被删除(这是正确的)但是当时间是在同一天晚上9点并且应用程序打开数据不会被删除(这是不正确的).我认为这与lastRefreshDate应用程序打开时更新的evreytime时间有关,必须等待24小时lastRefreshDate而不是等待userPickedHour.该应用程序应该像这样工作有一个设定的时间晚上7点.因此,应用程序应该在第二天晚上7点或晚上7点后删除数据,当用户打开应用程序时,如果用户在第二天晚上7点之前打开应用程序,则不应删除数据,

这是代码:

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)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Scr*_*ble 5

您不能保证您的应用每天都在运行.手机可能会丢失所有电池电量,应用程序可能无法运行...等等.

但这只是一个逻辑问题......如果你想在每天的某个时间后刷新数据,你应该只在UserDefaults中存储一个上次刷新时间,如果那个时间超过了你所需的到期时间(在这种情况下) 24h)然后刷新数据并更新上次更新的时间.

因此,如果您有一个活跃用户,一旦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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你真的不必像我一样把它变成新的类或单例.为了答案,更容易保持所有内容.

因此,如果没有刷新日期,或者自上一个小时数大于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
    }
}  
Run Code Online (Sandbox Code Playgroud)

在此修改后的isRefreshRequired函数中,您可以传递一小时的值,并查看自上次刷新以来是否至少24小时,以及当前小时是否大于用户所选小时.

这并不意味着顺便说一句,例如恰好在16:00运行.它将在用户加载该屏幕并且规则通过时运行(最少24小时过去,currentHour> = userSelected小时)

编辑3:如何打电话

class ViewController: UIViewController {

    let refreshManager = RefreshManager.shared

    override func viewDidLoad() {
        super.viewDidLoad()

        refreshManager.loadDataIfNeeded() { success in
            print(success)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:改变了逻辑

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
}
Run Code Online (Sandbox Code Playgroud)