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].
Related
I have the following flow: on the first app launch, I present a view which explains to the user why I need him to accept push notifications. He then has two options: skip (if he does this, I will never register for push notifications), or accept push notifications, in which case I display the push notifications popup where he can either accept or refuse.
I have two issues. First of all, I always used to register for push notifications in the AppDelegate, with the following code:
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)])
{
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
in the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
I am now attempting to use this exact same code in the view I display with the two buttons, and I've removed the code from the AppDelegate. Will this work anyway? The issue with having the code in the AppDelegate is that it directly prompts the user to either accept or refuse the push notifications on first launch, something I want to avoid.
Then, there is the issue that I need to know as soon as the user has either accepted or refused the push notifications (on the popup). I don't care what decision he's made, I just need to know as soon as he's made one, to be able to present the next view.
I've tried the following delegate methods:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
and -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
But they don't get called when I click on either allow or don't allow.
What is the right way to do this?
I found the solution to this problem.
First of all, as commented by #ystack, you can absolutely invoke registration for remote notifications anywhere in the app.
Secondly, I added this method in my App Delegate:
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"pushNotification"
object:self];
}
Then I added this in my particular ViewController:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(pushNotificationClicked:)
name:#"pushNotification"
object:nil];
And finally this method in the same ViewController:
- (void)pushNotificationClicked:(NSNotification *) notification {
if ([[notification name] isEqualToString:#"pushNotification"]){
//do whatever you want
}
}
This way I get a callback when the user presses either Allow or Don't Allow.
I am trying to send Push notification on iOS device via Worklight using sample code and steps provided at https://mobilefirstplatform.ibmcloud.com/tutorials/en/foundation/6.3/notifications/push-notifications-native-ios-applications/
When I run the app on iOS 7 device, i get a device token and therefore when i tap on subscribe button, i get a successful response. This works even if, when we don't write any code in didFinishLaunchingWithOptions for registeringForRemoteNotifications.
But When i run the same code on iOS 8 and iOS 9 device I am getting following message on console :
iOSNativePush[1119:372642] registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.
To make my application run for iOS>=8 device, I wrote following code :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if([[UIApplication sharedApplication] respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound)];
}
return YES;
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[application registerForRemoteNotifications];
}
Still i am getting "iOSNativePush[1119:372642] registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later" message in console but for iOS 8 device I am getting device token and device is getting subscribed but same thing is not working for iOS 9 device.
I refered following link also but no luck
https://www.ibm.com/developerworks/community/blogs/worklight/entry/understanding-and-setting-up-push-notifications-in-development-evnironment?lang=en
Kindly help me to obtain device token for iOS 9 device.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
Use above code
This issue has been fixed in later iFixes of MobileFirst 6.3 and higher.
To resolve:
1) Update your MobileFirst studio to the latest iFix .
2) Add a new iOS native environment.
3) Replace the sample's native folder with the newly generated one ( with iFix)
4) Clean , build and deploy.
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.
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.
Is there any known problem issue with:
application:didReceiveLocalNotification delegate
on iOS 8?
My application creates local notifications using UILocalNotification. When application is in background I get notifications, and when I click on the notification banner, it moves to my app. But this method:
-(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
is never called on iOS 8(Xcode 5.1.1), but works well on iOS 7 or earlier.
P.S. I've also tested project from this site:
http://www.appcoda.com/ios-programming-local-notification-tutorial/
and it doesn't work on iOS 8.
Actually, the solution on iOS 8 is to request authorization for notifications settings to the user, otherwise the delegate method -didReceiveLocalNotification: will never be called. You can do so by adding this code to the -didFinishLaunchingWithOptions: method:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
categories:nil]];
}
This will show the user an alert view asking for permission to display notifications. If she accepts, the delegate method will be called whenever a local notification is fired.
Use this for iOS8
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler{
}
I meet the same problem...
You must change to use the following code:
// register notification for push mechanism
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
to instead of the original:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound];
I have noticed the same on iOS8Beta5. Same code works fine on iOS8Beta4.
Edit:
If as the answer suggests, we need to handle it differently - then why did they drop support between two beta builds. It would make sense if iOS8Beta1 build behaved this way. This is why I feel its a bug.