【问题标题】:How to send apns token to server with additional data如何使用附加数据将 apns 令牌发送到服务器
【发布时间】:2021-01-23 14:34:24
【问题描述】:

我正在尝试在调用 didRegisterForRemoteNotificationsWithDeviceToken 时向我的服务器发送一个 apns 令牌。我可以成功地将令牌打印到控制台,所以我知道该部分正在工作。

我还在我的网络服务上实现了这样一个端点,它也可以与我的应用程序的其余部分一起正常工作。

Apple Developer documentation 中,在名为 Forward Tokens to Your Provider Server 的最后一节下,它说

收到设备令牌后,打开从您的应用到您的提供商服务器的网络连接。将设备令牌和识别特定用户所需的任何其他信息安全地转发到您的服务器。例如,您可以包含用户的登录名或将他们连接到您的服务的其他内容。

实际上,我如何包含这样的信息?我似乎无法将其他参数传递给 didRegisterForRemoteNotificationsWithDeviceToken,例如用户的访问令牌、用户 ID 等。

由于我使用的是 SwiftUI,所有用户的信息,包括他们的访问令牌,都在我的视图结构中的 @EnvironmentObject 中。我需要切换到单例吗?

【问题讨论】:

    标签: ios swift apple-push-notifications


    【解决方案1】:

    您可以将包含所有用户元数据(包括令牌)的结构编码为 JSON JSONEncodersend it 以向服务器发出请求。

    【讨论】:

      【解决方案2】:

      事实证明,单例可能是更好的实现。一旦你进入了 didRegisterForRemoteNotificationsWithDeviceToken,你就不能从视图中访问任何东西,所以@EnvironmentObject 是没用的。

      在我可以将登录的用户数据完全重组为单例之前(涉及删除/更改一堆代码),我只需在请求权限之前设置一个 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)
              }
              
          }
      

      【讨论】:

        【解决方案3】:

        您可以先将 apnToken 保存在某个地方 - 它可以是应用程序首选项数据库,或应用程序首选项状态(在应用程序启动时初始化),您可以从 API 层访问。

        例子:

        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            let encryptedToken = [UInt8](deviceToken).map{String(format: "%02x", $0)}.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
            )
        } 
        

        【讨论】:

          猜你喜欢
          • 2020-12-14
          • 1970-01-01
          • 1970-01-01
          • 2016-09-06
          • 2017-11-08
          • 2011-11-20
          • 2022-01-21
          • 2021-08-01
          • 1970-01-01
          相关资源
          最近更新 更多