Burf2000
Burf2000

Reputation: 5193

Switch : Enum Switch issue : Not member of a int

I am writing my first project in Swift(I have been doing ObjectiveC for years) and for some reason, I cant work out why my enum and Switch are not working togetber

enum ContactViewMode : Int
    {
        case ViewModeFavourite = 0
        case ViewModeRecent = 1
        case ViewModeContacts = 2
    }

Property

 @IBInspectable var contactViewMode : Int!

Switch

switch contactViewMode {
            case ContactViewMode.ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case ContactViewMode.ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }

The error I get is Enum case 'ViewModeFavourite' is not a member of type 'Int!'

So I changed it to this as it is not a Int! (I need Int! for Storyboard)

var contactMode:Int = contactViewMode

        switch contactMode {
            case .ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case .ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }

Then I get Enum case pattern cannot match values of the non-enum type 'Int'

Upvotes: 27

Views: 22045

Answers (6)

Quico Moya
Quico Moya

Reputation: 501

The other answers fail to take advantage of Swift’s strong typing. Note that they all have a default case in their switch. Swift knows at compile time, however, whether you have covered all cases of an enum or not, thus rendering the default case unnecessary.

This is a useful feature of the language. Imagine you add an extra case to your enum at a later point. The compiler will complain and point you to all the switches that are not considering that particular case.

How can we take advantage of Swift’s strong typing, then?

First, let’s fix the naming of your enumeration. As I assume you are nesting it inside a ContactView class (and, unlike in Objective-C, it should really be inside it), you can name the enum simply Mode. No need to mention ViewModes in the cases, either. This way you get a cleaner, more idiomatic type.

enum Mode: Int {
    case favourite
    case recent
    case contacts
}

What we need to do is to perform the switch on a Mode, not on an Int. Your Mode is RawRepresentable, and as such you can do:

guard let m = Mode(rawValue: contactViewMode) else { /* handle the situation */ }
switch m {
    case .favourite: /* handle case */
    case .recent: /* handle case */
    case .contacts: /* handle case */
}

That’s all there is to it—instead of switching on the rawValue, get the proper Mode first and then switch on it.

Upvotes: 27

Shikha Budhiraja
Shikha Budhiraja

Reputation: 79

You can simply use contactViewMode and create a new var of type ContactViewMode in case value of contactViewMode is coming from somewhere else and it has to be int.

let contactMode :ContactViewMode = ContactViewMode(rawValue: contactViewMode)!

Now you can easily use switch as shown below:

switch contactMode {
            case .ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case .ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }

Upvotes: 1

Jon Vogel
Jon Vogel

Reputation: 5634

This worked for me:

I have an enum like this:

enum Proximity{
  case Unknown
  case Immediate
  case Near
  case Far
}

Then a switch that looks like this:

switch b.proximity as Proximity {
    case Proximity.Immediate:
         if b.rssi == -30 && b.accuracy == 0.2345{
             closestBeacon = b
         }
    case Proximity.Near:
         return
    case Proximity.Far:
         return
    default:
         return
 }

Im looping through an array of "b" objects that have a proximity property.

Upvotes: 6

rintaro
rintaro

Reputation: 51911

You cannot directly match Int with enum. Instead, you have to convert ContactViewMode to Int with .rawValue property, OR convert Int to ContactViewMode with init(rawValue:) initializer.

The latter example:

switch ContactViewMode(rawValue: contactViewMode) {
case .Some(.ViewModeFavourite):
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
case .Some(.ViewModeRecent):
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
default:
    contacts = DBManager.getAllContacts() as [ContactEntity]
}

because ContactViewMode(rawValue:) returns Optionals, we need .Some().

Upvotes: 3

Antonio
Antonio

Reputation: 72760

You have to declare contactViewMode as ContactViewMode and not Int.

If you really want it to be Int, then you have to change the cases in your switch, by comparing the variable to the rawValue property of the enum cases:

switch contactViewMode {
case ContactViewMode.ViewModeFavourite.rawValue:
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
case ContactViewMode.ViewModeRecent.rawValue:
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
default:
    contacts = DBManager.getAllContacts() as [ContactEntity]
}

but unless you have a good reason for that, I wouldn't recommend

Upvotes: 34

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56707

Enumerations are types. Just because you make clear that the single enum values can be cast to Int doesn't make it valid to declare contactViewMode an Int!. The types simply don't match.

So either declare contactViewMode as ContactViewMode, use your first switch statement and cast to Int! when you actually need it for the storyboard, or use the second switch, but don't use .ViewModeFacourite et al, but the corresponding Int value.

var contactMode:Int = contactViewMode

    switch contactMode {
        case ContactViewMode.ViewModeFavourite.rawValue:
            contacts = DBManager.getFavouriteContacts() as [ContactEntity]
        case ContactViewMode..ViewModeRecent.rawValue:
            contacts = DBManager.getFavouriteContacts() as [ContactEntity]
        default:
            contacts = DBManager.getAllContacts() as [ContactEntity]
    }

Upvotes: 4

Related Questions