检测从哪个 UILocalNotification 打开应用程序

Posted

技术标签:

【中文标题】检测从哪个 UILocalNotification 打开应用程序【英文标题】:Detect from which UILocalNotification an application was opened 【发布时间】: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 中检查, 【参考方案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:)

这两种方法都会为您提供UILocalNotification 和contains 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

【讨论】:

以上是关于检测从哪个 UILocalNotification 打开应用程序的主要内容,如果未能解决你的问题,请参考以下文章

检测下一个将触发的 UILocalNotification

UILocalNotification 在后台 10 分钟后不会触发

iOS10 (Swift 3.0) 中弃用 UILocalNotification 接收功能

以编程方式从通知托盘中删除 UILocalNotification

UILocalNotification 从应用文档播放声音

iOS8 - UILocalNotification,稍后从代码中检查权限