【问题标题】:Handling Push Notifications when App is Terminated应用程序终止时处理推送通知
【发布时间】:2016-05-05 16:10:45
【问题描述】:

当我的应用程序未运行并收到推送通知时,如果我单击该通知,则会启动应用程序 - 但它不会使用我设置的警报视图提示用户,询问他们是否想要查看通知的内容与否。它刚刚启动,然后就坐在那里。

当应用程序运行时推送通知可以完美运行 - 无论是作为活动应用程序还是在后台运行 - 但在应用程序未运行时没有任何工作正常。

我尝试在应用程序中注销 launchOptions NSDictionary: didFinishLaunchingWithOptions: 以查看它带来的负载 - 但它显示为“(null)”。所以它基本上什么都不包含 - 这没有意义,因为它不应该包含通知的负载吗?

有人知道如何在应用未运行时让推送通知工作吗?

我的意思是当应用程序处于非运行状态时如何处理推送通知。如果您收到许多通知并且您没有打开应用程序,也没有点击系统的通知面板怎么办。您如何保留这些推送以供以后检索。

【问题讨论】:

标签: ios objective-c iphone push-notification


【解决方案1】:

1) 应用程序在后台运行时应用程序在前台运行时 application:didReceiveRemoteNotification: 方法将调用如下。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if (application.applicationState == UIApplicationStateInactive)
    {
        // opened from a push notification when the app was on background
        NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
    }
    else if(application.applicationState == UIApplicationStateActive)
    {
        // a push notification when the app is running. So that you can display an alert and push in any view
        NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
    }
}

2) 当应用程序没有启动(关闭)时会调用application:didFinishedLaunchingWithOptions方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (launchOptions != nil)
    {
        // opened from a push notification when the app is closed
        NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (userInfo != nil)
        {
             NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
        }
    }
    else
    {
        // opened app without a push notification.
    }
}

3) 目前无法删除特定通知。从您的应用中删除所有通知以便当用户从其中一个应用打开应用时它们不会显示在通知中心的方法是将应用徽章设置为 0。

【讨论】:

  • 只是添加...当应用程序在后台然后“- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult 结果) )handler" 将被调用。
  • "从您的应用程序中删除所有通知以便当用户从其中一个应用程序打开应用程序时它们不会显示在通知中心的方法是将应用程序徽章设置为 0"是这对我来说很重要,因为我正在跟踪一个错误,当触摸其中一个通知时所有通知都被删除,这有助于我追踪它。谢谢。
  • 它在 iOS 10 中不起作用。我们必须实现 "-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler " UserNotifications 框架的方法。
  • 如果您的应用程序在前台,那么它将被自动调用,否则,当用户与通知交互时将调用相应的方法。如果你想自动调用它,那么你应该使用“-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler”方法运行一小段代码推送通知到达时的背景.. 您可能需要为相同设置背景模式
  • 我在stackoverflow.com/questions/37658647/testing-a-closed-ios-app 找到了一些对我有用的东西
【解决方案2】:

根据您的问题,当您打开应用程序时,无法保留所有通知,最好调用 api 从后端/服务器获取所有通知,这就是 Facebook 的做法。

【讨论】:

    【解决方案3】:

    您可以使用getDeliveredNotifications(completionHandler:) 方法检索传递到您的应用程序的通知。请注意,这只会返回当前显示在通知中心的通知,而不是用户手动清除的通知。

    UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
    
        // notifications: An array of UNNotification objects representing the local
        // and remote notifications of your app that have been delivered and are still
        // visible in Notification Center. If none of your app’s notifications are
        // visible in Notification Center, the array is empty.
    
        // As said in the documentation, this closure may be executed in a background
        // thread, so if you want to update your UI you'll need to do the following:
        DispatchQueue.main.sync { /* or .async {} */ 
            // update UI
        }
    }
    

    【讨论】:

    • UNUserNotificationCenter 仅适用于 iOS 10 及更高版本
    【解决方案4】:

    应用程序不会在后台处理推送通知,操作系统真正做的是在您按下通知后唤醒应用程序。您可以通过以下方式捕捉这一刻:

        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
        { 
    
            if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]) {
          // Your app has been awoken by a notification...
            }
       }
    

    【讨论】:

      【解决方案5】:

      在应用程序端无法处理此问题。 您需要在服务器上维护未读徽章计数。 当应用程序被终止时,徽章值会从服务器更新。

      因此,当您随时打开应用程序时,您需要调用 Web 服务来获取所需的通知并更新标签栏的标记(如果使用)。

      【讨论】:

        【解决方案6】:

        在终止状态下收到通知后执行操作 - iOS 13 - 场景委托

        最近我遇到了一个问题,当我的应用程序处于终止状态时,我收到了远程推送通知。在最新的 iOS 版本中,Scene delegate 负责处理视图生命周期方法,而不是 App Delegate。

        较旧的 iOS 版本 - 由 App Delegate 处理 当应用程序终止并收到远程推送通知时,有效负载将反映在应用程序委托的 didfinishLaunchingWithOptions 方法中。使用此方法的启动参数,可以获取有效负载数据并执行任何交互。

        新的 iOS 版本 - 由场景委托处理 同样,当应用程序终止并收到远程推送通知时,有效负载会反映在场景委托的场景(willConnectTo 会话)中。使用该方法的connectingOption参数,可以获取payload数据并进行任何交互。

        提示:一旦视图控制器设置为根视图控制器,要执行任何交互或将此有效负载传递给另一个视图控制器,请保持几秒钟的延迟以传递数据。

        示例代码:

        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(frame: windowScene.coordinateSpace.bounds)
        window?.windowScene = windowScene
         
        if defaults.string(forKey: UserDefaultsKeys.TenantID.rawValue) != nil && connectionOptions.notificationResponse != nil {
           
          let rootViewController = UINavigationController(rootViewController: DashboardVC())
          window?.rootViewController = rootViewController
          window?.makeKeyAndVisible()
           
          DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            NotificationCenter.default.post(
              name: .passApnsDataToDashboardNotification,
              object: nil,
              userInfo: connectionOptions.notificationResponse?.notification.request.content.userInfo)
          }
           
        }
        

        【讨论】:

          【解决方案7】:

          您可以在启动之前终止的应用程序后通过这样的通知显示警报:

          DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { // display the alert }

          【讨论】:

          • 这是怎么回事?
          猜你喜欢
          • 2016-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-06
          • 2020-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多