检测从哪个 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 或其他信息。当在didFinishLaunchingWithOptions
或didReceiveLocalNotification
收到它时,从通知实例中取出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 在后台 10 分钟后不会触发
iOS10 (Swift 3.0) 中弃用 UILocalNotification 接收功能