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

标签 ios swift uitableview timer delete-row

我有一个表格 View ,我想在每天的特定时间(用户输入选择器)清空它。这是它主要工作的代码,但假设用户在晚上 7 点打开应用程序并且更新时间是晚上 8 点,数据不会被删除(这是正确的)但是当时间是当天晚上 9 点并且应用程序被打开时数据未被删除(这是不正确的)。我认为这与 lastRefreshDate 在每次打开应用程序时更新有关,并且必须从 lastRefreshDate 开始等待 24 小时,而不是从 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)
    }
  }
}

最佳答案

您无法保证您的应用每天都在那个时间运行。手机可能会失去所有电池电量,应用程序可能无法运行……等等。

但这只是一个逻辑问题......如果你想在每天的某个时间后刷新数据,你应该只在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
        }
    }
}

你真的不必像我一样把它变成一个新类或一个单例。为了得到答案,将所有内容妥善保存起来会更容易。

因此,如果没有刷新日期,或者如果自上次更新以来的小时数大于 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 小时过去了,currentHour >= userSelected hour)

编辑 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
}

关于ios - 每天在特定时间 Swift 调用一次函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50779564/

相关文章:

ios - 剖析 Tinder/FB Messenger 等聊天应用程序在发送加密消息方面的作用

ios - API调用去哪个文件?

ios - 获取 UITapGestureRecognizer 目标

ios - 实例化 View ,然后导航离开

ios - 选择时会膨胀和收缩的不同单元格高度

ios - UITableView 中的后退按钮

ios - 如何在xcode中将SubviewToFront tableview下拉按钮

iphone - 如何释放 subview

ios - HLS 直播流视频在首次加载时无法播放

ios - 当按下不同 UITableView 单元格中的另一个播放按钮时,如何自动停止当前播放的音频? - swift