194

I am trying to register my application for local notifications this way:

UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Alert | UIUserNotificationType.Badge, categories: nil))

In Xcode 7 and Swift 2.0 - I get error Binary Operator "|" cannot be applied to two UIUserNotificationType operands. Please help me.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Nikita Zernov
  • 5,465
  • 6
  • 39
  • 70

4 Answers4

387

In Swift 2, many types that you would typically do this for have been updated to conform to the OptionSetType protocol. This allows for array like syntax for usage, and In your case, you can use the following.

let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)

And on a related note, if you want to check if an option set contains a specific option, you no longer need to use bitwise AND and a nil check. You can simply ask the option set if it contains a specific value in the same way that you would check if an array contained a value.

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

if settings.types.contains(.Alert) {
    // stuff
}

In Swift 3, the samples must be written as follows:

let settings = UIUserNotificationSettings(types: [.alert, .badge], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)

and

let settings = UIUserNotificationSettings(types: [.alert, .badge], categories: nil)

if settings.types.contains(.alert) {
    // stuff
}
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • 1
    What about if you have ```flags |= .Alert?``` Can you use ```flags = [flags, .Alert]``` ? – user3246173 Jan 05 '16 at 16:04
  • i.e Is this treated like a Set where values are unique or as an Array which could possibly lead to an incorrect final value? – user3246173 Jan 05 '16 at 16:11
  • @user3246173 It depends on how the flags variable is declared. If flag's type is explicitly declared as `UIUserNotificationType`, i.e. `var flags: UIUserNotificationType = [.Alert, .Badge]`, then it will be treated like a set, and you could add an element either by using set instance methods like `insert()`, `union()`, `unionInPlace()`, or with the approach that you mentioned without worrying about duplicates. – Mick MacCallum Jan 05 '16 at 20:43
  • If you don't explicitly declare flags as having the type `UIUserNotificationType` and use something like `var flags = [UIUserNotificationType.Alert, UIUserNotificationType.Badge]` in your declaration, then flag's type will be inferred to be `[UIUserNotificationType]`, and adding elements to it via `append()` or other methods will result in duplicates. In the case of the latter, you can simply initialize an instance of `UIUserNotificationType` with the array as input and all will be well, but I recommend the set based approach for clarity. – Mick MacCallum Jan 05 '16 at 20:43
35

You can write the following:

let settings = UIUserNotificationType.Alert.union(UIUserNotificationType.Badge)
Bobj-C
  • 5,276
  • 9
  • 47
  • 83
  • 1
    wow this looks hideous! `NSTrackingAreaOptions.MouseEnteredAndExited.union(NSTrackingAreaOptions.MouseMoved).union(NSTrackingAreaOptions.ActiveAlways)`, but thanks for a working solution – Chad Cache Sep 09 '15 at 14:01
  • 2
    If I am not wrong you can write `var options : NSTrackingAreaOptions =[.MouseEnteredAndExited,.MouseMo‌​ved,.ActiveAlways]` – Bobj-C Sep 09 '15 at 14:27
7

What worked for me was

//This worked
var settings = UIUserNotificationSettings(forTypes: UIUserNotificationType([.Alert, .Badge, .Sound]), categories: nil)
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
Ah Ryun Moon
  • 370
  • 5
  • 4
2

This has been updated in Swift 3.

        let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(settings)
CodeSteger
  • 107
  • 1
  • 3