简体   繁体   English

我想创建一个通知,当 swift 中显示另一个通知时将触发该通知

[英]I want to create a notification that will be triggered when another notification is displayed in swift

Basically, I have an application where the user can set the time of the first notification, and the following ones will happen repeatedly.基本上,我有一个应用程序,用户可以在其中设置第一次通知的时间,以下会重复发生。 For example, I want to be notified every 8 hours, but the first notification will not be from now on.例如,我想每 8 小时收到一次通知,但从现在开始不会第一次通知。 So I need to create 2 notifications, one for the first one, and as soon as the first one goes off, I need to set a new notification every 8 hours.所以我需要创建 2 个通知,一个用于第一个,一旦第一个发出,我需要每 8 小时设置一个新通知。

A practical example: I will take my medicine at 8 o'clock in the morning, but now it's 5 o'clock, and I want to be notified every 8 hours.一个实际的例子:我会在早上 8 点吃药,但现在是 5 点,我想每 8 小时收到一次通知。 The first alarm must be for 8 o'clock from 8 o'clock, that is, 4 o'clock.第一次闹铃一定要从8点到8点,也就是4点。 For that, I made a logic:为此,我做了一个逻辑:

在此处输入图像描述

However, the other alarms cannot have the same time as the first one, because, as in the previous example, if I left the same trigger, the alarms would be 11 hours, not 8. I need the first to be 11 hours, and the subsequent numbers of 8 in the example.但是,其他警报不能与第一个警报具有相同的时间,因为在前面的示例中,如果我留下相同的触发器,警报将是 11 小时,而不是 8。我需要第一个是 11 小时,并且示例中的后续数字 8。

I already have the code for the first alarm, however, I can't think of a way to create the subsequent ones, which will keep repeating according to the desired time, for example, 8 in 8, 12 in 12我已经有了第一个警报的代码,但是,我想不出一种方法来创建后续警报,它将根据所需的时间不断重复,例如 8 中的 8、12 中的 12

You need to setup a BGAppRefreshTask , which will tell the System to periodically wake your app to run in the Background to do something in about 30 seconds, then app is Suspended.您需要设置一个BGAppRefreshTask ,它将告诉系统定期唤醒您的应用程序以在后台运行以在大约 30 秒内执行某些操作,然后应用程序被暂停。 You can set a Refreshing Task every 6 hours to check and make a new Local Push Notification if needed.您可以每 6 小时设置一次刷新任务,以便在需要时检查并制作新的本地推送通知。

Here is the guide: https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/using_background_tasks_to_update_your_app这是指南: https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/using_background_tasks_to_update_your_app

When you setup your local notification:当您设置本地通知时:

// Create the request
let uuidString = UUID().uuidString // SAVE this one to UserDefault then you can fetch delivered/pending notification if needed.
let request = UNNotificationRequest(identifier: uuidString, 
            content: content, trigger: trigger)


// Schedule the request with the system.
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.add(request) { (error) in
   if error != nil {
      // Handle any errors.
   }
}

Function in your AppDelegate.swift Function 在您的 AppDelegate.swift

// Here you register it in didFinishLaunching()
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.apple-samplecode.ColorFeed.refresh", using: nil) { task in
     self.handleAppRefresh(task: task as! BGAppRefreshTask)
}

// Func to register a next background refresh task
func scheduleAppRefresh() {
   let request = BGAppRefreshTaskRequest(identifier: "com.example.apple-samplecode.ColorFeed.refresh")
   // Fetch no earlier than 15 minutes from now.
   request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
        
   do {
      try BGTaskScheduler.shared.submit(request)
   } catch {
      print("Could not schedule app refresh: \(error)")
   }
}

// Here is where you do your logic when the app runs by background refresh event.
func handleAppRefresh(task: BGAppRefreshTask) {
   // Schedule a new refresh task.
   scheduleAppRefresh()

   // Create an operation that performs the main part of the background task.
   let operation = RefreshAppContentsOperation() // you dont really need this one, just call your logic here.

   // Ex:
   UNUserNotificationCenter.current().getDeliveredNotifications {[weak self] listNoti in
       for noti in listNoti {
           if noti.identifier == [your UUID that you just save in UserDefault before] {
               // It delivered, now make new Local notification...
           }
       }
   }
   
   // Provide the background task with an expiration handler that cancels the operation.
   task.expirationHandler = {
      operation.cancel()
   }


   // Inform the system that the background task is complete
   // when the operation completes.
   operation.completionBlock = {
      task.setTaskCompleted(success: !operation.isCancelled)
   }


   // Start the operation.
   operationQueue.addOperation(operation)
 }

Use a repeating UNCalendarNotificationTrigger for each separate time of day.为一天中的每个单独时间使用重复的UNCalendarNotificationTrigger In your case, that means use three triggers (and therefore three requests): one each at 8, 16, and 0 hours.在您的情况下,这意味着使用三个触发器(因此三个请求):在 8、16 和 0 小时各一个。 You don't need to add a separate request for the soonest occurrence.您无需为最快的事件添加单独的请求。

for i in 0 ..< 3 {
    let when = DateComponents(hour: (8 + 8 * i) % 24, minute: 0)
    let trigger = UNCalendarNotificationTrigger(dateMatching: when, repeats: true)
    let request = UNNotificationRequest(
        identifier: "trigger-\(i)",
        content: someContent(),
        trigger: trigger
    )
    UNUserNotificationCenter.current().add(request) { error in
        if let error = error {
            // handle error
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM