I'm trying to get my iOS devices to receive push notifications again, but it's not really working out.
The context in which I'm working:
My project setup
Platforms I need to support: iOS8+
UA version I'm using: 8.0.1 (installed using Cocoapods)
Background modes (Remote notifications) and Push Notifications are ON
My code
Added didReceiveRemoteNotification: to the Application delegate: √
Added UNUserNotificationCenter support (and implemented the delegate methods) for iOS10: √
Configured an UAConfig: √
UA takes off: √
UAPush has all the notificationOptions and has userPushNotificationsEnabled set to YES: √
Here are a few snippets of my code:
(in applicationDidFinishLaunching:)
if (UNUserNotificationCenter.class) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
DLog(#"There was an error trying to request authorization for push: %#", error);
}
}];
} else {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:(UIUserNotificationTypeAlert
| UIUserNotificationTypeSound
| UIUserNotificationTypeBadge)
categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
UAConfig *config = [UAConfig config];
config.inProduction = self.urbanAirshipInProduction;
if(self.urbanAirshipInProduction) {
config.productionAppKey = self.urbanAirshipKey;
config.productionAppSecret = self.urbanAirshipSecret;
} else {
config.developmentAppKey = self.urbanAirshipKey;
config.developmentAppSecret = self.urbanAirshipSecret;
}
[UAirship takeOff:config];
UAPush *pusher = [UAirship push];
pusher.notificationOptions = (UANotificationOptionAlert |
UANotificationOptionBadge |
UANotificationOptionSound);
pusher.pushNotificationDelegate = self;
pusher.userPushNotificationsEnabled = YES;
With the above code I was expecting to receive calls to applicationDidReceiveRemoteNotification:fetchCompletionHandler: and UNUserNotificationCenterDelegate methods for iOS10.
But alas, none of them methods even dared to get called.
I have no clue as to why push won't get pushed to my devices. I checked the App in UA and Installed, Opted in and Background are all green when I search for my device token.
The problem arises with both iOS 8,9 and iOS10. But I'm not sure if this is really an OS thing.
Why?
Because I found a support ticket here and somewhere to the bottom "aboca_ext" (just search the page for his/her username) says:
Hi guys, I found my problem, I was cleaning up my cache when my application was starting, but after UA initiated sqlite db, and by this I was deleting their db. After I fixed that, everything worked as it should.
Now that's interesting because my project also uses SQLCipher, I'm wondering if that produces some kind of conflict (even though I'm not clearing any cache or whatsoever), but I'm not seeing any errors produced by either SQLCipher or UA.
Another funny (actually not so funny) note is that I think UA actually started failing after installing it using Cocoapods, but again--I'm not really sure if that's the problem.
The Urban Airship SDK takes care of registering with UNUserNotificationCenter for you. You should be able to remove registration calls. I don't think it should be causing problems for you, but it could prevent some features such as OOTB categories from working.
As for push notification events, I would recommend listening using the push delegate on the UAPush instance instead of the factory methods or the UNUserNotificationCenter. The UA delegate methods are called across all OS versions. Hopefully it will help simplify your event handling code.
Deleting the sql lite database could cause some issues with reporting, but I would expect push to continue to work. Could you turn on verbose logging and the channel registration payload to see if opt_in is set to true? You can enable verbose logging on the UAConfig object.
Related
I could not find a solution for this and dumbfounded on this. I have this code :
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
NSLog(#"%i %#",granted, error);
}];
and then it immediately gets into the call handler without showing the notification permission
2020-09-18 18:05:46.657991-0700 My App [404:9600] 0 Error Domain=UNErrorDomain Code=1 "Notifications are not allowed for this application" UserInfo={NSLocalizedDescription=Notifications are not allowed for this application}
What am i missing? The alert does not even popup.
NOTE: This same code works with no issues on iOS 13.x, on iOS 14 it immediately fails.
My problem was to use Turkish characters in the Product Name section.
https://developer.apple.com/forums/thread/660648
In my case, Build Settings - Packaging - Product Name was not English. Changed to English and worked.
The problem is you omitted a step. Before asking for authorization, call getNotificationSettingsWithCompletionHandler: and look at the authorizationStatus of the resulting object. If it is UNAuthorizationStatusDenied there is no point proceeding.
My product name was in Japanese. When the product name is non-english the above issue happens! If I change the product name to English it works! I have filed an issue via Apple Feedback Assistant.
I had the same problem. The other posters are right that it seems to be a non-English character in the app name (mine was ñ), for some reason that's disallowed.
To get around it I added CFBundleDisplayName to my plist and put the app's "correct" name (with the ñ) in there, and removed that character from the ${PRODUCT_NAME}.
Hi I am using enabledRemoteNotificationTypes as I am targeting iOS 7 only.
But i observed that, if I set notifications to none and deletes app & then re install, I found that even in notification settings my option is selected other that none, enabledRemoteNotificationTypes method returns me value 3, which is kind of weird.
This is what i tried:
UIRemoteNotificationType notificationType = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
// will return YES if "Alert Style" is set to "Banners" or "Alerts"
if (notificationType & UIRemoteNotificationTypeAlert) {
returnVal = YES;
} else {
returnVal = NO;
}
iOS caches those settings in a fairly annoying way I believe. The only way to truly reset it on the simulator is to reset its content and settings so you get a clean slate.
On a physical device you have to do a dance with adjusting the time as outlined on the ADC Site.
Delete your app from the device.
Turn the device off completely and
turn it back on.
Go to Settings > General > Date & Time and set the
date ahead a day or more.
Turn the device off completely again and
turn it back on.
Is it possible to add interactive notification categories without the notifications permissions dialog popping up? The problem is if they hit "Don't Allow" on the original notifications permissions dialog, but then later change the notification setting manually, your categories never get added and there doesn't seem to be anyway to add them back. Is there anyway to separate the two?
I've tried:
UIMutableUserNotificationAction* snoozeAction = [[UIMutableUserNotificationAction alloc] init];
[snoozeAction setIdentifier:#"snooze_action_id"];
[snoozeAction setTitle:#"Snooze"];
[snoozeAction setActivationMode:UIUserNotificationActivationModeBackground];
[snoozeAction setDestructive:NO];
[snoozeAction setAuthenticationRequired:NO];
UIMutableUserNotificationCategory* SnoozeCategory = [[UIMutableUserNotificationCategory alloc] init];
[SnoozeCategory setIdentifier:kNotifCategory];
[SnoozeCategory setActions:#[snoozeAction] forContext:UIUserNotificationActionContextDefault];
[SnoozeCategory setActions:#[snoozeAction] forContext:UIUserNotificationActionContextMinimal];
NSSet* categories = [NSSet setWithArray:#[SnoozeCategory]];
//NOT asking for permission to send any type of notifications here, just making sure our categories get saved
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeNone categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
As you can see im setting the notification settings to UIUserNOtificationTypeNone, but the permissions dialog still pops up.
From the docs on registerUserNotificationSettings:
The first time your app launches and calls this method, the system asks the user whether your app should be allowed to deliver notifications and stores the response. Thereafter, the system uses the stored response to determine the actual types of notifications you may use.
...
Calling this method with a new user settings object replaces the previous settings request.
So I think what you can do is wrap your code in a method that gets called on each app launch (maybe in application:didFinishLaunchingWithOptions: or even applicationDidBecomeActive:). The user will only be prompted once and if they reject and enable later your new method should add the correct settings.
Hello i successfully created a single interactive push set but when i tried to register for multiple set it only register the last settings and the previously registered ones just overwritten.
My question is how can i create multiple interactive push with different identifiers where i can provoke any of them when i wanted.
Simply use the setWithObjects method on NSSet to include both of your categories in one set object:
NSSet *set = [NSSet setWithObjects:yesNoButtonBackground, acceptDeclineBackground];
Then you only need to call registerUserNotificationSettings once:
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types
categories:set]];
I have an app I am working on with allows the user to set and remove UILocalNotifications. In the course of developing this I have added and removed UILocalNotifications for testing and it seems to be working.
However I am seeing strange behavior where, after deleting my app from the device and running it again without setting any notifications, I will get a UILocalNotification. This notification was not set in this fresh install (checked through adding a breakpoint in my notification setup method).
Is it possible that I have an orphaned UILocalNotification from a previous install (yes, it seems highly unlikely to me too).
I've tried debugging this by setting the notification alertBody to something specific to each new install but this unique string doesn't get displayed in the alert. For example:
notif.alertBody = [NSString stringWithFormat:#"Alert for: %#", alertName];
Has anyone seen this sort of behavior before?
Update: Just confirmed orphaned UILocalNotifications: deleted the app from the device and ran the code below in my rootViewController on viewDidAppear. I get the following output in the Console:
2013-03-14 14:20:07.439 TestApp[16606:907] found alert: uigffhy
2013-03-14 14:20:07.444 TestApp[16606:907] found alert: uigffhy
Where this user was from some previous install. Ugh.
NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notif in notificationArray) {
NSDictionary * info = notif.userInfo;
NSString * name = [info objectForKey:#"sequenceName"];
NSLog(#"found alert: %#", name);
}
Just detect if it's a fresh install (using NSUserDefaults) and do the following in applicationDidFinishLaunching:
[[UIApplication sharedApplication] cancelAllLocalNotifications];