I receive a push notification when the my app is closed or canceled. Is there a way to set an nsuserdefault when this happens? I know if a user taps the notification or opens the app from the notification you can check if the app was inactive or canceled but what if they don't open the app from the notification but rather just launch the app by clicking on the icon?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
I know this method is called but it seems like I can not save to nsuserdefaults if the app is terminated or canceled.
If the app is closed or inactive and user opens the app through the icon ,
you will get the remote notification in "didFinishLaunchingWithOptions" method if any notification is available , there you can set you userdefault if you want .
Here is the code to get the remote notification in "didFinishLaunchingWithOptions"
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions) { //launchOptions is not nil
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo) { //apsInfo is not nil
[self performSelector:#selector(postNotificationToPresentPushMessagesVC)
withObject:nil
afterDelay:1];
}
}
return YES;
}
For more help please visit this link #staticVoidMan have answered it very well .
Hope this Helps!
Related
I am having an iOS application where I am receiving Push Notifications. I have the following code in AppDelegate
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if ( application.applicationState == UIApplicationStateActive )
{
// app was already in the foreground
}
else
{
NSLog(#"Received push notification");
}
}
I am running the app in Xcode with my iPhone. When the app is in background I am able see the NSLog when the notification comes.
When I close the app i.e removing it from opened apps in iOS the debugger session in Xcode stops and I can't see the NSlog after that even after receiving notification on my iPhone for the app when the app is closed (Push Notifications can come to app even if it is closed)
How can I print logs when the app is being opened from closed state?
It sounds like you're describing a few different things here.
First, you won't be able to see any NSLog notification messages if/after the app is fully terminated, until the app is launched by some mechanism.
If you want to print logs when the app is being opened from a terminated state, you can do something like the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ...
NSLog(#"%s", __PRETTY_FUNCTION__); // print the function name
// Process remote notifications
NSDictionary *remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification) {
[self processNotification:remoteNotification];
}
}
- (void)processNotification:(NSDictionary *)payload {
NSString *someString = [payload objectForKey:#"someStringKey"];
// do something!
}
I have searched for hours but somewhere is saying that,
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandlerNotification
is called, regardless of application is in active state or inactive state. Somewhere it says when application is not active it push notification calls your didFinishLaunchingWithOptions and there you can detect notification like this :
NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]`
In my case, both are working if user tap on notification and everything is fine, but the problem occurs when user does not tap on notification and direct open app from its icon, then neither didFinishLaunchingWithOptions detect it has notification nor didReceiveRemoteNotification get called. I need to save messages in database, received from push notification, but without tapping on notification how to call method?
to get notification data in didFinishLaunchingWithOptions do this code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(launchOptions != nil)
{
NSDictionary *remoteNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if(remoteNotif != nil){
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[remoteNotif objectForKey:#"aps"] objectForKey: #"badge"] integerValue];
//do something here to process notification
}
}
}
My app doesn't receive push notifications when it's not running.
I am trying to handle remote notification sent as JSON and update data in my app using data from given JSON.
All is going well when app is active or in background.
But when app is not running, app is processing notifications only when I open my app by tapping on notification, but not when I open app by tapping on icon.
Here is the code from appDelegate class:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Parse setApplicationId:appId
clientKey:clKey];
if (application.applicationState != UIApplicationStateBackground) {
BOOL preBackgroundPush = ![application respondsToSelector:#selector(backgroundRefreshStatus)];
BOOL oldPushHandlerOnly = ![self respondsToSelector:#selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)];
BOOL noPushPayload = ![launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (preBackgroundPush || oldPushHandlerOnly || noPushPayload) {
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
}
}
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
UIRemoteNotificationTypeAlert|
UIRemoteNotificationTypeSound|
UIRemoteNotificationTypeNewsstandContentAvailability];
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
[self processPushNotification:notificationPayload foreground:YES];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
TFLog(#"didRegisterForRemoteNotificationsWithDeviceToken");
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
TFLog(#"deviceToken: %#, currentInstallation.badge: %ld", currentInstallation.deviceToken, (long)currentInstallation.badge);
TFLog(#"deviceToken: %#, deviceType: %#", currentInstallation.deviceToken, currentInstallation.deviceType);
TFLog(#"installationId: %#", currentInstallation.installationId);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
TFLog(#"didFailToRegisterForRemoteNotificationsWithError %#", error);
if (error.code == 3010) {
TFLog(#"Push notifications are not supported in the iOS Simulator.");
} else {
// show some alert or otherwise handle the failure to register.
TFLog(#"application:didFailToRegisterForRemoteNotificationsWithError: %#", error);
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
TFLog(#"%#", userInfo);
[PFPush handlePush:userInfo];
[self processPushNotification:userInfo foreground:YES];
[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
TFLog(#"didReceiveRemoteNotification2");
[self processPushNotification:userInfo foreground:YES];
[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
}
As result, app is receiving remote notification in all states, excepting when it is not running.
What have I missed?
You have missed the bit in the Local and Push Notification Programming Guide where it says -
If the action button is tapped (on a device running iOS), the system
launches the application and the application calls its delegate’s
application:didFinishLaunchingWithOptions: method (if implemented); it
passes in the notification payload (for remote notifications) or the
local-notification object (for local notifications).
If the application icon is tapped on a device running iOS, the
application calls the same method, but furnishes no information about
the notification
Also, this note from Apple -
Important: Delivery of notifications is a “best effort”, not
guaranteed. It is not intended to deliver data to your app, only to
notify the user that there is new data available.
If your application is launched from the app icon rather than the notification you need to check for updated content independent of any push notification that may have been received. This enables an application to behave differently when it opens from a notification and when it is opened from the app icon.
For example, the Facebook app opens directly to the item in the notification when launched from the notification alert but not when launched from the app icon - which is the "correct" behaviour from a user point of view. If I interact with the notification then I am interested in its content. If I launch the app from the icon then I just want to use the app - I can then access the notifications in the app if I want.
There's no way you can get the information about your push notification JSON payload when you launch the app by explicitly tapping the app icon.
That's as per Apple's design. When you open the application from any push notification action, then you can retrieve the push notification in application: didFinishLaunchingWithOptions: delegate method. Typically you look up for the UIApplicationLaunchOptionsRemoteNotificationKey key in your launchOptions dictionary.
But, when you open the app by explicitly tapping the application icon, though still the application: didFinishLaunchingWithOptions: delegate will be called, the UIApplicationLaunchOptionsRemoteNotificationKey key will return nil.
Hi Im currently developing an app where i have push notifications activated. I use parse.com. I have got it working so far that i can send a notification and the device receives it and i also get a badge on the app. But when i open the nothing happens and the badge does not disappear. I've set it in my appdelegate.m so parse is handling the push notifications. Heres some code that im using:
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:newDeviceToken];
[currentInstallation saveInBackground];
}
and also:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
[PFPush handlePush:userInfo];
}
Thanks
Ok thaks but how to i show the content of the push notification in the alert view? Or is that not a problem do i just have to configure a alertview with no text?
There are two scenarios:
App closed
When the app is closed and the user taps on a notification it's like when taps on the app icon. The app starts from application:didFinishLaunchingWithOptions:. To know if the app is opened normal (tap icon) or with a notification, just check the dictionary launchOptions for the key UIApplicationLaunchOptionsRemoteNotificationKey.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary * pushDictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushDictionary)
{
//AlertView
}
}
App opened
When the app is opened there are two possible case
App in background UIApplicationStateInactive
App in foreground UIApplicationStateActive
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if (application.applicationState == UIApplicationStateInactive)
{
//AlertView
}
else if (application.applicationState == UIApplicationStateActive)
{
// AlertView
}
}
pushDictionary and userInfo are exactly the same dictionary that represents the notification.
Edit 1
A push notification is a JSON file that iOS automatically convert into a NSDictionary. The standard configuration is:
{"aps":
{
"alert":"Text message",
"sound":"default",
"badge":"1" //the number shown on the app's icon
}
}
From this base you can extend the JSON and put inside your own content. For example
{"aps":
{
"alert":"Text message",
"sound":"default",
"badge":"1" //the number shown on the app's icon
},
"Name":"Fry"
}
Now you can retrive the name in this very simple way:
NSString * name = userInfo[#"Name"];
and show it in the alert.
Edit 2
To show the content of push in UIAlertView just do this:
UIAlertView *av = [[UIAlertView alloc] initWithTitle:name
message:name
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[av show];
If you receive push notification while your app isn't active (killed)
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
will not be triggered. Instead of that you will have to use object with key UIApplicationLaunchOptionsRemoteNotificationKey from launchOptions dictionary inside
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
I am using notification in one of my app ,when app is active , notification is received , i process data and everything is fine , but I do not receive any notification when app is in background or killed.What is the issue can any one plz help me ?
Thank you!
Here is what I doing so far
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
tokenstring = [[NSString alloc] initWithFormat:#"%#",deviceToken];
tokenstring = [tokenstring stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
tokenstring = [[NSString alloc]initWithFormat:#"%#",[tokenstring stringByReplacingOccurrencesOfString:#" " withString:#""]];
NSLog(#"TokeinID:>> %#",tokenstring);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"didReceiveRemoteNotification: %#",userInfo);
AudioServicesPlaySystemSound(1002);
//Some code or logic
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(#"didFailToRegisterForRemoteNotificationsWithError: %#",err.description);
}
When you receive remote notifications, -application:didReceiveRemoteNotification: is only called when your app is in the foreground. If your app is in the background or terminated, then the OS may display an alert or play a sound (depending on the aps dictionary in the notification), but the delegate method is not called.
The remote notification received in the background will only passed to your application if it is launched with that notification's action button, and then you need to look at the launch options dictionary on -application:didFinishLaunchingWithOptions: to see the content of the notification.
If you're looking at new content fetching/remote notification background support with iOS7, check Will iOS launch my app into the background if it was force-quit by the user? and see if that helps, as there are very specific circumstances that those functions work in.
little code ..
When app is not running
(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
is called ..
where u need to check for push notification
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
NSLog(#"app recieved notification from remote%#",notification);
[self application:application didReceiveRemoteNotification:(NSDictionary*)notification];
}else{
}