APNs 远程通知,用于 Perfect 框架。此包为你的服务器添加推送通知支持。向 iOS/macOS 设备发送通知。
这是一个基于 Swift Package Manager 的项目。将此仓库作为依赖项添加到你的 Package.swift 文件中。
.package(url:"https://github.com/PerfectlySoft/Perfect-Notifications.git", from: "5.0.0")
此系统在服务器端运行。通常在应用程序启动时,Apple 设备将向 Apple 系统注册远程通知。这样做将返回给设备一个 ID,外部系统可以使用该 ID 来寻址设备并通过 APNs 发送通知。
当设备获得其 ID 后,它需要将其传输到你的服务器。你的服务器将存储此 ID,并在通过 APNs 向一个或多个设备发送通知时使用它。
要将你的服务器连接到 Apple 的推送通知系统,你首先需要获取一个 “APNs 身份验证密钥”。此密钥在你的服务器上用于配置其 APNs 访问权限。你可以通过你的 Apple 开发者帐户门户生成此密钥。登录到你的开发者帐户,然后从菜单中选择 “证书、ID 和描述文件”。然后,在 “密钥” 下,选择 “全部”。
如果你尚未创建和下载身份验证密钥,请单击 “+” 以创建一个新的密钥。输入密钥的名称,并确保选择Apple Push Notifications service (APNs)。此密钥可用于开发或生产环境,并且可用于你的任何 iOS/macOS 应用程序。
单击 “继续”,然后单击 “确认”,然后你将有机会下载私钥。你必须立即下载此密钥并保存文件。同时复制同一视图中显示的 “密钥 ID”。这将是一个 10 个字符的字符串。
最后,你需要找到你的开发者团队 ID。单击窗口顶部的 “帐户”。在菜单中选择 “成员资格”。然后你将看到你的许多个人信息,包括 “团队 ID”。这是另一个 10 个字符的字符串。复制此值。
要从你的服务器发送通知,你必须拥有以下三条信息
这四条信息用于执行推送通知。此信息必须驻留在你的服务器上。你可以以任何方式存储此信息,只要服务器可以使用它即可。为了简单起见,本示例的其余部分假设私钥文件位于服务器的工作目录中,并且两个密钥和应用程序 ID 都嵌入在 Swift 代码中。
在你的服务器 Swift 代码中,你必须 import PerfectNotifications
。然后,在你启动任何 HTTP 服务器或发送任何通知之前,你必须为你将要发送的通知添加 “配置”。这非常简单地将你的 APNs 密钥与一个名称关联起来,你可以在以后推送通知时使用该名称。
import PerfectNotifications
// your app id. we use this as the configuration name, but they do not have to match
let notificationsAppId = "my.app.id"
let apnsKeyIdentifier = "AB90CD56XY"
let apnsTeamIdentifier = "YX65DC09BA"
let apnsPrivateKeyFilePath = "./APNsAuthKey_AB90CD56XY.p8"
NotificationPusher.addConfigurationAPNS(
name: notificationsTestId,
production: false, // should be false when running pre-release app in debugger
keyId: apnsKeyIdentifier,
teamId: apnsTeamIdentifier,
privateKeyPath: apnsPrivateKeyFilePath)
添加配置后,可以在任何时候发送通知。为此,使用你的应用程序 ID 或 “主题” 创建一个 NotificationPusher
,然后通过调用其 pushAPNS
函数来触发向一个或多个设备的通知
let deviceIds: [String] = [...]
let n = NotificationPusher(apnsTopic: notificationsTestId)
n.pushAPNS(
configurationName: notificationsTestId,
deviceTokens: deviceIds,
notificationItems: [.alertBody("Hello!"), .sound("default")]) {
responses in
print("\(responses)")
...
}
创建 NotificationPusher 时,主题是必需的。可以提供其他可选参数来自定义通知的过期时间、优先级和 collapse-id。有关这些选项的语义,请查阅 Apple 的 APNS 文档。
以下是通知推送器的完整公共版本 3.0 API
public class NotificationPusher {
/// Add an APNS configuration which can be later used to push notifications.
public static func addConfigurationAPNS(
name: String,
production: Bool,
keyId: String,
teamId: String,
privateKeyPath: String)
/// Initialize given an apns-topic string.
public init(
apnsTopic: String,
expiration: APNSExpiration = .immediate,
priority: APNSPriority = .immediate,
collapseId: String? = nil)
/// Push one message to one device.
/// Provide the previously set configuration name, device token.
/// Provide a list of APNSNotificationItems.
/// Provide a callback with which to receive the response.
public func pushAPNS(
configurationName: String,
deviceToken: String,
notificationItems: [APNSNotificationItem],
callback: @escaping (NotificationResponse) -> ())
/// Push one message to multiple devices.
/// Provide the previously set configuration name, and zero or more device tokens. The same message will be sent to each device.
/// Provide a list of APNSNotificationItems.
/// Provide a callback with which to receive the responses.
public func pushAPNS(
configurationName: String, deviceTokens: [String],
notificationItems: [APNSNotificationItem],
callback: @escaping ([NotificationResponse]) -> ())
}
其余结构,包括 APNSNotificationItem 如下
/// Items to configure an individual notification push.
public enum APNSNotificationItem {
/// alert body child property
case alertBody(String)
/// alert title child property
case alertTitle(String)
/// alert title-loc-key
case alertTitleLoc(String, [String]?)
/// alert action-loc-key
case alertActionLoc(String)
/// alert loc-key
case alertLoc(String, [String]?)
/// alert launch-image
case alertLaunchImage(String)
/// aps badge key
case badge(Int)
/// aps sound key
case sound(String)
/// aps content-available key
case contentAvailable
/// aps category key
case category(String)
/// aps thread-id key
case threadId(String)
/// custom payload data
case customPayload(String, Any)
/// apn mutable-content key
case mutableContent
}
public enum APNSPriority: Int {
case immediate = 10
case background = 5
}
/// Time in the future when the notification, if has not be able to be delivered, will expire.
public enum APNSExpiration {
/// Discard the notification if it can't be immediately delivered.
case immediate
/// now + seconds
case relative(Int)
/// absolute UTC time since epoch
case absolute(Int)
}
/// The response object given after a push attempt.
public struct NotificationResponse: CustomStringConvertible {
/// The response code for the request.
public let status: HTTPResponseStatus
/// The response body data bytes.
public let body: [UInt8]
/// The body data bytes interpreted as JSON and decoded into a Dictionary.
public var jsonObjectBody: [String:Any]
/// The body data bytes converted to String.
public var stringBody: String
public var description: String
}
APNs 请求从你的服务器发送到 Apple 的服务器 “api.development.push.apple.com” 或 “api.push.apple.com”,端口为 443。当向一个或多个设备发送一个通知时,将使用一个请求。每个连接将保持打开状态,并在发送后续通知时重复使用。如果连接 “消失” 或没有可用的空闲连接,则将打开一个新连接。这符合 Apple 推荐的 APNs 用法,并应在处理许多并发通知请求时提供最佳吞吐量。
请查阅 Perfect-NotificationsExample,以获取客户端/服务器组合,该组合可以轻松地使用你自己的信息进行配置,从而为你的应用程序快速获取 APNS 通知。
有关 Perfect 项目的更多信息,请访问 perfect.org。