Swift 4中如何合理移除重复本地通知?强制退出场景问题
解决iOS应用强退后本地通知仍触发的问题
嘿,这个问题我太熟了!当用户从多任务界面上滑强退应用时,你的应用会被系统直接终止,完全没机会执行removeAllPendingNotificationRequests()这类清理代码——而已经提交给系统通知中心的待执行通知请求,是存储在系统层面的,和你的应用进程无关,所以会继续按时触发,这就是问题的根源。
下面给你几个靠谱的解决方案:
方案1:给通知设置专属标识,应用启动时主动清理
这是最直接有效的办法,核心思路是给你的30分钟重复通知设置一个固定的唯一标识,然后在应用每次启动时,主动找到并移除这个标识对应的待执行请求。
首先,调度通知时用统一的标识:
// 创建通知内容 let content = UNMutableNotificationContent() content.title = "提醒" content.body = "已经过去30分钟啦" content.sound = UNNotificationSound.default // 创建30分钟重复触发的触发器 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1800, repeats: true) // 给请求设置专属标识,比如"recurring_30min_alert" let request = UNNotificationRequest( identifier: "recurring_30min_alert", content: content, trigger: trigger ) // 添加通知请求 UNUserNotificationCenter.current().add(request)然后在应用启动入口(比如
AppDelegate的didFinishLaunchingWithOptions或者SceneDelegate的willConnectTo方法)里,清理这个标识的通知:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 获取所有待执行的通知请求 UNUserNotificationCenter.current().getPendingNotificationRequests { requests in // 筛选出我们的30分钟重复通知 let targetIdentifiers = requests .filter { $0.identifier == "recurring_30min_alert" } .map { $0.identifier } // 移除这些请求 UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: targetIdentifiers) } return true }这样,只要用户重新打开应用,之前的重复通知就会被自动清理,要是需要继续接收,再点击开启按钮重新调度就行。
方案2:用UserDefaults记录通知状态,精准控制
如果想更精准地判断是否需要清理通知,可以用UserDefaults记录用户的通知开关状态:
用户点击开启通知按钮时,记录状态:
UserDefaults.standard.set(true, forKey: "isRecurringNotificationEnabled") // 然后调度通知...用户点击关闭按钮或销毁视图控制器时,更新状态并清理通知:
UserDefaults.standard.set(false, forKey: "isRecurringNotificationEnabled") UNUserNotificationCenter.current().removeAllPendingNotificationRequests()应用启动时,读取状态并处理:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let isEnabled = UserDefaults.standard.bool(forKey: "isRecurringNotificationEnabled") if !isEnabled { // 如果用户之前已经关闭了通知,直接清理所有待执行请求 UNUserNotificationCenter.current().removeAllPendingNotificationRequests() } return true }这个方案适合需要保留用户选择状态的场景,比如用户主动开启过通知,但强退应用后,如果你想继续触发,就可以不清理——不过通常用户强退应用大概率是想停止所有功能,所以默认清理会更符合预期。
额外小提示
- 注意iOS对重复通知触发器的限制:
UNTimeIntervalNotificationTrigger的重复间隔不能小于60秒,你的30分钟是完全符合要求的。 - 强制退出应用后,系统会继续执行已经调度好的通知,因为这些请求属于系统通知中心管理,和应用进程无关,所以必须通过应用下次启动时主动清理,没有办法在强退时直接触发清理代码。
内容的提问来源于stack exchange,提问作者Andrei
相关产品推荐
相关产品推荐

