Swift3 Xcode 8: 'none' is unavailable: use [] to construct an empty option set ; What should I do?
Asked Answered
C

2

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

        }

    }

}
Congenial answered 22/10, 2016 at 23:1 Comment(3)
You shouldn't check for nil then force unwrap. Just use conditional bindingDenishadenison
Have you tried replacing .none with [] to construct an empty option set?Expostulation
Look at the docs for UIUserNotificationType. There isn't any none value.Buehler
D
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
    }
}
Denishadenison answered 22/10, 2016 at 23:10 Comment(37)
@Hamish Good call,Denishadenison
So I just leave the OptionSet empty?Congenial
Is there a difference between [.badge] and .badge ? How does one check ".badge present" versus "only .badge in the set".Expostulation
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.Denishadenison
NOTE: On your switch case you forgot a bracket to close off the functionCongenial
@AlexanderMomchliov I fixed a couple of issues with your code, but the switch still needs a default: clause, as non-exhaustive.Commixture
@Commixture Ah yeah, I was leaving that for OP to fill out as appropriateDenishadenison
@Expostulation 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).Commixture
@Commixture 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 .Congenial
@Congenial Get no errors doing what? On what line do you get the fatal error? (Please remember this isn't my answer).Commixture
I got no errors in the code. The fatal error is coming in Line 32 (line that says textField.isHidden = true under case []:)Congenial
@Commixture I got no errors in the code. The fatal error is coming in Line 32 (line that says textField.isHidden = true under case []:)Congenial
@Congenial Have you considered perhaps (call me crazy for thinking of this), telling us what the error is?Denishadenison
@Commixture the error is fatal error: unexpectedly found nil while unwrapping an Optional valueCongenial
@Commixture I checked all IBOutlets and they're connected correctly. And they each are only connected to one object which is good:)Congenial
@Congenial Step through the code in the debugger, and see what the value of textfield is right before the errorDenishadenison
@Commixture the fatal error still shows even though they are connected correctly:(Congenial
@Commixture the value of textField is @IBOutlet weak var textField: UITextField!Congenial
@Congenial No it's not, that's the declaration, which says nothing about its valueDenishadenison
@Commixture there is not another isHidden for textField before the function, therefore I don't think it had a value beforeCongenial
@Congenial Have you read what I said? Step through the code in the debugger, and see what the value of textfield is right before the errorDenishadenison
@Commixture in the debugger the only thing it says about the textField is Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)Congenial
@Congenial That's not what I said. Also, I'm not HamishDenishadenison
@Commixture Then how do I find textField value in the debugger. And I was only adding Hamish so both of you could see thisCongenial
@Congenial You need to look up a tutorial on using the debuggerDenishadenison
@Commixture the value of textField is nilCongenial
@Congenial well, when is that textField value set?Denishadenison
@Commixture I can't figure out how to find when that value is set. Can you tell me where to find out?Congenial
@Congenial Well first check its IBOutletDenishadenison
@AlexanderMomchliov what should I do with the IBOutlet?Congenial
@Commixture what should I do with the IBOutletCongenial
@Congenial 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..." – I would highly reccomend going through them to see if they solve your problem.Commixture
@Commixture the updateUI() method is getting called in the viewDidLoad() therefore it is after the IBOutlets are being connectedCongenial
@Commixture the updateUI() method is getting called in the viewDidLoad() therefore it is after the IBOutlets are being connectedCongenial
@Congenial 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.Commixture
@Congenial However, if none of these suggestions solve your problem, then please ask a new question with a minimal reproducible example 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.Commixture
@Congenial 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 :)Commixture
C
3

So replace every instance of UIUserNotificationType.none with []

Centering answered 22/10, 2016 at 23:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.