根据Apple指南:
“作为呈现通知的结果,用户点击警报的操作按钮或点击(或点击)应用程序图标。 如果点击操作按钮(在运行iOS的设备上),系统将启动应用程序,应用程序将调用其委托的应用程序:didFinishLaunchingWithOptions:method(如果已实现);它传入通知有效负载(用于远程通知)或本地通知对象(用于本地通知)。
如果在运行iOS的设备上轻触应用程序图标,则应用程序会调用相同的方法,但不会提供有关通知的信息。如果在运行Mac OS X的计算机上单击应用程序图标,则应用程序将调用委托的applicationDidFinishLaunching:方法,其中委托可以获取远程通知有效负载。“
我的问题是 假设用户从提供商处获得3-4个推送通知,并且所有通知都存储在苹果的通知中心。如果用户点击了通知提醒,他/她可以轻松地在应用中获取通知数据。但是,如果用户点击iPhone上的应用程序图标,如何获取所有先前通知的所有数据。
提前致谢!
答案 0 :(得分:39)
您无法接收有关用于打开应用的通知的信息。
因此,如果用户打开您的应用,并且您的应用有通知,那么您将无法在应用中检索它们。
解决方法可能是跟踪服务器上的通知并在应用程序中处理此问题。因此,服务器跟踪已读取的通知。 Facebook就是这样做的。
答案 1 :(得分:15)
要以正确的方式做到这一点,必须满足一些条件:
您的服务器知道您的应用当前所看到的内容以及可以再次发送的通知。
我们只考虑远程通知。 app有三种状态:
FOREGROUND :
通知会在没有用户操作的情况下显示:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
//handle your notification
}
您可以使用第三方库显示横幅:BSForegroundNotification
背景
通知出现在屏幕上。 (请注意,在推送通知中设置content-available = 1可能会导致在按下应用程序图标后可以看到最新的推送消息,因为didReceive ... 被调用)。
//nothing is called in the app, but app icon badge changes
// OR - if the notification contains the field content-available set to 1 -
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
//handle your notification
}
用户点按通知
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
//handle your notification
}
用户采取通知操作
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
//handle your notification's action
}
或
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
//handle your notification's action response info
}
用户点按应用图标
func applicationDidBecomeActive(application: UIApplication) {
//fetch pending notifications from server
}
全部不运行
通知出现在屏幕上。
//nothing is called in the app, but app icon badge changes
用户点按通知
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let userInfo = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject: AnyObject] {
//handle your notification
}
}
用户采取通知操作
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
//handle your notification's action
}
或
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
//handle your notification's action response info
}
用户点按应用图标
func applicationDidBecomeActive(application: UIApplication) {
//fetch pending notifications from server
}
如何处理通知?
let notification = WLNotification(userInfo: userInfo)
在
WLNotification
内,请记住在收到通知时保持当前的申请状态。将来您可能需要知道该通知的来源。
WLNetworkClient.sharedClient().notificationForIdentifier(notification.identifier)
从服务器获取有关该通知的详细信息,同时让它知道您真正收到该通知,并对用户的数据产生影响。
如何获取所有待处理的通知?
WLNetworkClient.sharedClient().pendingNotificationsWithCompletionBlock(nil)
获取您错过的所有通知。换句话说,获取那些未在您收到的服务器中标记的那些。
阅读Limitations of Apple Push Notifications。
查看相关问题:
答案 2 :(得分:3)
我遇到了同样的问题:如果用户点击推送横幅,他会获得推送应用的信息,如果他点击应用图标,他就不会得到它。你可以从中处理派生的,但只有一些限制。例如,如果您想要推送徽章编号,则可以执行以下操作: (推送 - >应用图标 - >应用图标徽章 - >您的var)
AppDelegate中的
- (void)applicationWillEnterForeground:(UIApplication *)application
{
newMessages = application.applicationIconBadgeNumber;
}
答案 3 :(得分:1)
从应用程序加载点击提示推送通知的警报视图时,概念上,如果您的应用程序在后台,则使用didReceiveLocalNotification
委托方法启动应用程序。此时不调用applicationDidFinishLaunching
委托方法。
如果您的应用程序不在后台,点击提示推送通知的提醒视图将调用applicationDidFinishLaunching
方法。
希望这清除了您对这两种委托方法之间的理解。
答案 4 :(得分:-2)
您可以使用此代码:
NSArray *pendingNotifications = [[[UIApplication sharedApplication] scheduledLocalNotifications] sortedArrayUsingComparator:^(id obj1, id obj2) {
if ([obj1 isKindOfClass:[UILocalNotification class]] && [obj2 isKindOfClass:[UILocalNotification class]])
{
UILocalNotification *notif1 = (UILocalNotification *)obj1;
UILocalNotification *notif2 = (UILocalNotification *)obj2;
return [notif1.fireDate compare:notif2.fireDate];
}
return NSOrderedSame;
}];
// if there are any pending notifications -> adjust their badge number
if (pendingNotifications.count != 0)
{
//do something
}