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

Flutter iOS端前台无法接收OneSignal静默通知问题排查

iOS Flutter应用前台无法接收OneSignal静默通知的解决方案

核心问题排查

  1. OneSignal SDK未初始化:你的AppDelegate里完全没初始化OneSignal,这直接导致SDK无法接管通知处理逻辑,静默通知自然没法触发原生回调。
  2. 前台通知回调未配置:没有设置UNUserNotificationCenter的delegate,前台收到通知时不会走原生方法,全被OneSignal Flutter插件拦截了。
  3. 静默通知Payload可能不符合要求:APN发送的静默通知必须严格符合格式,否则iOS不会识别为静默通知。

具体修复步骤

1. 补全OneSignal初始化与Delegate配置

修改AppDelegate.swift,添加OneSignal初始化代码,同时设置通知中心delegate,确保前台通知能触发原生回调:

import Flutter
import UIKit
import OneSignal // 别忘了导入OneSignal

@main
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        print("**** didFinishLaunchingWithOptions ****");
        
        // 初始化OneSignal,替换成你的App ID
        OneSignal.initialize("YOUR_ONESIGNAL_APP_ID", withLaunchOptions: launchOptions)
        
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        // 设置delegate,确保前台通知能触发原生方法
        center.delegate = self
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    // 处理前台收到的所有通知(包括非静默和静默)
    override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("**** 前台收到通知 ****")
        let userInfo = notification.request.content.userInfo
        
        // 检查是否为静默通知
        if let aps = userInfo["aps"] as? [String: Any], aps["content-available"] as? Int == 1 {
            // 传递给Flutter
            if let flutterVC = window?.rootViewController as? FlutterViewController {
                let channel = FlutterMethodChannel(name: "com.shachardev.vivencia/notifications", binaryMessenger: flutterVC.binaryMessenger)
                channel.invokeMethod("notificationReceived", arguments: userInfo)
            }
            // 静默通知不需要展示,直接传空选项
            completionHandler([])
        } else {
            // 非静默通知交给OneSignal处理,同时展示通知
            OneSignal.didReceiveNotificationExtensionRequest(notification.request, with: notification.request.content.mutableCopy() as! UNMutableNotificationContent, withContentHandler: { content in
                completionHandler([.alert, .sound, .badge])
            })
        }
    }

    override func application(
        _ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable: Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        print("**** didReceiveRemoteNotification ****");
               
        DispatchQueue.main.async {
                print("收到通知内容: \(userInfo)")
        }        
        // 处理静默通知
        if let aps = userInfo["aps"] as? [String: Any],
           aps["content-available"] as? Int == 1 {
            if let flutterVC = window?.rootViewController as? FlutterViewController {
                let channel = FlutterMethodChannel(name: "com.shachardev.vivencia/notifications", binaryMessenger: flutterVC.binaryMessenger)
                channel.invokeMethod("notificationReceived", arguments: userInfo)
            }
            completionHandler(.newData)
            return
        }

        // 非静默通知交给OneSignal处理
        OneSignal.didReceiveRemoteNotification(userInfo, fetchCompletionHandler: completionHandler)
    }
}

2. 确保静默通知Payload格式正确

通过APN控制台发送的静默通知必须满足:

  • aps字典必须包含"content-available": 1
  • 不能有alert、badge、sound这些会触发通知展示的字段
  • 示例Payload:
{
  "aps": {
    "content-available": 1
  },
  "custom_data": "你的自定义数据"
}

3. 验证后台权限配置

  • 在Xcode的Signing & Capabilities中,添加Background Modes,勾选Remote notifications
  • 确认Info.plist中UIBackgroundModes数组包含remote-notification

4. 关于NotificationServiceExtension

这个扩展只处理带有mutable-content: 1的通知(比如需要修改通知内容、加附件),静默通知不需要这个扩展,所以它不会触发,属于正常情况。如果不需要修改通知内容,可以直接移除这个扩展。

测试注意事项

  • 必须用真机测试,模拟器收不到APN通知
  • 设备要登录Apple ID,并且开启了应用的通知权限
  • 测试前台静默通知时,确保应用处于完全活跃的前台状态(没被挂起)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:22:06