Perfect-Notifications 简体中文

Get Involed with Perfect!

Swift 5.2 Platforms OS X | Linux License Apache

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 向一个或多个设备发送通知时使用它。

获取 APNs 身份验证密钥

要将你的服务器连接到 Apple 的推送通知系统,你首先需要获取一个 “APNs 身份验证密钥”。此密钥在你的服务器上用于配置其 APNs 访问权限。你可以通过你的 Apple 开发者帐户门户生成此密钥。登录到你的开发者帐户,然后从菜单中选择 “证书、ID 和描述文件”。然后,在 “密钥” 下,选择 “全部”。

如果你尚未创建和下载身份验证密钥,请单击 “+” 以创建一个新的密钥。输入密钥的名称,并确保选择Apple Push Notifications service (APNs)。此密钥可用于开发或生产环境,并且可用于你的任何 iOS/macOS 应用程序。

单击 “继续”,然后单击 “确认”,然后你将有机会下载私钥。你必须立即下载此密钥并保存文件。同时复制同一视图中显示的 “密钥 ID”。这将是一个 10 个字符的字符串。

最后,你需要找到你的开发者团队 ID。单击窗口顶部的 “帐户”。在菜单中选择 “成员资格”。然后你将看到你的许多个人信息,包括 “团队 ID”。这是另一个 10 个字符的字符串。复制此值。

服务器配置

要从你的服务器发送通知,你必须拥有以下三条信息

  1. 已下载的私钥文件
  2. 10 个字符的密钥 ID
  3. 你的 10 个字符的团队 ID
  4. 一个 iOS/macOS 应用程序 ID

这四条信息用于执行推送通知。此信息必须驻留在你的服务器上。你可以以任何方式存储此信息,只要服务器可以使用它即可。为了简单起见,本示例的其余部分假设私钥文件位于服务器的工作目录中,并且两个密钥和应用程序 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 文档。

公共 API

以下是通知推送器的完整公共版本 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