You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift本地通知无法触发求助(Flutter混合开发场景)

Flutter调用Swift本地通知不触发问题排查与解决

我在Flutter项目中通过Method Channel调用Swift代码实现本地通知,使用的代码如下:

private func scheduleBGNotifications(result: FlutterResult) {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
        if success {
            print("All set!")
        } else if let error = error {
            print(error.localizedDescription)
        }
    }
    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: "Wake up!", arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: "Rise and shine! It's morning time!",arguments: nil)
      let calendar = Calendar(identifier: .gregorian)
      let notificationCenter = UNUserNotificationCenter.current()
      let notificationDate = Date().addingTimeInterval(TimeInterval(30))
      let component = calendar.dateComponents([.day,.month,.year, .hour,.minute,.second], from: notificationDate)
      print(component)
      let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: false)
      let request: UNNotificationRequest = UNNotificationRequest(identifier: "positiveAffirmation", content: content, trigger: trigger)
      UNUserNotificationCenter.current().add(request){(error) in
          if let _ = error {
              print("Failed to schedule notifications")
              assertionFailure()
          } else {
              print("Notification scheduled!")
          }
      }
}

已在didFinishLaunchingWithOptions中设置UNUserNotificationCenter.current().delegate = self,真机测试时打开APP后退出,通知未触发;已获取所有权限,此前应用可正常接收远程通知;控制台已打印“All set!”和“Notification scheduled!”。


解决方法

1. 替换日历触发器为时间间隔触发器

当前使用的UNCalendarNotificationTrigger依赖精确到秒的时间组件,系统时间微小偏差就会导致触发失败。对于固定延迟30秒的场景,改用UNTimeIntervalNotificationTrigger更可靠:

// 替换原trigger相关代码
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 30, repeats: false)

2. 完善UNUserNotificationCenterDelegate实现

仅设置delegate不够,需实现必要方法确保后台通知正常显示:

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .badge, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }
}

如果delegate在非AppDelegate类中实现,需确保该类实例不会被提前释放。

3. 使用唯一通知标识符

固定标识符"positiveAffirmation"可能导致新请求覆盖旧请求,改用UUID生成唯一ID:

let request = UNNotificationRequest(
    identifier: "positiveAffirmation_\(UUID().uuidString)",
    content: content,
    trigger: trigger
)

4. 验证通知是否已被调度

添加代码查询待触发通知列表,确认你的通知存在:

UNUserNotificationCenter.current().add(request){(error) in
    if let _ = error {
        print("Failed to schedule notifications")
        assertionFailure()
    } else {
        print("Notification scheduled!")
        // 查询待触发通知
        UNUserNotificationCenter.current().getPendingNotificationRequests { requests in
            print("待触发通知数量:\(requests.count)")
            requests.forEach { req in
                print("通知ID:\(req.identifier),触发器:\(req.trigger ?? "无")")
            }
        }
    }
}

5. 检查系统设置

  • 关闭设备的专注模式,避免通知被屏蔽
  • 确认APP通知权限为“允许通知”,且“锁定屏幕、通知中心、横幅”均已开启(设置→通知→你的APP)
  • 关闭低电量模式,该模式可能延迟或禁用本地通知

内容的提问来源于stack exchange,提问作者luminous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:32:03