如何使用附加数据将 apns 令牌发送到服务器
How to send apns token to server with additional data
我正在尝试在调用 didRegisterForRemoteNotificationsWithDeviceToken 时向我的服务器发送一个 apns 令牌。我可以成功地将令牌打印到控制台,所以我知道这部分工作正常。
我还在我的网络服务上实现了这样一个端点,它也可以很好地与我的应用程序的其余部分一起工作。
在 Apple Developer documentation 中,在名为 Forward Tokens to Your Provider Server 的最后一节中说
Upon receiving a device token, open a network connection from your app to your provider server. Securely forward the device token and any other information you need to identify the specific user to your server. For example, you might include the user's login name or something that connects them to your service.
实际上,我该如何包含这样的信息?我似乎无法将其他参数传递给 didRegisterForRemoteNotificationsWithDeviceToken,例如用户的访问令牌、用户 ID 等。
因为我使用的是 SwiftUI,所有用户的信息,包括他们的访问令牌,都在我的视图结构中的 @EnvironmentObject
中。我需要切换到单例还是什么?
您可以在对服务器的请求中将包含所有用户元数据(包括令牌)的结构编码为 JSON JSONEncoder and send 它。
事实证明,单例可能是更好的实现方式。一旦进入 didRegisterForRemoteNotificationsWithDeviceToken,就无法从视图访问任何内容,因此 @EnvironmentObject
无用。
直到我可以将登录的用户数据完全重组为单例(涉及撕裂 out/changing 一堆代码),我只是有一个 ApiAccessToken
在请求许可之前设置的单例(用户此时已登录)然后访问 didRegisterForRemoteNotificationsWithDeviceToken 中的单例。
ApiTokenSingleton.swift
import Foundation
class ApiTokenSingleton
{
static let shared = ApiTokenSingleton()
private var token = ""
func getToken() -> String {
return token
}
func setToken(newToken: String) {
token = newToken
}
}
MyView.swift,onAppear,当我请求访问时。 authenticatedUser 是 EnvironmentObject
.onAppear() {
ApiTokenSingleton.shared.setToken(newToken: authenticatedUser.accessToken ?? "")
appDelegate.registerForPushNotifications()
}
AppDelegate.swift
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)")
// send token to backend here
let deviceService = DeviceService()
deviceService.add(accessToken: ApiTokenSingleton.shared.getToken(), deviceToken: token) { createDeviceResponse in
print(createDeviceResponse)
}
}
您可以先将 apnToken 保存在某个地方 - 它可以是应用程序首选项数据库或应用程序首选项状态(在应用程序启动时初始化),您可以从 API 层访问这些位置。
示例:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let encryptedToken = [UInt8](deviceToken).map{String(format: "%02x", [=10=])}.joined()
// persist encrypted token to application settings DB
}
从我的 API 层中的数据库中获取 apnToken 并将其与其他数据一起发送到 API
private static func subscribeToNotification() {
guard let apnToken = // get apnToken from app preferences DB
// ... code for getting other params for API request from different other places
let result = apiFetcher.request(
type: ApiRequestType.post,
path: // url,
headers: // headers,
queryParams: [
"Token": apnToken,
"Param1": param1,
"Param2": param2
],
withAuth: true
)
}
我正在尝试在调用 didRegisterForRemoteNotificationsWithDeviceToken 时向我的服务器发送一个 apns 令牌。我可以成功地将令牌打印到控制台,所以我知道这部分工作正常。
我还在我的网络服务上实现了这样一个端点,它也可以很好地与我的应用程序的其余部分一起工作。
在 Apple Developer documentation 中,在名为 Forward Tokens to Your Provider Server 的最后一节中说
Upon receiving a device token, open a network connection from your app to your provider server. Securely forward the device token and any other information you need to identify the specific user to your server. For example, you might include the user's login name or something that connects them to your service.
实际上,我该如何包含这样的信息?我似乎无法将其他参数传递给 didRegisterForRemoteNotificationsWithDeviceToken,例如用户的访问令牌、用户 ID 等。
因为我使用的是 SwiftUI,所有用户的信息,包括他们的访问令牌,都在我的视图结构中的 @EnvironmentObject
中。我需要切换到单例还是什么?
您可以在对服务器的请求中将包含所有用户元数据(包括令牌)的结构编码为 JSON JSONEncoder and send 它。
事实证明,单例可能是更好的实现方式。一旦进入 didRegisterForRemoteNotificationsWithDeviceToken,就无法从视图访问任何内容,因此 @EnvironmentObject
无用。
直到我可以将登录的用户数据完全重组为单例(涉及撕裂 out/changing 一堆代码),我只是有一个 ApiAccessToken
在请求许可之前设置的单例(用户此时已登录)然后访问 didRegisterForRemoteNotificationsWithDeviceToken 中的单例。
ApiTokenSingleton.swift
import Foundation
class ApiTokenSingleton
{
static let shared = ApiTokenSingleton()
private var token = ""
func getToken() -> String {
return token
}
func setToken(newToken: String) {
token = newToken
}
}
MyView.swift,onAppear,当我请求访问时。 authenticatedUser 是 EnvironmentObject
.onAppear() {
ApiTokenSingleton.shared.setToken(newToken: authenticatedUser.accessToken ?? "")
appDelegate.registerForPushNotifications()
}
AppDelegate.swift
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)")
// send token to backend here
let deviceService = DeviceService()
deviceService.add(accessToken: ApiTokenSingleton.shared.getToken(), deviceToken: token) { createDeviceResponse in
print(createDeviceResponse)
}
}
您可以先将 apnToken 保存在某个地方 - 它可以是应用程序首选项数据库或应用程序首选项状态(在应用程序启动时初始化),您可以从 API 层访问这些位置。
示例:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let encryptedToken = [UInt8](deviceToken).map{String(format: "%02x", [=10=])}.joined()
// persist encrypted token to application settings DB
}
从我的 API 层中的数据库中获取 apnToken 并将其与其他数据一起发送到 API
private static func subscribeToNotification() {
guard let apnToken = // get apnToken from app preferences DB
// ... code for getting other params for API request from different other places
let result = apiFetcher.request(
type: ApiRequestType.post,
path: // url,
headers: // headers,
queryParams: [
"Token": apnToken,
"Param1": param1,
"Param2": param2
],
withAuth: true
)
}