Home » Swift » Changes to registerUserNotificationSettings in Swift 2?

Changes to registerUserNotificationSettings in Swift 2?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I can’t seem to find any documentation on registerUserNotificationSettings beyond what was produced last November (here), but my old code doesn’t seem to work for me any more in Xcode 7 and Swift 2.

I have this code in App Delegate:

let endGameAction = UIMutableUserNotificationAction()
endGameAction.identifier = "END_GAME"
endGameAction.title = "End Game"
endGameAction.activationMode = .Background
endGameAction.authenticationRequired = false
endGameAction.destructive = true

let continueGameAction = UIMutableUserNotificationAction()
continueGameAction.identifier = "CONTINUE_GAME"
continueGameAction.title = "Continue"
continueGameAction.activationMode = .Foreground
continueGameAction.authenticationRequired = false
continueGameAction.destructive = false

let restartGameCategory = UIMutableUserNotificationCategory()
restartGameCategory.identifier = "RESTART_CATEGORY"
restartGameCategory.setActions([continueGameAction, endGameAction], forContext: .Default)
restartGameCategory.setActions([endGameAction, continueGameAction], forContext: .Minimal)

application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: (NSSet(array: [restartGameCategory])) as Set<NSObject>))

I now receive the following two errors on the final line of code:

‘Element.Protocol’ does not have a member named ‘Alert’

and

Cannot invoke ‘registerUserNotificationSettings’ with an argument list of type ‘(UIUserNotificationSettings)’

I’ve searched for information on any changes, but I can’t find anything. Am I missing something obvious?

Answers:

Instead of using (NSSet(array: [restartGameCategory])) as Set<NSObject>) with (NSSet(array: [restartGameCategory])) as? Set<UIUserNotificationCategory>) like so:

application.registerUserNotificationSettings(
    UIUserNotificationSettings(
        forTypes: [.Alert, .Badge, .Sound],
        categories: (NSSet(array: [restartGameCategory])) as? Set<UIUserNotificationCategory>))

Questions:
Answers:

@Banning’s answer will work, but it’s possible to do this in a more Swifty way. Instead of using NSSet and down casting, you can build this from the ground up using a Set with a generic type UIUserNotificationCategory.

let categories = Set<UIUserNotificationCategory>(arrayLiteral: restartGameCategory)
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: categories)
application.registerUserNotificationSettings(settings)

It’s also worth noting that breaking the code up onto multiple lines will help you identify exactly where the problem is. In this case, your second error is only a result of the first since the expressions are inlined.

And as was expertly pointed out by @stephencelis in his comment below, Sets are ArrayLiteralConvertible, so you can reduce this all the way down to the following.

let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: [restartGameCategory])