I have a problem handling more than one Push Notifications. When I unlock the iphone and there is (for example) 10 push notifications of my app, my app just register some:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
if (launchOptions != nil)
{
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(#"Launched from push notification: %#", dictionary);
[self addMessageFromRemoteNotification:dictionary updateUI:YES];
}
}
}
If my app is open there is no problem and all received notifications are added to array.
Thank you
Related
For system upper than iOS 10 version, within UNUserNotificationCenterDelegate, there are two methods to clarify whether the APNS message method was called from user clicked or system received the message:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
While for system under iOS 10 version, there was an issue for the application delegate method - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo, there are 3 ways to call this method:
1:Click a notification message when App was running in background, will call this method.
2:Click App icon wether App was running in background or was killed, before App really launched(about 1~3 seconds), during these seconds if received an APNS message, this method will be called too.
3: App was running, pull down the notification bar to make application become inactive, at this state if received an APNS message, this method will be called too.
Now here is the question, how to judge these 3 kind of clicks? Generally if user did't click message to enter app(2 and 3's click), app shouldn't execute this message(like open a new page base on the message info). But how to know it is from 2 and 3?
From below answers, found that kind-2 has been resolved with the applicationState, while kind-3 still has left no answer, anyone knows how to fix it?
Check the app state in the application didReceiveRemoteNotification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//app was on background
}
}
You can check that using UIApplication state as the following:
///- if app is running in foreground
if (application.applicationState == UIApplicationStateActive) {
[self pushNotificationReceivedWhileActiveWithInfo:userInfo];
///- if app was running in background
} else if (application.applicationState == UIApplicationStateBackground) {
if (self.pushReceivedWhileClosed != YES) {
[self pushNotificationReceivedWhileInBackgroundWithInfo:userInfo];
}
}
Also you’ll need to handle the notification when the app was fully closed by getting it from didFinishLaunchingWithOptions when opened from a notification by saving the notification data and execute it when the user reaches the home screen let’s say:
///- when receiving push notification while [app closed]
if (launchOptions != nil) {
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil) {
NSLog(#"[AppDelegate]##########################AppDelegate######################### Received notification while app CLOSED");
///- save the dictionary data and execute it when the app loads for example.
self.pushReceivedWhileClosed = YES;
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSMutableDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil)
{
comingFromNotification = YES;
}else{
comingFromNotification = NO;
}
}
My problem seems to be duplicate of this one,but it's not. While application is killed and not running in the background, if I receive push notification and clicked the notification banner, it works fine. "userInfo" isn't empty and application handles the notification. BUT if i dismiss the notification banner and open the app via clicking the application icon, this "userInfo" returns nil.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
NSDictionary* userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo != nil){
//Handling notification
}
}
and also
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if([application applicationState] == UIApplicationStateActive) {
NSLog(#"...1");
}else if([application applicationState] == UIApplicationStateInactive){
NSLog(#"...2");
}else if([application applicationState] == UIApplicationStateBackground){
NSLog(#"...2");
}
completionHandler(UIBackgroundFetchResultNoData);
}
Is there any way to handle these notifications or should I handle them by my own ?
No your app is only informed about the notification that is used to open/launch your app.
There is no way to detect of there are any notification in the notification center for your app. You need to build this yourself in your apps server.
I have an app where I have push notification.
What I have is I go to respective category when push is clicked (from the push notification list).
All is working perfectly, except when the app is killed.
If the app is minimized and push comes, if I click on push, it goes to respective category.
However if I forcefully kill the app and push comes and click on the push, it just open the app and no transition occurs.
Is this natural behavior in iPhone or I am doing something wrong?
In didReceiveRemoteNotification I go to specific category based on the data I received.
didReceiveRemoteNotification not call app will not run, that time push notification open app newly in device, you manually check if any notifications are bending in application:didFinishLaunchingWithOptions: try this for check bending notifications in app.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...............
...............
UILocalNotification *localNotif =[launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (localNotif) {
NSLog(#"load notifiation *******");
isLoadNotification=YES;
}
return YES;
}
Below is what I used.
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
if (launchOptions != nil) {
NSMutableDictionary *dic = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey"];
NSMutableDictionary *dicItem = [dic objectForKey:#"aps"];
NSString *itemNotification = [dicItem objectForKey:#"alert"];
// do all transition here....
}else if (launchOptions == nil){
NSLog(#"launch ,,, nil");
}
...//code something
}
I check for new message in AppDelegate class in 3 places, in didFinishLaunchingWithOptions:(NSDictionary *)launchOptions using code:
if (launchOptions != nil)
{
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
//NSLog(#"Launched from push notification: %#", dictionary);
//notification pending ... so pull from server the new message
[self addMessageFromRemoteNotification:dictionary updateUI:YES];
}
}
and in didReceiveRemoteNotification:(NSDictionary*)userInfo using code:
// notification pending ... so pull from server the new message
[self addMessageFromRemoteNotification:userInfo updateUI:YES];
and in - (void)applicationDidBecomeActive:(UIApplication *)application using code
if(application.applicationIconBadgeNumber>0)
{
application.applicationIconBadgeNumber = 0;
// notification pending ... so pull from server the new message
[self openMessageViewForNewMessage];
}
However, still I notice there is some cases where my app still dont "catch" notification, meaning, it still not aware that it receive notification. Did I message something? or I should all the time check "my server" for new messages becouse app might not all the times be informed by iOS that there is new notification.
Quick overview...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Here you specify what kind of notifications you want your app to receive. For Example, if you want badge, sound and alert you would include this:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
In the:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
You can add something like this to make sure to update your badge:
NSString *badge = [apsInfo objectForKey:#"badge"];
application.applicationIconBadgeNumber = [badge intValue];
I personally also add this code and do my processing where appropriate:
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReceivedNotificationAlert" object:self];
The above works well for all my apps. You mentioned there are some cases when your app misses APNs. Can you share exactly what kind of cases?
I've created an iphone app with push notification feature. The server works well and I could receive the notification when app is running in foreground. The function
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
is called then notification arrives.
However, when I press the home key, brought the app into background or kill it in the task bar. I cannot receive any notification, neither in the notification area or any popup.
Anyone knows the reason? Thanks
You can use...
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
if (launchOptions != nil) {
NSMutableDictionary *dic = [launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSMutableDictionary *dicItem = [dic objectForKey:#"aps"];
NSString *itemNotification = [dicItem objectForKey:#"alert"];
}else if (launchOptions == nil){
NSLog(#"launch ,,, nil");
}
...//code something
}
itemNotification is an item in Notification barge. Have fun!!