0

I could not find some help for my problem here on SO or somewhere else, so I hope somebody of you guys can help me.

I'm trying to implement the functionality of a reminder in my iOS app, that the user enables by himself. The reminder is a local notification.

I'm not asking the user for permission for local notifications until he enables the reminder. After that I have to check, if the user granted the permissions and schedule a notification if so.

The core problem here is that the code doesn't stop executing on the ´registerUserNotificationSettings´ method and wait for the result of the upcoming UIAlertController. Therefore I cannot check for permissions directly after calling the method. I also don't want to ask for permission at the first start of the app because the user doesn't know why my app should send notifications and I think that this would be too much for the first start and for an optional feature.

I know of the appdelegate message ´didRegisterUserNotificationSettings´, which is sent after the question was answered. An idea is to firstly store the notification in a global variable and schedule it if the permission was granted. But that would be too much code that will be executed if the notification isn't even scheduled at the end.

So I'm looking for some solution to ask the user for permission and then decide whether to create and schedule the notification or not.

This is my problematic piece of code in the ´value changed´-event of a UISwitch, which does not work as intended:

//check if the app is allowed to send notifications or ask the user
    var settingTypes = UIApplication.sharedApplication().currentUserNotificationSettings()?.types
    if (settingTypes?.contains(.Alert) == false) {
        let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: nil)
        UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)

//get NotificationSettings again after the user was asked 
    settingTypes = UIApplication.sharedApplication().currentUserNotificationSettings()?.types
    }


//now check if if notifications are finally permitted
    if (settingTypes?.contains(.Alert) == true) {
        let notification = UILocalNotification()
        * create notification *
        UIApplication.sharedApplication().scheduleLocalNotification(notification)
    }
    else {
        switchNotification.on = false
    }

Does anyone has an idea? Thank you in advance

Martin
  • 151
  • 10

2 Answers2

1

Declare a Closure in AppDelegate

var userNotificationChanged: ((settings: UIUserNotificationSettings) -> Void)?

and call the closure when user registers for notification

Your AppDelegate didRegisterUserNotificationSettings would look like below

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
    if (userNotificationChanged != nil) {
        userNotificationChanged!(settings: notificationSettings)
    }
}

Now in your valueChanged event of UISwitch set the closure and perform your required action inside:

    (UIApplication.sharedApplication().delegate as! AppDelegate).userNotificationChanged = { (settings: UIUserNotificationSettings) -> Void in

        //Schedule your notification here
    }
Mohammed Shakeer
  • 1,446
  • 16
  • 23
  • Thank you very much! This is exactly, what I was looking for. I'm new to swift and already read about closures, but did not really know when to use them. I think I can also use them now in other situations. – Martin Jul 28 '16 at 14:43
-1

Put this simple code in didFinishLaunchingWithOptions

if #available(iOS 8.0, *)
{

    if application.respondsToSelector("isRegisteredForRemoteNotifications")
    {

        let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])

        let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)

        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
    }

}
else{
        let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
        application.registerForRemoteNotificationTypes(types)
}
Hasya
  • 9,792
  • 4
  • 31
  • 46
  • 1
    I do not really understand the whole code, but did you read my whole question? I wrote that I don't want to ask the user for permission on the first app start. It seems that this is just what your code is doing, isn't it? Otherwise can you please explain your code a bit? Thank you – Martin Jul 28 '16 at 14:47