如何在 Swift 中每天仅显示一次信标通知?

How to show beacon notification only once a day in Swift?

当检测到信标信号时,我的信标通知会随时触发。我怎样才能限制它每天只接收一次通知?

我实施了日期检查,但这没有帮助。 if/else 检查工作正常,但无视此检查会触发信标通知

非常感谢任何解决方法的建议!

这是我的代码片段:

class ViewController: UIViewController, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()

    let date = Date()
    let calendar = Calendar.current

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = 10
        locationManager.distanceFilter = 100
        locationManager.startUpdatingLocation()


        let year = calendar.component(.year, from: date)
        let month = calendar.component(.month, from: date)
        let day = calendar.component(.day, from: date)
        let currentDate = "\(year)\(month)\(day)"
        var savedDate = UserDefaults.standard.string(forKey: "savedDate") ?? "12345"

        print(currentDate)
        print(savedDate)

        if (savedDate == currentDate){
            print("same date - no action")
        } else {
            savedDate = currentDate
            UserDefaults.standard.set(savedDate, forKey: "savedDate")
            print(savedDate + " execute program")

            let beaconRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: "13D9F4C7-A68D-46F4-8D35-4BA7F64BC417")!, identifier: "estimote")
            beaconRegion.notifyOnEntry = true
            beaconRegion.notifyOnExit = false

            let content = UNMutableNotificationContent()
            content.title = " Daily beacon check! "
            content.subtitle = "Receive a new info every day!"
            content.body = "ONLY ONCE A DAY WE SUPPLY INFO!"
            content.sound = .default
            content.badge = 1

            let trigger = UNLocationNotificationTrigger(region: beaconRegion, repeats: true)
            let identifier = "estimote"
            let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
            UNUserNotificationCenter.current().removeAllPendingNotificationRequests()

            UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
            UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
            })

            self.locationManager.startRangingBeacons(in: beaconRegion)

        }
    }

通过设置

let trigger = UNLocationNotificationTrigger(region: beaconRegion, repeats: true)
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)

您基本上是在告诉程序关闭并在满足 beaconRegion 条件时自动发送通知。如果您总是想要通知并让系统为您处理,这很方便。但是你不可能在那个时候进行干预,因为它是自动运行的。

您可以做的是手动处理通知,并检查是否应该在每次检测到信标时发送通知。为此使用 locationManager(didRangeBeacons beacons:in region:) 委托函数:

let locationManager = CLLocationManager()
override func viewDidLoad() {
    super.viewDidLoad()

    // Setup beacon tracking once
    locationManager.delegate = self
    locationManager.requestAlwaysAuthorization()
    locationManager.desiredAccuracy = 10
    locationManager.distanceFilter = 100
    locationManager.startUpdatingLocation()
    let beaconRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: "13D9F4C7-A68D-46F4-8D35-4BA7F64BC417")!, identifier: "estimote")
    beaconRegion.notifyOnEntry = true
    beaconRegion.notifyOnExit = false

    // Start looking for beacons
    self.locationManager.startRangingBeacons(in: beaconRegion)
}

// Handle beacons in range
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    let now = Date()
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyyMMdd"
    let nowString = formatter.string(from: now)

    // Check if notified ever (lastTime != nil) and if notified today
    if let lastTime = UserDefaults.standard.string(forKey: "savedDate"), lastTime == nowString {
        // Already notified today, skip
        print("same date - no action")
        return
    }

    // Your notification code
    let content = UNMutableNotificationContent()
    content.title = " Daily beacon check! "
    content.subtitle = "Receive a new info every day!"
    content.body = "ONLY ONCE A DAY WE SUPPLY INFO!"
    content.sound = UNNotificationSound.default()
    content.badge = 1

    let identifier = "estimote"
    let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: nil)

    UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
        if error != nil {
          print("Error showing notification: \(error!.localizedDescription)")
        } else {
          print("Notification shown")
        }
    })

    UserDefaults.standard.set(nowString, forKey: "savedDate")
}