APNS
用于在 iOS 上实现 APNS 推送通知,在 Android 上实现 Firebase 的插件。
为什么制作这个插件?
目前,唯一可用的推送通知插件是 `firebase_messaging`。这意味着,即使在 iOS 上,您也需要设置 firebase 并与 Google 通信以发送推送通知。此插件通过提供原生 APNS 实现来解决此问题,同时保留为 Android 配置的 Firebase。
用法
-
根据说明在 Android 上配置 firebase:https://pub.dartlang.org/packages/firebase_messaging。
-
在 iOS 上,请确保您已正确配置应用程序以支持推送通知,并已生成用于发送推送的证书/令牌。有关更多信息,请参阅 如何运行 iOS 示例应用程序 部分。
-
将以下行添加到 iOS 项目的 AppDelegate.m/AppDelegate.swift 文件中的 `didFinishLaunchingWithOptions` 方法中。
Objective-C
if (@available(iOS 10.0, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
Swift
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
- 将 `flutter_apns` 添加到您 `pubspec.yaml` 文件中的 依赖项。
- 使用 `createPushConnector()` 方法,根据您的需求配置推送服务。`PushConnector` 非常类似于 `FirebaseMessaging`,因此在实现过程中 Firebase 示例可能很有用。您应该尽快创建连接器,以使 onLaunch 回调在应用程序关闭时启动时能够正常工作。
import 'package:flutter_apns/apns.dart';
final connector = createPushConnector();
connector.configure(
onLaunch: _onLaunch,
onResume: _onResume,
onMessage: _onMessage,
);
connector.requestNotificationPermissions()
- 在设备上构建,并使用 Firebase 控制台(Android)和 CURL(iOS,请参阅 如何运行 iOS 示例应用程序)测试您的解决方案。
其他 APNS 功能
在前台显示通知
final connector = createPushConnector();
if (connector is ApnsPushConnector) {
connector.shouldPresent = (x) => Future.value(true);
}
处理预定义操作
首先,配置支持的操作
final connector = createPushConnector();
if (connector is ApnsPushConnector) {
connector.setNotificationCategories([
UNNotificationCategory(
identifier: 'MEETING_INVITATION',
actions: [
UNNotificationAction(
identifier: 'ACCEPT_ACTION',
title: 'Accept',
options: [],
),
UNNotificationAction(
identifier: 'DECLINE_ACTION',
title: 'Decline',
options: [],
),
],
intentIdentifiers: [],
options: [],
),
]);
}
然后,在您的推送处理程序中处理可能的操作
Future<dynamic> onPush(String name, RemoteMessage payload) {
final action = UNNotificationAction.getIdentifier(payload.data);
if (action == 'MEETING_INVITATION') {
// do something
}
return Future.value(true);
}
注意:如果用户在应用程序处于后台时点击您的通知,推送将通过 onResume 传递,而不会实际唤醒应用程序。请确保您对给定操作的处理快速且无误,因为后台运行的应用程序的执行时间非常有限。
请查看示例项目以获取完整的可用代码。
启用 FirebaseCore
如果您想使用 firebase,但不是 firebase messaging,请将此配置条目添加到您的 Info.plist(以避免 MissingPluginException)。
<key>flutter_apns.disable_firebase_core</key>
<false/>
flutter_apns_only – 无 firebase 的 APNS
如果您只关心 apns – 请使用 flutter_apns_only 插件。它不依赖于 firebase。为确保不发生(原始插件需要此操作来禁用 firebase)的 swizzling,请将此配置条目添加到您的 Info.plist。
<key>flutter_apns.disable_swizzling</key>
<true/>
故障排除
- 确保您在实际设备上进行测试。注意:从 11.4 开始可能不需要此项:https://ohmyswift.com/blog/2020/02/13/simulating-remote-push-notifications-in-a-simulator/
- 如果 onToken 方法未被调用,请在您的 AppDelegate 中添加错误日志记录,请参阅下面的代码。
- 打开 macOS 的 Console 应用程序,连接您的设备,然后运行您的应用程序。在日志中搜索“PUSH registration failed”字符串。错误消息将告诉您出了什么问题。
swift
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
NSLog("PUSH registration failed: \(error)")
}
}
objc
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"%@", error);
}
@end
如何运行 iOS 示例应用程序
在 iOS 上设置推送通知可能会很棘手,因为无法允许需要复杂证书设置的 Apple Push Notification Service (APNS)。以下指南描述了一个分步方法,用于通过此包的示例应用程序从 Mac 向 iPhone 发送推送通知。本指南仅描述调试环境设置。
- 使用 Xcode 打开示例 iOS 文件夹
- 选择 Runner -> Signing & Capabilities
- 选择您的开发团队,并添加一个全局唯一的捆绑标识符。图片中的那个已占用:

- 访问 https://developer.apple.com/account/resources/identifiers/list/bundleId 并点击加号按钮。
- 选择“App IDs”并继续

- 选择类型“App”
- 选择“App ID Prefix”,它应该与“Team ID”相同。
- 输入描述和捆绑标识符。后者需要与 3 中指定的捆绑标识符相同。
- 选择推送通知功能

- 点击“Continue”然后点击“Register”。
- 访问 https://developer.apple.com/account/resources/certificates 并通过点击加号按钮添加新证书。
- 选择“Apple Push Notification service SSL (Sandbox & Production)”

- 选择您在第 4-10 点定义的应用程序 ID。
- 选择一个证书签名请求 (CSR) 文件。有关如何创建此证书的信息,请参阅 https://help.apple.com/developer-account/。
- 完成后,下载新创建的 Apple Push Services 证书。
- 通过打开新下载的文件将证书添加到您的本地钥匙串。
- 点击钥匙串窗口左上角的“login”,然后选择“My Certificates”选项卡

- 右键单击 Apple-Push-Services-certificate,然后将其导出为 .p12 文件。
- 使用以下命令将 p12 文件转换为 pem 文件。请注意,“flutterApns”需要替换为您相应的证书名称。 更多信息
openssl pkcs12 -in flutterApns.p12 -out flutterApns.pem -nodes -clcerts - 从 Xcode 或您喜欢的 IDE 在物理 iPhone 设备上启动示例应用程序。
- 当应用程序能够从 APNS 检索到推送令牌时,设备令牌会自动打印出来。这发生在接受通知权限提示后。
- 从您的开发 Mac 发送以下 CURL。您可以将 CURL 复制并粘贴到终端中执行,然后按 Enter。 更多信息
curl -v \ -d '{"aps":{"alert":"<your_message>","badge":2}}' \ -H "apns-topic: <bundle_identifier_of_registered_app>" \ -H "apns-priority: 10" \ --http2 \ --cert <file_path_to_downloaded_signed_and_converted_certificate>.pem \ https://api.development.push.apple.com/3/device/<device_token> - 当示例应用程序处于后台时,会出现推送通知。
如果不使用示例应用程序,您还需要 在 Xcode 中设置推送通知功能 并添加 使用 中提到的代码。