我试图在应用程序的后台、前台和终止状态下接收到 firebase 通知时显示 flutter 本地通知。我正在尝试使用工作管理器包来解决这个问题,它在 android 中的工作就像一个魅力。它也适用于前台、后台和终止状态,但不适用于 ios 设备。如果我试图执行未在 info plist 和 appDelegate 中注册的任务,它会给我一个错误,但在注册后它什么也没做(没有错误,也没有执行我的代码)。我想象我的任务已注册,但 iOS 出于某种原因没有执行它。如果有人做过类似的事情,请提供一些例子或者一些关于我做错了什么的想法?
尝试使用工作管理器和 flutter 本地通知解决问题
我为这个问题苦苦挣扎了好几个星期,直到我设法让我的 ios 应用程序无论其状态如何都显示通知。
首先,您必须在 Xcode 中勾选“Background fetch”和“Background processing”模式。这些可以在签名和功能下找到。
接下来,您必须注册您的任务并在您的 AppDelegate.swift 中提供您的应用程序通知功能。
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
UNUserNotificationCenter.current().delegate = self
WorkmanagerPlugin.setPluginRegistrantCallback { registry in
// Registry, in this case is the FlutterEngine that is created in Workmanager's
// performFetchWithCompletionHandler or BGAppRefreshTask.
// This will make other plugins available during a background operation.
GeneratedPluginRegistrant.register(with: registry)
}
// you will need to duplicate the line below for each identifier
WorkmanagerPlugin.registerTask(withIdentifier: "your.task.identifier")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(.alert) // shows banner even if app is in foreground
}
}
您还需要在 info.plist 中注册您的任务:
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>your.task.identifier/string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>
registerPeriodicTask 不适用于 ios,因此,您应该使用 flutter_local_notifications periodicallyShow 函数。
作为参考,我提供了我的代码片段,展示了我如何使用 workmanager 和 flutter_local_notifications;
void registerWorkmanagerTask() async {
try {
await Workmanager().registerOneOffTask(
AppConstants.notifyReviewTask,
AppConstants.notifyReviewTask,
initialDelay: Duration(hours: 4),
existingWorkPolicy: ExistingWorkPolicy.replace,
backoffPolicy: BackoffPolicy.linear,
);
} catch (e) {
print("exception caught $e");
}
}
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask((taskName, _) async {
try {
await NotificaitonService().setup();
if (taskName == AppConstants.notifyReviewTask)
await NotificaitonService().showNotification(
body: 'items are ready to be reviewed',
notificationId: AppConstants.recallNotificationId,
channel: AppConstants.recallChannel,
title: 'Time to review',
);
return Future.value(true);
} catch (e) {
print("exception caught $e");
}
});
}
请记住,iOS 设备可能会出于多种原因(例如电池电量不足)决定推迟运行后台工作管理器任务,对此我们无能为力。