For iOS >= 8, only
In my AppDelegate, I register for user notifications as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"didFinishLaunchingWithOptions called");
// iOS >= 8.0
// register to receive user notifications
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
...
}
Upon completion, I register for remote notification as follows:
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
NSLog(#"didRegisterUserNotificationSettings called");
//register to receive remote notifications
[application registerForRemoteNotifications];
}
And upon completion, I check to see whether the app is registered
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"didRegisterForRemoteNotificationsWithDeviceToken called");
BOOL pushNotificationOnOrOff = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications]; // always returns TRUE
}
But app always indicates that push notification is enabled, even when the user has explicitly set the app's remote notification capability off (via the notification permissions alert that appears after first time installation of the app, or via app settings.)
I have set the app's Background Modes / Remote Notifications to TRUE. I have been debugging on an actual device (tethered via USB cable) compiled with a development certificate.
Help, I've been battling this for hours.
This seems to be a bug, I also discovered the same behaviour on iPhone 6, iOS 8.1.2.
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications] always returns TRUE even if user declined the push notification permission (via the alert view) or by manually disabling the notification via Settings.app > Notifications.
After some research I discovered that if you have Background App Refresh enabled for the app, then [[UIApplication sharedApplication] isRegisteredForRemoteNotifications] will always returns TRUE.
When Background App Refresh set to FALSE then [[UIApplication sharedApplication] isRegisteredForRemoteNotifications] returns the correct value.
As a workaround, you can evaluate the [[UIApplication sharedApplication] currentUserNotificationSettings].types to determine whether the push notification is allowed or not.
typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
UIUserNotificationTypeNone = 0, // the application may not present any UI upon a notification being received
UIUserNotificationTypeBadge = 1 << 0, // the application may badge its icon upon a notification being received
UIUserNotificationTypeSound = 1 << 1, // the application may play a sound upon a notification being received
UIUserNotificationTypeAlert = 1 << 2, // the application may display an alert upon a notification being received
} NS_ENUM_AVAILABLE_IOS(8_0);
Hope this helps.
Related
I am using Push Notification in my app. It works fine on all iPad iOS versions including iOS 8.3 but strangely on iPhones it is not being received. I have tested on iPhone 5C having iOS 8.3 and iPhone 5S having iOS 8.3. Though Push notification events are being fired from these two iPhones but they are not being received !!
iPhone is generating device token for registration when clicking on "OK" button of push notification alert. I am really at loss to understand as to what is the problem. I have also tried creating new set of certificates, provisioning profiles but the problem is still the same. Any help would be highly appreciated.
My codes are as follow
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
.....
[self registerForRemoteNotification];
.....
return YES;
}
- (void)registerForRemoteNotification
{
if (IS_OS_8_OR_LATER)
{
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
}
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:#"declineAction"])
{
}
else if ([identifier isEqualToString:#"answerAction"])
{
}
}
#endif
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
.....
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
......
}
So please solve my problem.
" Push notification events are being fired from these two iPhones ". What does this mean? Push notifications don't originate on the iPhone. I presume that is just a typo and you meant push events are being fired to the two iPhone.
The first thing is to double check that you are using the correct push token, and when sending to the iPhones you are actually using their push tokens and not the iPad push token.
If that is ok then are these foreground pushes or background pushes? If they are background pushes then try plugging the iPhones into a power supply when you are sending the push and see if they are received then.
Two questions about changes in iOS8 for the user to accept push notifications (as well as notifications such as badges and so).
1) I am using the current approach which is working fine both on iOS7 and iOS8
if ([[[UIDevice currentDevice] systemVersion] floatValue]>= 8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:
(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert)
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
This is completely working as push and alert are working and I got the token in the didRegister delegate method, but I am never asked with a pop-up as it used to be the case. Even if I completely delete the app from my phone?
Why that? Does the OS keep in memory privacy settings for apps even if they have been deleted ?
2) I saw some people suggesting to ask for remote notifications in the following delegate
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
NSLog(#"registered for notifications settings %#",notificationSettings);
//register to receive notifications
[application registerForRemoteNotifications];
}
Why that ?
From document, - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings this method callback will be made upon calling -[UIApplication registerUserNotificationSettings:]. The settings the user has granted to the application will be passed in as the second argument. This means, once we get user permission (or if we already got before), then this method will call, where we can register the app for remote notification by calling, [application registerForRemoteNotifications].
I have an iPhone development application with APNS enabled for the appID. In my applicationDidBecomeActive event I check to see whether or not push notifications are enabled by doing the following:
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"applicationDidBecomeActive");
//Check if remote notifications are enabled for this app, if not proceed with performSetupAndWebService calls
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if(types == UIRemoteNotificationTypeNone)
{
//User has push notifications DISABLED for this application.
NSLog(#"PUSH NOTIFICATIONS DISABLED");
[self performSetupAndWebServiceCalls];
}
else
{
//User has push notifications ENABLED for this application.
NSLog(#"PUSH NOTIFICATIONS ENABLED");
NSLog(#"Registering for push notifications...");
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationType)(UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert)];
}
}
It seems that no matter what I do, my code always tells me that push notifications are disabled. My app icon is in Notification Center in Settings and it is included. I have tried turning off specific types of notification and turning them back on but types == UIRemoteNotificationTypeNone is always true.
Am I missing something obvious? The bad thing is this seems to be affecting users of our production app as well, but not all of them. Very inconsistent and very frustrating.
Any advice?
When notifications are disabled and you try to register for them you get the following UIApplicationDelegate method called:
application:didFailToRegisterForRemoteNotificationsWithError:
- (BOOL) getpushNotificationstatus
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
return ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]);
}
else
{
UIRemoteNotificationType types = [[UIApplicationy sharedApplication] enabledRemoteNotificationTypes]; return (types & UIRemoteNotificationTypeAlert);
}
}
It will work in iOS8 as well
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];'
I added the above code to didfinishLaunchingWithOptions but when a user taps a notification in his notification center and enters my app the notification does not gets cleared.
Edit:
I also tried adding this to my code:
You Also need to increment then decrement the badge in your
application:didReceiveRemoteNotification: method if you are trying
to clear the message from the message centre so that when a user
enters you app from pressing a notification the message centre will
also clear, ie:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
as describes here: iOS application: how to clear notifications? but the notification still won't clear from the notification center
I just Added a Badge number manually to my application and pasted
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
To my AppDelegate. For me this works like a charm.
Note that didfinishLaunchingWithOptions and applicationDidBecomeActive are not the same as Mouhammad Lamaa explained. If you paste this to your AppDelegate and tap the notification in notification center it should disapper. If it does not your App maybe creates a new Notification after becoming active?
add this code
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
the didfinishlaunchingwithoptions launched at the initial launch of your app. if your app the running in the background, didfinishlaunchingwithoptions will not be launched.
When the user open application from notification action - it launches with
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *remoteNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif) {
//handle remote notification
}
....
}
But when the app was in background it calls
- application:didReceiveRemoteNotification:
Also method [[UIApplication sharedApplication] cancelAllLocalNotifications]; cancel registered LOCAL notifications only. Push notifications can't be canceled - they delivered immediately and executed only once.
Can I find out which event launching the application on iOS ?
I need to distinguish between the followings:
Icon tap
Banner notification
Alert notification
Alternatively, can I view the application local settings (set for Banner or alert notification)?
To determine if the app was launched from the using pressing a notification, you need to implement 2 methods.
First, in application didFinishLaunchingWithOptions, do something like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if ([launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
// Handle notification
}
Second:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (application.applicationState == UIApplicationStateActive) {
// The app was open when a remote notification was received...
} else {
// The app was in the background and just came to the foreground in response to the user pressing the push notification
}
}
You can view which notification types have been enabled using:
UIRemoteNotificationType notificationTypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
However, you can't distinguish between Banner or Alert notifications.