远程推送通知(Push Notifications)在 iOS 平台上是免费提供的,但需要一些准备工作。以下是开通和使用远程推送通知的基本步骤:
开通远程推送通知
注册 Apple Developer Program:
访问 Apple Developer 并注册一个开发者账号。个人开发者账号是免费的,但如果你想发布应用到 App Store,需要支付 99 美元/年的费用。
创建和配置 App ID:
登录 Apple Developer 账号,进入 Certificates, Identifiers & Profiles。
创建一个新的 App ID,并启用“Push Notifications”服务。
创建和下载推送证书:
在同一页面中,创建一个新的推送证书(Push Notification SSL Certificate)。
下载并安装证书,以便在你的服务器上使用。
配置 APNs 证书:
将下载的推送证书导出为 .p12 文件。
将 .p12 文件转换为 .pem 文件(可选,取决于你的服务器需求)。
在 Xcode 中配置项目:
打开你的 Xcode 项目。
选择项目的 Target,进入“Signing & Capabilities”选项卡。
添加“Push Notifications”功能。
确保你的 App ID 和 Team 都正确配置。
代码示例
以下是一个简单的示例,展示如何在 iOS 应用中注册和接收远程推送通知:
请求推送通知权限
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 请求推送通知权限
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
print("通知权限已授予")
} else {
print("通知权限被拒绝")
}
}
// 注册推送通知
application.registerForRemoteNotifications()
return true
}
// 处理远程推送通知的注册
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
// 将设备令牌发送到你的服务器
sendDeviceTokenToServer(deviceToken: token)
}
// 处理远程推送通知的注册失败
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: \(error.localizedDescription)")
}
// 发送设备令牌到服务器
func sendDeviceTokenToServer(deviceToken: String) {
// 你的服务器端逻辑
print("Sending device token to server: \(deviceToken)")
}
}
接收推送通知
Swift
浅色版本
import UserNotifications
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 请求推送通知权限
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
print("通知权限已授予")
} else {
print("通知权限被拒绝")
}
}
// 注册推送通知
application.registerForRemoteNotifications()
return true
}
// 处理远程推送通知的注册
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
// 将设备令牌发送到你的服务器
sendDeviceTokenToServer(deviceToken: token)
}
// 处理远程推送通知的注册失败
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: \(error.localizedDescription)")
}
// 发送设备令牌到服务器
func sendDeviceTokenToServer(deviceToken: String) {
// 你的服务器端逻辑
print("Sending device token to server: \(deviceToken)")
}
// 处理接收到的推送通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// 处理用户点击通知后的操作
print("Notification received: \(response.notification.request.content.body)")
completionHandler()
}
}
服务器端
你需要一个服务器来发送推送通知。可以使用 Apple 的 APNs (Apple Push Notification service)。以下是一个简单的 Node.js 示例,展示如何使用 apn 库发送推送通知:
const apn = require('apn');
// 创建 APNs 连接
const options = {
token: {
key: './path/to/your/key.p8', // APNs auth key
keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
},
production: false // Set to true if sending notifications to production devices
};
const apnProvider = new apn.Provider(options);
// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app
// 发送通知
const deviceToken = 'YOUR_DEVICE_TOKEN';
apnProvider.send(note, deviceToken).then((result) => {
console.log(result);
});
总结
注册 Apple Developer Program:免费注册,但发布应用到 App Store 需要付费。
配置 App ID 和推送证书:在 Apple Developer 账户中完成。
在 Xcode 中配置项目:添加“Push Notifications”功能。
请求和处理推送通知:在应用中请求权限并处理通知。
服务器端:使用 APNs 发送推送通知。
配置服务器端
发送远程推送通知(APNs)涉及几个步骤。
以下是一个详细的指南,使用 Node.js 作为示例语言,展示如何配置服务器端来发送推送通知。
步骤 1:准备 APNs 证书
创建 APNs 证书:
登录 Apple Developer 账户。
前往 Certificates, Identifiers & Profiles。
选择 Keys,然后点击 + 按钮创建一个新的密钥。
选择 Apple Push Notifications service (APNs),然后点击 Continue。
输入密钥的描述,然后点击 Generate。
下载生成的 .p8 文件并保存。
获取 Key ID 和 Team ID:
Key ID:在密钥列表中,找到你刚刚创建的密钥,复制其 Key ID。
Team ID:在 Apple Developer 账户的概览页面中,找到你的 Team ID。
步骤 2:安装 Node.js 和依赖
安装 Node.js:
如果你还没有安装 Node.js,可以从 Node.js 官网 下载并安装。
创建项目目录:
Sh
浅色版本
mkdir apns-server
cd apns-server
初始化项目:
Sh
浅色版本
npm init -y
安装 apn 库:
Sh
浅色版本
npm install apn
步骤 3:编写服务器代码
创建 index.js 文件:
Sh
浅色版本
touch index.js
编写代码:
Javascript
浅色版本
const apn = require('apn');
// APNs 连接配置
const options = {
token: {
key: './path/to/your/AuthKey_YourKeyID.p8', // APNs auth key path
keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
},
production: false // Set to true if sending notifications to production devices
};
// 创建 APNs 提供者
const apnProvider = new apn.Provider(options);
// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app
// 设备令牌
const deviceToken = 'YOUR_DEVICE_TOKEN';
// 发送通知
apnProvider.send(note, deviceToken).then((result) => {
console.log("Notification sent:", result);
}).catch((error) => {
console.error("Error sending notification:", error);
});
步骤 4:运行服务器
确保 AuthKey_YourKeyID.p8 文件路径正确:
将 ./path/to/your/AuthKey_YourKeyID.p8 替换为实际的文件路径。
运行服务器:
Sh
浅色版本
node index.js
步骤 5:测试推送通知
确保设备已注册推送通知:
在你的 iOS 应用中,确保设备已注册并获取到设备令牌。
运行服务器:
运行 node index.js,你应该会看到类似以下的输出:
浅色版本
Notification sent: { sent: [ 'YOUR_DEVICE_TOKEN' ], failed: [] }
检查设备:
检查你的设备是否收到了推送通知。
常见问题
设备未收到通知:
确保设备已正确注册推送通知。
确保设备令牌正确无误。
确保 APNs 证书和配置正确。
确保设备连接到互联网。
错误信息:
查看 console.error 输出的错误信息,根据错误信息进行调试。
进一步扩展
批量发送通知:
可以将多个设备令牌放入数组中,一次性发送通知。
Javascript
浅色版本
const deviceTokens = ['TOKEN1', 'TOKEN2', 'TOKEN3'];
apnProvider.send(note, deviceTokens).then((result) => {
console.log("Notification sent:", result);
}).catch((error) => {
console.error("Error sending notification:", error);
});
自定义通知内容:
可以在 note 对象中添加更多自定义字段,如 payload、customData 等。
//
这个通知的作用是开发者向所有用户发通知吗,什么情况下需要用到远程通知
远程推送通知(Remote Push Notifications)的主要作用是让开发者能够从服务器向用户的设备发送消息,即使应用不在前台运行或甚至被关闭。这种机制使得开发者可以在特定情况下及时通知用户,提高应用的活跃度和用户体验。
远程推送通知的主要用途
即时消息:
例如,在即时通讯应用中,当用户收到新消息时,可以通过推送通知提醒用户。
新闻更新:
新闻应用可以推送最新的新闻标题和摘要,吸引用户查看详细内容。
促销活动:
电商应用可以推送限时折扣、新品上市等信息,促进用户购买。
账户通知:
例如,银行应用可以推送账户余额变动、交易确认等重要信息。
事件提醒:
日历应用可以推送即将到来的会议或日程安排。
游戏更新:
游戏应用可以推送新的关卡、活动或排行榜变化。
安全通知:
安全应用可以推送异常登录、账户风险等信息。
什么情况下需要用到远程通知
用户互动:
当需要与用户进行实时互动时,例如社交应用中的新消息提醒。
重要信息传递:
当有重要信息需要立即告知用户时,例如账户安全、紧急通知等。
增加用户粘性:
通过定期推送有价值的内容,增加用户打开应用的频率,提高用户粘性。
数据同步:
当应用需要在后台同步数据时,可以通过推送通知触发应用进行数据同步。
用户召回:
通过推送通知召回长时间未使用应用的用户,提高用户活跃度。
示例场景
即时通讯应用:
用户 A 向用户 B 发送了一条消息,服务器检测到新消息后,向用户 B 的设备发送推送通知,提醒用户 B 有新消息。
新闻应用:
服务器检测到最新新闻更新,向订阅该类别的用户发送推送通知,提醒用户查看最新新闻。
电商应用:
服务器检测到限时折扣活动开始,向符合条件的用户发送推送通知,提醒用户参与活动。
银行应用:
用户进行一笔大额转账,服务器检测到交易后,向用户发送推送通知,确认交易详情。
实现步骤总结
设备注册推送通知:
应用请求设备注册推送通知,并获取设备令牌。
应用将设备令牌发送到服务器。
服务器发送推送通知:
服务器使用设备令牌和 APNs 证书向 APNs 发送通知。
APNs 将通知推送到设备。
示例代码回顾
客户端(iOS 应用)
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 请求推送通知权限
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
print("通知权限已授予")
} else {
print("通知权限被拒绝")
}
}
// 注册推送通知
application.registerForRemoteNotifications()
return true
}
// 处理远程推送通知的注册
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
// 将设备令牌发送到你的服务器
sendDeviceTokenToServer(deviceToken: token)
}
// 处理远程推送通知的注册失败
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: \(error.localizedDescription)")
}
// 发送设备令牌到服务器
func sendDeviceTokenToServer(deviceToken: String) {
// 你的服务器端逻辑
print("Sending device token to server: \(deviceToken)")
// 例如,使用网络请求将设备令牌发送到服务器
// URLSession 或其他网络库
}
// 处理接收到的推送通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// 处理用户点击通知后的操作
print("Notification received: \(response.notification.request.content.body)")
completionHandler()
}
}
服务器端(Node.js)
const apn = require('apn');
// APNs 连接配置
const options = {
token: {
key: './path/to/your/AuthKey_YourKeyID.p8', // APNs auth key path
keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
},
production: false // Set to true if sending notifications to production devices
};
// 创建 APNs 提供者
const apnProvider = new apn.Provider(options);
// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app
// 设备令牌
const deviceToken = 'YOUR_DEVICE_TOKEN';
// 发送通知
apnProvider.send(note, deviceToken).then((result) => {
console.log("Notification sent:", result);
}).catch((error) => {
console.error("Error sending notification:", error);
});
总结
远程推送通知是一种强大的工具,可以帮助开发者与用户保持实时互动,提高应用的活跃度和用户体验。通过上述步骤,你可以实现从服务器向用户设备发送推送通知的功能。