UIUserNotificationSettings not working right? - ios

I have the following code which Im using to decide if the user has given permissions for local notifications:
UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (grantedSettings.types == UIUserNotificationTypeNone) {
NSLog(#"No permission granted");
//IF AND ONLY IF alerts are wanted by raymio user! FIX
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Notice"
message:#"You need to enable notifications to be able to receive sun alerts!"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* OKAction = [UIAlertAction actionWithTitle:#"Go to Settings now" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];
}];
[alert addAction:OKAction];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:cancelAction];
[self.window addSubview:self.window.rootViewController.view];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
else if (grantedSettings.types & UIUserNotificationTypeSound & UIUserNotificationTypeAlert ){
NSLog(#"Sound and alert permissions ");
}
else if (grantedSettings.types & UIUserNotificationTypeAlert){
NSLog(#"Alert Permission Granted");
Basically, it just dont work. I get "Alert Permission Granted" when the allow notification switch is clearly set to off in app settings. If i switch it to on, the settings dont change either. Below is the console output for grantedSettings. It stays the same. I have other cases where something is off. For now I am resorting to just removing code. I had to do this in the first place in case a user accidentally pressed cancel on the initial prompt (and yet requests alerts in-app).
granted settings: <UIUserNotificationSettings: 0x17042e940; types: (UIUserNotificationTypeAlert UIUserNotificationTypeBadge UIUserNotificationTypeSound);>
Any insight in this buggy area? Btw, I am running on 8.1. The need for this is not entirely the same on ios9, as ios9 will let the user be prompted for notification permission more than once pr device..

I used the below method in one of my project to determine whether the user has given permission or not, or whether he/she actually turned off the notifications in settings. Put this method in Appdelegate and check
-(BOOL)notificationServicesEnabled {
BOOL isEnabled = NO;
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]){
UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (!notificationSettings || (notificationSettings.types == UIUserNotificationTypeNone)) {
isEnabled = NO;
} else {
isEnabled = YES;
}
} else {
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert) {
isEnabled = YES;
} else{
isEnabled = NO;
}
}
return isEnabled;
}
Then you can simple check with condition
if([self notificationServicesEnabled])
I hope this should help you out.

In iOS 9, to check whether the app is currently registered for remote notifications, use this:
BOOL isEnabled = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications];

Related

How can I prevent IOS apps from resetting after changing permissions (such as Microphone, Camera, Photoes)?

My question is similar to "How can I prevent iOS apps from resetting after changing Camera permissions?".
But I don't understand the answer very well .
I set the microphone permission by the code as follow:
-(BOOL)canRecord
{
__block BOOL bCanRecord = NO;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)
{
//prompt
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"setting permission" message:#"need microphone permission" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *settingAction = [UIAlertAction actionWithTitle:#"setting now" style:UIAlertActionStyleDefault handler:^(UIAlertAction * a){
// jump to setting
NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if ([[[UIDevice currentDevice]systemVersion]floatValue]>10.0) {
[[UIApplication sharedApplication] openURL:url options:#{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
}
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"later" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:settingAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}else{
if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 7.0) {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession performSelector:#selector(requestRecordPermission:) withObject:^(BOOL granted) {
if (granted) {
bCanRecord = YES;
} else {
bCanRecord = NO;
}
}];
// }
}
NSLog(#"bCanRecord %d",bCanRecord);
}
return bCanRecord;
}
then back to my app by clicking the return key in the status bar, my app will force a refresh and I will lose my place in the app.
I'm using an iPhone5 running IOS 9.3.3.

iOS push notifications does not play sound and does not show badge alert [in Objective C]

I was using the demo instructions provided here:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAlertController_class/
here is the main code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
return YES;
}
-(void)MessageBox:(NSString *)title message:(NSString *)messageText
{
// OLD way of sending push notifications:
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:messageText delegate:self
// cancelButtonTitle:#"OK" otherButtonTitles: nil];
// [alert show];
UIAlertController* alert= [UIAlertController
alertControllerWithTitle:title
message:messageText
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
I get notifications to appear, however there is not sound and badge update.
Any suggestions?
Have you included the badge and sound parameters in your JSON payload?
EXAMPLE
{"aps":{"alert":"Example notification title","badge":1,"sound":"default"}}
I'd read up on the Apple Push Notification Payload Documents to familiarise yourself.

Alert user to enable notifications from settings in ios

Hi in my app i have notification section and user can enable notifications using switch.After first launch when ever user on the switch i am getting don't allow or ok alertview from ios.If user select don't allow and switch will be off and user will not get notifications. Now if user try to on the switch i want to show an alert to user with text "Please enable notifications from settings".Can any one please suggest the way to do this.
For UILocalNotification permission check the following, types parameter value will be none incase user has not allowed it.
[[UIApplication sharedApplication] currentUserNotificationSettings]
You can check the the permission using isRegisteredForRemoteNotifications method.
- (void)checkForNotificationPermission
{
if (!([[UIApplication sharedApplication] isRegisteredForRemoteNotifications] && [self pushNotificationsEnabled]))
{
// Show alert here
}
}
// For fixing iOS 8 issue mentioned here http://stackoverflow.com/a/28441181/1104384
- (BOOL)pushNotificationsEnabled
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)])
{
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
return (types & UIUserNotificationTypeAlert);
}
else
{
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
return (types & UIRemoteNotificationTypeAlert);
}
}
NSString *iOSversion = [[UIDevice currentDevice] systemVersion];
NSString *prefix = [[iOSversion componentsSeparatedByString:#"."] firstObject];
float versionVal = [prefix floatValue];
if (versionVal >= 8)
{
if ([[UIApplication sharedApplication] currentUserNotificationSettings].types != UIUserNotificationTypeNone)
{
NSLog(#" Push Notification ON");
}
else
{
NSString *msg = #"Please press ON to enable Push Notification";
UIAlertView *alert_push = [[UIAlertView alloc] initWithTitle:#"Push Notification Service Disable" message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Setting", nil];
alert_push.tag = 2;
[alert_push show];
NSLog(#" Push Notification OFF");
}
}
else
{
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types != UIRemoteNotificationTypeNone)
{
NSLog(#" Push Notification ON");
}
else
{
NSString *msg = #"Please press ON to enable Push Notification";
UIAlertView *alert_push = [[UIAlertView alloc] initWithTitle:#"Push Notification Service Disable" message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Setting", nil];
alert_push.tag = 2;
[alert_push show];
NSLog(#" Push Notification OFF");
}
}
UIUserNotificationType allNotificationTypes =
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIAp
plication sharedApplication] registerUserNotificationSettings:settings];
// [[UIApplicationsharedApplication]registerForRemoteNotifications];
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]) {
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
if (types == UIUserNotificationTypeNone) {
[_TransparentView setBackgroundColor:[[UIColor clearColor] colorWithAlphaComponent:0.8]];
lblDescription.text=#"Please enable notifications from settings.";
}
}
}
Try this code. It will work for iOS 8.0 later and before versions.
if (([[[UIDevice currentDevice] systemVersion] compare:8.0 options:NSNumericSearch] != NSOrderedAscending)) {
if (![[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
{
DisplayAlert(#"Please enable Permission from Settings->App Name->Notifications->Allow Notifications");
return;
}
}
else{
UIRemoteNotificationType status = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (status == UIRemoteNotificationTypeNone)
{
DisplayAlert(#"Please enable Permission from Settings->App Name->Notifications->Allow Notifications");
return;
}
}

Is it possible to fallback to AuthorizedWhenInUse when a user doesn't allow AuthorizedAlways in iOS?

My app uses user location in the background, but sometimes, users don't allow the app to always collect GPS data. The app can handle foreground only locations, and I'd like to set that as a fallback.
Is there a graceful way, once an iOS user has declined my AuthorizedAlways request, to re-prompt the user to give AuthorizedWhenInUse permission ?
You can't force it, but you can:
1) know that user is declined permission
2) and show an alert asking: "Please, go to settings and enable it".
3) go to ios settings ([[UIApplication sharedApplication] openURL:[NSURL URLWithString: UIApplicationOpenSettingsURLString]];)
Something like this:
- (void)checkLocation
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways){
NSLog(#"ok");
} else if(status == kCLAuthorizationStatusDenied ||
status == kCLAuthorizationStatusAuthorizedWhenInUse){
[self showRequestLocationMessage];
} else if(status == kCLAuthorizationStatusNotDetermined){
//request auth
}
}
- (void)showRequestLocationMessage
{
UIAlertAction *action = [UIAlertAction actionWithTitle:#"Settings"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * alertAction){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: UIApplicationOpenSettingsURLString]];
}];
NSString *title = #"Service Enable";
NSString *text = #"Please enable your location.. bla bla bla";
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:title
message:text
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction:cancelAction];
[alertController addAction:action];
[self presentViewController:alertController animated:YES completion:nil];
}

Push Notification ON or OFF Checking in iOS

I want to check "Push Notification option" in iOS device, any time if the application is running (or ON from resume mode). I use the following code to check, if the option is OFF:
-(void)PushNotificationServiceChecking
{
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
{
NSString *msg = #"Please press ON to enable Push Notification";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Push Notification Service Disable" message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"ON", nil];
alert.tag = 2;
[alert show];
}
}
Then i use the following code for going to the "Settings tab >> Notification center", so that user can on it manually :
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 2)
{
if (buttonIndex == 0)
{
// this is the cancel button
}
else if (buttonIndex == 1)
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert)];
}
}
}
But, now the problem that I am facing is, it only appears at the 1st time after launching the application. It works as I want. But after that, if I turn OFF the "Push Notification option" from "settings" it gives me no "Alert Message".
In iOS 8 you can now use:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications];
And to check how the settings are setup you could use:
[[UIApplication sharedApplication] currentUserNotificationSettings];
If the App once got registered with the registerForRemoteNotification, then you can disable as well as enable . Once you disable and you are about to Re-Regigister with it, then this will enable the registerForRemoteNotification, without Popup for a alert.
Technical Note TN2265: Troubleshooting Push Notifications
The first time a push-enabled app registers for push notifications, iOS
asks the user if they wish to receive notifications for that app. Once
the user has responded to this alert it is not presented again unless
the device is restored or the app has been uninstalled for at least a
day.
If you want to simulate a first-time run of your app, you can leave
the app uninstalled for a day. You can achieve the latter without
actually waiting a day by setting the system clock forward a day or
more, turning the device off completely, then turning the device back
on.
Fore More Info: INFO && Info 2
Edit : For checking with alert enable -
use
if (types & UIRemoteNotificationTypeAlert){}
instead of
if (types == UIRemoteNotificationTypeNone){}
Edit :
Latest update from the doc for iOS 8 or later, You can check out by :
- (BOOL)isRegisteredForRemoteNotifications
It's work for me. Hope this help! :D
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")){
UIUserNotificationType type = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
if (type == UIUserNotificationTypeNone){
ALERT_WITH_TITLE(#"", kMessageNotificationTurnOnRequire);
}
}
else {
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone) {
ALERT_WITH_TITLE(#"", kMessageNotificationTurnOnRequire);
}
}
NSString *iOSversion = [[UIDevice currentDevice] systemVersion];
NSString *prefix = [[iOSversion componentsSeparatedByString:#"."] firstObject];
float versionVal = [prefix floatValue];
if (versionVal >= 8)
{
if ([[UIApplication sharedApplication] currentUserNotificationSettings].types != UIUserNotificationTypeNone)
{
NSLog(#" Push Notification ON");
}
else
{
NSString *msg = #"Please press ON to enable Push Notification";
UIAlertView *alert_push = [[UIAlertView alloc] initWithTitle:#"Push Notification Service Disable" message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Setting", nil];
alert_push.tag = 2;
[alert_push show];
NSLog(#" Push Notification OFF");
}
}
else
{
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types != UIRemoteNotificationTypeNone)
{
NSLog(#" Push Notification ON");
}
else
{
NSString *msg = #"Please press ON to enable Push Notification";
UIAlertView *alert_push = [[UIAlertView alloc] initWithTitle:#"Push Notification Service Disable" message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Setting", nil];
alert_push.tag = 2;
[alert_push show];
NSLog(#" Push Notification OFF");
}
}

Resources