为同一 phone 上的多个用户管理 APN 通知

Managing APN notification for multiple users on the same phone

我想知道当许多用户在同一台​​设备上使用同一应用程序时如何管理 Apple 推送通知,因为每台设备的设备令牌都是唯一的。

如果我的应用程序在同一台设备上有 2 个注册用户,如果通知是针对用户 A 但用户 B 当前已登录应用程序,如何防止推送通知出现?

如果应用程序在前台,则可以通过用户 ID 轻松管理,如果 APN 不适用于该用户,则可以防止代码执行。

但是应用在后台怎么处理呢? 设备将收到 APN,发出警报,并显示通知,无论用户当前登录到应用程序...

根据您关于在应用程序位于前台时能够处理这种情况的评论,我假设通知包含一些信息来标识通知所针对的用户。似乎如果您在 NSUserDefaults 中存储一些标识当前登录用户的信息,您应该能够在 didReceiveRemoteNotification 中检索该信息,并根据该信息决定是否应处理通知。

更新添加更多信息:

您还需要实施 application:didReceiveRemoteNotification:fetchCompletionHandler 并将您的通知变成 "silent" 通知,然后在您从要抑制的通知中过滤出要显示的通知后,您将为要显示的通知创建本地通知。您还需要在 info.plist 中添加一个 UIBackgroundModes,并在您的有效负载中包含一个 "content-available",键。有关详细信息,请参阅 here

<key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>remote-notification</string>
    </array>

实现带有 fetchCompletionHandler 的版本是关键,因为当应用程序处于后台时不会调用没有它的版本。

这是我的一个应用程序的示例,它接收 "silent" 位置更新请求通知,并且还接收一些 "non-silent" 通知。如果应用程序处于活动状态,我会显示 "toast",如果应用程序在后台,我会根据远程通知创建本地通知,然后触发它。

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void ) {
    log?.info("******* got a remote message = \(userInfo)  *******")
    let message: String = (userInfo["message"] ?? "stop") as! String
    log?.info("message = \(message)")
    switch message {
    case "update_locations":
      log?.info("starting location update cycle")
      locationUploader?.startUploading(handler)
    case "micropost_created":
      log?.info("got a new micropost notification")
      let notification = UILocalNotification()
      let userName = userInfo["user_name"] as? String ?? ""
      let content = userInfo["content"] as? String ?? ""
      notification.alertTitle = "Micropost from \(userName)"
      let alertBody = "\(userName) said: \(content)"
      notification.alertBody = alertBody
      notification.soundName = UILocalNotificationDefaultSoundName
      application.presentLocalNotificationNow(notification)
      if let topMostView = application.keyWindow {
        topMostView.makeToast(message: alertBody)
      }
      handler(.NewData)
    default:
      handler(.NoData)
    }
  }

为了解决上述问题,我有两个选择 1.注销时,从服务器数据库中删除登录用户的令牌,每次新用户登录到应用程序请求新令牌并发送到服务器时。 2. 注销应用程序可以从通知中心注销自身,登录应用程序必须自行注册以获取通知并在服务器上更新令牌。

这是注册和注销通知的代码。 注销时:[[UIApplication sharedApplication] unregisterForRemoteNotifications];

登录时:

[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];