Flutter:iOS Release模式下后台本地通知不生效求助
iOS Release模式下flutter_local_notifications后台本地通知不显示问题
问题概述
使用flutter_local_notifications v16.1.0实现本地通知功能,Android全模式、iOS Debug模式均正常运行,但iOS Release模式下后台无法展示本地通知。
已完成排查
- 确认使用最新版本flutter_local_notifications(v16.1.0)
- 已开启iOS Debug/Release模式Signing & Capabilities中的Background modes权限(包含fetch、remote notifications)
实现代码
import 'dart:async'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; class ReceivedNotification { ReceivedNotification({ required this.id, required this.title, required this.body, required this.payload, }); final int id; final String? title; final String? body; final String? payload; } /// 触发应用导航的通知动作 const String navigationActionId = 'id_3'; @pragma('vm:entry-point') void notificationTapBackground(NotificationResponse notificationResponse) { // ignore: avoid_print print('通知(${notificationResponse.id})被点击: ' '动作ID: ${notificationResponse.actionId}, ' '负载: ${notificationResponse.payload}'); if (notificationResponse.input?.isNotEmpty ?? false) { // ignore: avoid_print print('通知点击附带输入内容: ${notificationResponse.input}'); } } class NotificationService { // 单例模式 static final NotificationService _notificationService = NotificationService._internal(); factory NotificationService() { return _notificationService; } NotificationService._internal(); /// 创建流以响应通知相关事件(插件在main函数初始化) final StreamController<ReceivedNotification> didReceiveLocalNotificationStream = StreamController<ReceivedNotification>.broadcast(); final StreamController<String?> selectNotificationStream = StreamController<String?>.broadcast(); // FlutterLocalNotificationsPlugin实例 final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); Future<void> initialize() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@drawable/iclauncher'); // iOS初始化设置 final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings( requestSoundPermission: true, requestBadgePermission: true, requestAlertPermission: true, onDidReceiveLocalNotification: (int id, String? title, String? body, String? payload) async { didReceiveLocalNotificationStream.add( ReceivedNotification( id: id, title: title, body: body, payload: payload, ), ); }, ); final InitializationSettings settings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, ); await flutterLocalNotificationsPlugin.initialize( settings, onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) { switch (notificationResponse.notificationResponseType) { case NotificationResponseType.selectedNotification: selectNotificationStream.add(notificationResponse.payload); break; case NotificationResponseType.selectedNotificationAction: if (notificationResponse.actionId == navigationActionId) { selectNotificationStream.add(notificationResponse.payload); } break; } }, onDidReceiveBackgroundNotificationResponse: notificationTapBackground, ); } Future<NotificationDetails> _notificationDetails() async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'channel ID', 'channel name', playSound: true, priority: Priority.high, importance: Importance.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); return notificationDetails; } Future<void> showNotification({ required int id, required String title, required String body, }) async { final details = await _notificationDetails(); await flutterLocalNotificationsPlugin.show(id, title, body, details); } }
解决方向
- 补充iOS专属通知配置
当前_notificationDetails()方法仅配置了Android端参数,iOS Release模式下需要明确配置弹窗、徽章、声音等权限,否则可能被系统拦截。修改该方法:
Future<NotificationDetails> _notificationDetails() async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'channel ID', 'channel name', playSound: true, priority: Priority.high, importance: Importance.high, ); // 添加iOS通知配置 const DarwinNotificationDetails darwinNotificationDetails = DarwinNotificationDetails( presentAlert: true, presentBadge: true, presentSound: true, ); const NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, iOS: darwinNotificationDetails ); return notificationDetails; }
- 验证权限状态
Release模式下需主动检查用户是否开启通知权限,避免权限被关闭导致通知无法展示:
// 在initialize方法中添加权限检查逻辑 final bool hasPermission = await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>() ?.requestPermissions( alert: true, badge: true, sound: true, ) ?? false; if (!hasPermission) { // 提示用户前往设置开启通知权限 }
确认后台触发逻辑
如果是定时触发通知,需使用zonedSchedule等支持后台调度的API,而非仅用show(show多用于前台即时触发)。同时确保应用处于后台活跃状态,完全退出后iOS系统不会触发本地通知。检查Xcode编译配置
- 确认Release模式下未开启
Strip Debug Symbols During Copy等可能影响后台代码执行的选项 - 验证
Info.plist中已添加UIBackgroundModes字段,包含fetch和remote-notification值
内容的提问来源于stack exchange,提问作者Jean-Noël Aubry
相关产品推荐
相关产品推荐

