7

I was using the UIUserNotificationType.none in Swift3 on ViewController.swift, and I got this error: 'none' is unavailable user[] to construct an empty option set ; Here is my code:

func updateUI() {
       let currentSettings = UIApplication.shared.currentUserNotificationSettings

    if currentSettings?.types != nil {

        if currentSettings!.types == [UIUserNotificationType.badge, UIUserNotificationType.alert] {

            textField.isHidden = false

            button.isHidden = false

            datePicker.isHidden = false

        }
        else if currentSettings!.types == UIUserNotificationType.badge {

            textField.isHidden = true

        }
        else if currentSettings!.types == UIUserNotificationType.none {

            textField.isHidden = true

            button.isHidden = true

            datePicker.isHidden = true

        }

    }

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
krish
  • 159
  • 1
  • 12

2 Answers2

15

As the error says, there is no .none member to that OptionSet type. Just use [], the empty option set.

This should work:

func updateUI() {
    guard let types = UIApplication.shared.currentUserNotificationSettings?.types else {
        return
    }

    if types == [.badge, .alert] {
        textField.isHidden = false
        button.isHidden = false
        datePicker.isHidden = false
    }
    else if types == [.badge] {
        textField.isHidden = true
    }
    else if types.isEmpty {
        textField.isHidden = true
        button.isHidden = true
        datePicker.isHidden = true
    }
}

Even better, use a switch:

func updateUI() {
    guard let types = UIApplication.shared.currentUserNotificationSettings?.types else {
        return
    }

    switch types {
    case [.badge, .alert]:
        textField.isHidden = false
        button.isHidden = false
        datePicker.isHidden = false

    case [.badge]:
        textField.isHidden = true

    case []: 
        textField.isHidden = true
        button.isHidden = true
        datePicker.isHidden = true

    default:
        fatalError("Handle the default case") //TODO
    }
}
Alexander
  • 59,041
  • 12
  • 98
  • 151
  • @Hamish Good call, – Alexander Oct 22 '16 at 23:11
  • So I just leave the `OptionSet` empty? – krish Oct 22 '16 at 23:11
  • Is there a difference between `[.badge]` and `.badge` ? How does one check ".badge present" versus "only .badge in the set". – Thilo Oct 22 '16 at 23:13
  • 1
    Thilo `.badge` and `[.badge]` have the same meaning. `OptionSet` perform a bitwise OR of all the members of the set to produce an integer bit pattern. In the case of `[.badge]`, it's ORed with nothing, so the result is just `.badge`. In the case of `.badge`, the value is used directly. – Alexander Oct 22 '16 at 23:15
  • NOTE: On your switch case you forgot a bracket to close off the function – krish Oct 22 '16 at 23:17
  • @AlexanderMomchliov I fixed a couple of issues with your code, but the `switch` still needs a `default:` clause, as non-exhaustive. – Hamish Oct 22 '16 at 23:19
  • @Hamish Ah yeah, I was leaving that for OP to fill out as appropriate – Alexander Oct 22 '16 at 23:20
  • 2
    @Thilo An option set is just like a regular set – so if you want to test whether it contains `.badge` (rather than just being a set of only `.badge`), you can just say `types.contains(.badge)`. – Hamish Oct 22 '16 at 23:23
  • @Hamish Now even though I get no errors doing that. When I run it I get- fatal error: unexpectedly found nil while unwrapping an Optional value . – krish Oct 22 '16 at 23:29
  • 1
    @krish Get no errors doing what? On what line do you get the fatal error? (Please remember this isn't my answer). – Hamish Oct 23 '16 at 14:59
  • I got no errors in the code. The fatal error is coming in Line 32 (line that says `textField.isHidden = true` under `case []:`) – krish Oct 23 '16 at 20:45
  • @Hamish I got no errors in the code. The fatal error is coming in Line 32 (line that says `textField.isHidden = true` under `case []`:) – krish Oct 23 '16 at 20:46
  • 1
    @krish Have you considered perhaps (call me crazy for thinking of this), telling us what the error is? – Alexander Oct 23 '16 at 20:47
  • @Hamish the error is `fatal error: unexpectedly found nil while unwrapping an Optional value` – krish Oct 23 '16 at 20:48
  • @Hamish I checked all IBOutlets and they're connected correctly. And they each are only connected to one object which is good:) – krish Oct 23 '16 at 20:50
  • @krish Step through the code in the debugger, and see what the value of `textfield` is right before the error – Alexander Oct 23 '16 at 20:55
  • @Hamish the fatal error still shows even though they are connected correctly:( – krish Oct 23 '16 at 20:55
  • @Hamish the value of `textField` is `@IBOutlet weak var textField: UITextField!` – krish Oct 23 '16 at 20:58
  • @krish No it's not, that's the declaration, which says nothing about its value – Alexander Oct 23 '16 at 21:00
  • @Hamish there is not another `isHidden` for `textField` before the function, therefore I don't think it had a value before – krish Oct 23 '16 at 21:15
  • @krish Have you read what I said? Step through the code in the debugger, and see what the value of textfield is right before the error – Alexander Oct 23 '16 at 21:16
  • @Hamish in the debugger the only thing it says about the `textField` is `Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)` – krish Oct 23 '16 at 21:20
  • @krish That's not what I said. Also, I'm not Hamish – Alexander Oct 23 '16 at 21:23
  • @Hamish Then how do I find `textField` value in the debugger. And I was only adding Hamish so both of you could see this – krish Oct 23 '16 at 21:25
  • @krish You need to look up a tutorial on using the debugger – Alexander Oct 23 '16 at 21:26
  • @Hamish the value of `textField` is `nil` – krish Oct 23 '16 at 21:37
  • @krish well, when is that `textField` value set? – Alexander Oct 23 '16 at 21:53
  • @Hamish I can't figure out how to find when that value is set. Can you tell me where to find out? – krish Oct 23 '16 at 22:05
  • @krish Well first check its IBOutlet – Alexander Oct 23 '16 at 22:07
  • @AlexanderMomchliov what should I do with the IBOutlet? – krish Oct 23 '16 at 22:12
  • @Hamish what should I do with the IBOutlet – krish Oct 23 '16 at 22:44
  • 1
    @krish When is this code (the `updateUI()` method) getting called? It's most likely happening before your IBOutlets have been connected (this happens at runtime). Please note that [there are many many questions on SO about "fatal error: unexpectedly found nil..."](https://www.google.co.uk/search?q=swift%20fatal%20error%20unexpectedly%20found%20nil%20while%20unwrapping%20an%20optional%20value%20site%3Astackoverflow.com) – I would highly reccomend going through them to see if they solve your problem. – Hamish Oct 23 '16 at 23:00
  • @Hamish the `updateUI()` method is getting called in the `viewDidLoad()` therefore it is after the IBOutlets are being connected – krish Oct 23 '16 at 23:43
  • @Hamish the `updateUI()` method is getting called in the `viewDidLoad()` therefore it is after the `IBOutlets` are being connected – krish Oct 24 '16 at 18:58
  • @krish Place a breakpoint in the `updateUI()` method and take a look at the stack trace – my gut feeling is that you are indeed calling it before `viewDidLoad()` and thus the IBOutlets are not connected. Besides not being connected, the only other real cause of this problem that I can think of is that you've accidently set the outlet to `nil` somewhere in your code, although this seems quite unlikely. – Hamish Oct 24 '16 at 19:58
  • 1
    @krish However, if none of these suggestions solve your problem, then please [ask a new question](http://stackoverflow.com/questions/ask) with a [mcve] of the problem, as this problem is completely unrelated to the question you originally asked, and there's only so much help we can give through exchanges in the comments without actually seeing your code. Although please note that as I mentioned above, this is a very common problem. Therefore please do make sure that you've looked through the many questions on SO about this error before asking. – Hamish Oct 24 '16 at 19:58
  • 1
    @krish I would also kindly request that you don't repost your comments in order to attract our attention – it comes across as somewhat rude, especially given that people on SO volunteer their free time to help others, and many of us have busy lives outside of SO. Thank you :) – Hamish Oct 24 '16 at 20:07
3

So replace every instance of UIUserNotificationType.none with []

Duncan C
  • 128,072
  • 22
  • 173
  • 272