Flutter iOS应用如何实现后台本地通知?
解决Flutter iOS后台本地通知的问题
嘿,作为iOS新手遇到这个问题很正常,我来帮你拆解一下:
关于“同时运行两个ViewController”的疑问
首先明确:iOS里可以存在多个ViewController,但这不是解决后台本地通知的正确方式。Flutter应用默认以FlutterViewController作为根控制器,你确实可以通过导航栈push或者模态弹出的方式展示自定义iOS VC,但本地通知的推送根本不需要额外的VC——通知是由iOS系统的通知中心负责展示的,和你的App界面VC没有直接关联。
更合适的本地通知实现方案
推荐两种靠谱的路径,不用折腾多VC:
方案1:使用Flutter成熟插件(最省心)
直接用flutter_local_notifications这个插件,它已经封装了iOS和Android的本地通知能力,包括后台调度的场景:
- 配置iOS权限:在
Info.plist中添加通知相关权限描述(NSLocalNotificationUsageDescription、NSAlertUsageDescription等) - 初始化插件:在Flutter的
main函数或者初始化页面中完成插件初始化,请求通知权限 - 调度通知:调用插件的
scheduleNotification方法,设置触发时间、内容等。iOS会通过系统的UNNotificationScheduler来处理,即使App在后台甚至被杀死,到时间系统也会自动推送通知到通知中心
示例代码(Dart侧):
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 初始化通知插件 Future<void> initNotifications() async { const IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(); const InitializationSettings initializationSettings = InitializationSettings(iOS: initializationSettingsIOS); await flutterLocalNotificationsPlugin.initialize(initializationSettings); } // 调度一个10秒后触发的本地通知 Future<void> scheduleNotification() async { const IOSNotificationDetails iosNotificationDetails = IOSNotificationDetails(); const NotificationDetails notificationDetails = NotificationDetails(iOS: iosNotificationDetails); await flutterLocalNotificationsPlugin.schedule( 0, '后台通知标题', '这是一条Flutter后台触发的本地通知', DateTime.now().add(const Duration(seconds: 10)), notificationDetails, androidAllowWhileIdle: true, ); }
方案2:原生iOS代码实现(自定义需求场景)
如果需要完全自定义原生逻辑,也不需要额外VC,直接在App的原生入口集成UserNotifications框架:
- 在
AppDelegate.swift或者FlutterAppDelegate的子类中,导入UserNotifications - 请求通知权限,创建并调度
UNNotificationRequest - 所有逻辑都在App启动或后台回调中完成,不需要替换Flutter的VC
示例代码(iOS Swift侧):
import UIKit import Flutter import UserNotifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { // 请求通知权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { // 权限通过后调度通知 self.scheduleLocalNotification() } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } func scheduleLocalNotification() { let content = UNMutableNotificationContent() content.title = "原生后台通知" content.body = "这是iOS原生调度的本地通知" content.sound = .default // 设置10秒后触发通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false) let request = UNNotificationRequest(identifier: "LocalNotification", content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("通知调度失败:\(error.localizedDescription)") } } } }
关键提醒
- iOS的本地通知是系统级别的调度,不需要App在后台保持运行,只要你正确配置了通知请求,系统会负责按时推送
- 如果需要在通知被点击后跳转特定页面,不管用插件还是原生实现,都可以通过监听通知点击事件来处理(插件有回调,原生可以在
UNUserNotificationCenterDelegate中处理)
内容的提问来源于stack exchange,提问作者camilleB
相关产品推荐
相关产品推荐

