在前台和后台收到 firebase 通知时显示 flutter 本地通知

问题描述 投票:0回答:1

我试图在应用程序的后台、前台和终止状态下接收到 firebase 通知时显示 flutter 本地通知。我正在尝试使用工作管理器包来解决这个问题,它在 android 中的工作就像一个魅力。它也适用于前台、后台和终止状态,但不适用于 ios 设备。如果我试图执行未在 info plist 和 appDelegate 中注册的任务,它会给我一个错误,但在注册后它什么也没做(没有错误,也没有执行我的代码)。我想象我的任务已注册,但 iOS 出于某种原因没有执行它。如果有人做过类似的事情,请提供一些例子或者一些关于我做错了什么的想法?

尝试使用工作管理器和 flutter 本地通知解决问题

flutter dart background-task flutter-local-notification flutter-workmanager
1个回答
0
投票

我为这个问题苦苦挣扎了好几个星期,直到我设法让我的 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 设备可能会出于多种原因(例如电池电量不足)决定推迟运行后台工作管理器任务,对此我们无能为力。

© www.soinside.com 2019 - 2024. All rights reserved.