【问题标题】:Detect from which UILocalNotification an application was opened检测从哪个 UILocalNotification 打开应用程序
【发布时间】:2015-12-04 23:30:38
【问题描述】:

在某些情况下,我的 iOS 应用程序必须同时触发多个UILocalNotification。我想决定用户点击了哪个UILocalNotification。当用户单击UILocalNotification 时,应用程序处于非活动状态或在后台。问题是方法

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {

每个触发的UILocalNotification 调用。因此,当应用程序处于活动状态时,此方法会被多次调用,因为我收到了多个 UILocalNotification。有没有办法确定哪个UILocalNotification 是应用程序打开的原因?由于在应用程序处于非活动状态或在后台时已收到所有 UILocalNotification,因此无法检查 applicationState。

非常感谢!

编辑: 举个远的例子:当您收到来自两个不同组 A 和 B 的 WhatsApp 消息并选择来自组 A 的推送通知时,该消息将在应用程序自行打开后立即显示。 WhatsApp 和我的用例之间的区别在于我有本地通知。

【问题讨论】:

  • 根据我的经验(我刚刚编写了一个小测试应用程序,它在应用程序关闭时安排三个具有相同 fireDate 的 UILocalNotifications 来测试这一点),当用户在通知屏幕中点击给定警报时,从而启动应用程序,传递给 UIApplication 的 didReceiveNotifications 方法的唯一 UILocalNotification 是用户点击的那个。所以我不太明白你的问题。
  • 它没有回答您的问题,但是只有一个本地通知(即取消以前的通知)怎么样。如果这样做,您可以跟踪通知的 userInfo 字典以供以后在应用程序激活时使用。如果您仍然需要多个本地通知,是否可以选择以某种方式将其组合成一个通知?如果是,您可以准备一种 userInfo 字典数组,以便在应用激活时使用。
  • 你不能使用 userinfo 字典来确定打开了哪个通知并在 didRecieveLocalNotif 中检查,

标签: ios swift notifications uilocalnotification


【解决方案1】:

在发送通知时,您可以为通知用户信息设置一些唯一的 id。

UILocalNotification *notif = [[UILocalNotification alloc] init];
    notif.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
    notif.timeZone = [NSTimeZone defaultTimeZone];

// set the your data with unique id
    NSMutableDictionary *dict=[NSMutableDictionary new];
    [dict setObject:Id forKey:@"id"];

// assignt the dictionary to user info
    notif.userInfo=dict;


    notif.alertBody = @"test Notification";
    notif.soundName = UILocalNotificationDefaultSoundName;


    [[UIApplication sharedApplication] scheduleLocalNotification:notif];

你可以像这样从 didReceiveLocalNotification 获取用户信息

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    if ([[notification.userInfo valueForKey:@"id"] isEqualToString:@"1"])
    {
        NSLog(@"notification id %@",[notification.userInfo valueForKey:@"id"]);
    }
    else if ([[notification.userInfo valueForKey:@"id"] isEqualToString:@"2"])
    {
        NSLog(@"notification id %@",[notification.userInfo valueForKey:@"id"]);
    }

    ////// or /////

    if ([notification.userInfo valueForKey:@"id"] )
    {
        NSLog(@"id of notification %@",[notification.userInfo valueForKey:@"id"]);
    }

}

来自 didFinishLaunchingWithOptions

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey])
    {
       UILocalNotification *notif=[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
        NSLog(@"notif.userInfo  %@",notif.userInfo);

//        notif.userInfo  {
//            id = 2;
//        }

    } 


        return YES;
}

【讨论】:

    【解决方案2】:

    您可以使用launch options 访问与通知一起传递的字典,并从那里访问,具体取决于您在设置本地通知时提供的数据,您可以检查字典并查看该方法正在响应哪个通知。

    【讨论】:

    • 您好 pbush25,感谢您的回复。不幸的是,这并不能帮助我找出用户点击了哪个 UILocalNotification,因为 application:didReceiveLocalNotification 会为用户同时收到的每个 UILocalNotification 调用。
    • 此外,启动选项仅在应用程序第一次启动时发送,而不是从后台激活时发送。
    【解决方案3】:

    在安排通知时,在UILocalNotification userInfo 属性中以NSDictionary 的形式提供一些独特的信息,例如id 或其他信息。当在didFinishLaunchingWithOptionsdidReceiveLocalNotification 收到它时,从通知实例中取出user info 字典并相应地做你的工作。

    【讨论】:

      【解决方案4】:

      由于您使用的是 swift,我了解到您的应用程序可能正在运行 iOS 8 及更高版本。

      如果你使用iOS8,你可以为你的通知提供动作(点击通知本身就是一个动作)。

      因此,您将通过UIApplicationDelegate:触发此方法:

      application(_:handleActionWithIdentifier:forLocalNotification:completionHandler:)

      application(_:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:)

      这两种方法都会为您提供UILocalNotificationcontains a userInfo property,您可以在创建通知时填写它,然后输入某种标识符让您知道哪个是哪个。

      【讨论】:

        【解决方案5】:

        只是对@pbush25的一点补充,您可以像这样将字典对象分配给属性notification.userInfo = [:],然后您也可以通过这种方式获取它并随意使用!

        【讨论】:

          【解决方案6】:

          在 Swift 3.x 中,在 AppDelegate 的 didFinishLaunchingWithOptions 方法中使用以下代码。

          func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
                  // See if the application was launched from a local notification.
                  if let options = launchOptions {
                      if let notification = options[UIApplicationLaunchOptionsKey.localNotification] as? UILocalNotification {
                          print(notification.userInfo ?? "No info attached.")
                      }
                  }
                  return true
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多