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

Flutter中OneSignal静默通知iOS端无法触发的问题求助

解决iOS端OneSignal静默通知无法触发Flutter回调的问题

我之前也碰到过一模一样的情况——用onesignal_flutter: ^2.0.0时,iOS的静默通知能在原生AppDelegate里拿到数据,但就是触发不了Flutter层的setNotificationReceivedHandler。后来才搞明白,这个版本的插件默认只把带UI的显示型通知事件转发到Flutter,静默通知(content_available: true)并没有被纳入回调触发范围。下面给你两个可行的解决方案:

方案一:通过MethodChannel手动传递静默通知数据(最可靠,兼容当前版本)

既然原生层已经能捕获到静默通知,我们可以用Flutter的MethodChannel把数据传到Dart层,步骤很清晰:

1. iOS端(AppDelegate.swift)修改

在AppDelegate里实现远程通知回调,判断是否为静默通知,然后通过通道把数据发给Flutter:

import Flutter
import OneSignal

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    // 自定义通道名称,要和Flutter端保持一致
    private let silentNotificationChannel = FlutterMethodChannel(name: "com.your.app/onesignal_silent", binaryMessenger: window!.rootViewController as! FlutterBinaryMessenger)
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // 保留你原有的OneSignal初始化代码
        OneSignal.initWithLaunchOptions(launchOptions)
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // 判断是否为静默通知:content_available为1,且没有alert字段
        let aps = userInfo["aps"] as? [String: Any] ?? [:]
        let isSilent = (aps["content-available"] as? Int ?? 0 == 1) && (aps["alert"] == nil)
        
        if isSilent {
            // 把静默通知数据传给Flutter
            silentNotificationChannel.invokeMethod("onSilentNotificationReceived", arguments: userInfo)
        }
        
        // 必须调用OneSignal的原生处理,保证普通通知正常工作
        OneSignal.didReceiveRemoteNotification(userInfo, fetchCompletionHandler: completionHandler)
    }
}

2. Flutter端监听通道

在Dart代码里初始化MethodChannel,监听来自原生的静默通知事件:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
  // 初始化静默通知监听
  _setupSilentNotificationListener();
}

final MethodChannel _silentNotificationChannel = MethodChannel('com.your.app/onesignal_silent');

void _setupSilentNotificationListener() {
  _silentNotificationChannel.setMethodCallHandler((MethodCall call) async {
    if (call.method == 'onSilentNotificationReceived') {
      // 这里处理你的静默通知业务逻辑
      print('收到iOS静默通知:${call.arguments}');
      // 比如更新本地缓存、发起后台请求等
    }
  });
}

// 你的其他Flutter业务代码...

方案二:升级onesignal_flutter版本(可选,注意API变更)

onesignal_flutter: ^2.0.0是比较老旧的版本了,后续的3.x版本可能修复了静默通知的回调转发问题。不过升级前要注意:3.x版本的API和2.x差异很大,比如初始化方式、回调方法名都有调整,需要对照官方文档修改现有代码。

额外注意事项

  • 确保iOS项目的Capabilities里已经勾选了Background Modes下的Remote notifications;
  • 发送静默通知的API请求中,iOS 13+必须添加apns_push_type: "background"参数,否则系统会拦截通知;
  • 静默通知触发条件严格:App不能被用户强制关闭,设备需联网,且后台刷新权限未被禁用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:42:58