Passing all Enum values in Swift - ios

I have to pass an array of an enum as a function parameter, most of the time I have to pass every single case of the enum. Is there a shorthand way to include all instead of having to pass [.NFL, .NBA, .NHL, .MLB, .NCAAM, .NCAAF] every time? Can I make and all property so that I can just pass .all that included all the cases?
enum LSLeague: String {
case NFL = "NFL"
case NBA = "NBA"
case NHL = "NHL"
case MLB = "MLB"
case NCAAM = "NCAAM"
case NCAAF = "NCAAF"
}

You can use .allCases on the enum type.
So, you might still have to do a bit of work depending on your use case, but you can iterate over each element in an enum if you use:
for league in LSLeague.allCases {
//code here
}
EDIT: #aheze had a great point that I just wanted to add into this answer. He says, "Make sure to also conform the enum to CaseIterable"
So, also make sure that you change the enum you have to:
enum LSLeague: String: CaseIterable {
case NFL = "NFL"
case NBA = "NBA"
case NHL = "NHL"
case MLB = "MLB"
case NCAAM = "NCAAM"
case NCAAF = "NCAAF"
}
if you're able to use this technique.

Swift 5
Use CaseIterable protocol to the enum:
enum CustomTypes: String, CaseIterable {
case location = "Location"
case organization = "Organization"
case dutyUse = "Duty Use"
}
Usage:
let values: [String] = CustomTypes.allCases.map { $0.rawValue }
// values = ["Location", "Organization", "Duty Use"]

Related

Enum: Count and list all cases (from outside!)

I've got this enum (Xcode 10/Swift 5) in its own file ("MyEnum.swift"):
enum MyEnum: Int, CaseIterable {
case A = 0
case B = 1
case C = 2
case D = 3
case E = 4
//Each case needs its own number and description!
var description: String {
switch self {
case .A:
return "abc"
case .B:
return "bcd"
case .C:
return "cde"
case .D:
return "def"
case .E:
return "efg"
}
}
}
... and want to add the descriptions to a PickerView. I know how to set up the functions for the view but I'm now stuck on counting the enum cases and adding the descriptions.
According to the documentation and different questions, adding CaseIterable is supposed to make it possible to call
MyEnum.allCases.count
... but I can only access allCases from within the enum file. From outside (so from my ViewController class) I can only call MyEnum.AllCases, which hasn't got count and, to be honest, I'm not even sure what AllCases returns exactly (it's not a normal array you can use count on).
Adding this code (source) to the enum file at least makes it possible to count the cases:
static let count: Int = {
var max: Int = 0
while MyEnum(rawValue: max) != .none { max += 1 }
return max
}()
...but isn't there supposed to be an easier way to do this with Swift 4.2+?
How do I get a list of the case descriptions to fill my PickerView with (so "abc", "bcd",... - preferably without hardcoding it)?
I tried in 1 file:
enum TestEnum: CaseIterable {
case test1
case test2
}
in another file of another class I wrote:
let count = TestEnum.allCases.count
And it works, but I noticed that when I was typing "allCases" wasn't shown
I manually needed to write it
allCases is declared public, so you should be able to access it from another file:
/// A collection of all values of this type.
public static var allCases: Self.AllCases { get }
like this:
let descriptions = MyEnum.allCases.map { $0.description }
Try cleaning the project and rebuild.
Also, if something is not in Xcode's autocomplete list, it doesn't mean that you can't access that thing. Xcode's complete list has a ton of bugs according to my own experience.
For the sake of completeness and in case allCases doesn't work at all (even after a restart) add this to the enum file:
static let allValues = [MyEnum.A, MyEnum.B, MyEnum.C, MyEnum.D, MyEnum.E]
It's hardcoded but at least it gives you access to everything:
count: MyEnum.allValues.count
description (e.g. "abc"): MyEnum.allValues[0].description
rawValue (e.g. 0):MyEnum.allValues[0].rawValue
The same issue happened to me. What ended up working is restarting xcode.

How to make a reference from an Enum with constants to an Enum with cases of type String

I have 2 enums.
First enum contains Constants:
enum Constants {
static let settings = "settings"
static let help = "Help"
}
Second Enum is of type String and contains few cases:
enum SettingsName: String {
case Settings = "Settings"
case Help = "Help"
}
How can I associate the String from the Constants enum to my second Enum ?
I've tried case Settings = Constants.settings but is not working.
You can't. The raw value of a case must be a literal.

iOS Swift, Enum CaseIterable extension

Im trying to write an extension for an enum that is CaseIterable so that i can get an array of the raw values instead of the cases, Im not entirely sure how to do that though
extension CaseIterable {
static var allValues: [String] {
get {
return allCases.map({ option -> String in
return option.rawValue
})
}
}
}
i need to add a where clause somehow, if i dont have a where clause i get an error saying 'map' produces '[T]', not the expected contextual result type '[String]'
Anyone know if there is a good way of going about this?
my enums i want this function to work on look a bit like this
enum TypeOptions: String, CaseIterable {
case All = "all"
case Article = "article"
case Show = "show"
}
Not all enumeration types have an associated RawValue, and if they have then it is not necessarily a String.
Therefore you need to restrict the extension to enumeration types which are RawRepresentable, and define the return value as an array of RawValue:
extension CaseIterable where Self: RawRepresentable {
static var allValues: [RawValue] {
return allCases.map { $0.rawValue }
}
}
Examples:
enum TypeOptions: String, CaseIterable {
case all
case article
case show
case unknown = "?"
}
print(TypeOptions.allValues) // ["all", "article", "show", "?" ]
enum IntOptions: Int, CaseIterable {
case a = 1
case b = 4
}
print(IntOptions.allValues) // [1, 4]
enum Foo: CaseIterable {
case a
case b
}
// This does not compile:
print(Foo.allValues) // error: Type 'Foo' does not conform to protocol 'RawRepresentable'

Update / change the rawValue of a enum in Swift

Taking the below enum for instance
enum Name : String {
case Me = "Prakash"
case You = "Raman"
}
Can I do the following
Change the raw value of one "case" to something else.
Name.Me = "Prak"
Add a new case to the ENUM
Name.Last = "Benjamin"
Thanks!
Short answer: No, you can't.
Enumeration types are evaluated at compile time.
It's not possible to change raw values nor to add cases at runtime.
The only dynamic behavior is using associated values.
Reference: Swift Language Guide: Enumerations
No you cannot. Instead You can redefine your enum to contain associated values instead of raw values.
enum Name {
case Me(String)
case You(String)
case Last(String)
}
var me = Name.Me("Prakash")
print(me)
me = .You("Raman")
print(me)
me = .Last("Singh")
print(me)

Set enum from NSDictionary Swift

I have information stored in a plist file that I pull into a dictionary.
I have a class with some enums set up as follows:
enum componentPostion {
case upperLeft, UpperRight, lowerLeft, lowerRight
}
I've declared a var as of type componentPostion
var isPosition: componentPostion
Can I then set the enum from the value in the dictionary without having to write a function with a switch statement etc. I've tried this with no luck
isPosition = componentInfo["Type"] as componentPostion
You can use raw values by inheriting the enum from the type you want to hold, in your case I presume it's string:
enum componentPostion : String{
case upperLeft = "upperLeft"
case upperRight = "upperRight"
case lowerLeft = "lowerLeft"
case lowerRight = "lowerRight"
}
Then you can use fromRaw() to obtain an enum case:
let isPosition = componentPostion.fromRaw("upperLeft")
and toRaw() to obtain its string representation
isPosition.toRaw()
Note that fromRaw() returns an optional, in case the parameter doesn't match any raw value defined for the enum
Suggested reading: Raw Values

Resources