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
Related
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"]
I am new to Swift and I have data I'd like to call from an API through JSON. For some strange reason some of the names are written with whitespaces making it difficult for me to declare variables that'll show the integer type value they hold. Here is a screenshot . I am trying to parse the Int value attached to the type "Anti-social behaviour" but don't seem to know how to declare it appropriately.
You can define your own CodingKeys inside the file. Note that the name should be CodingKeys.
struct Types: Codable {
let buglary: Int
let shoplifting: Int
let drugs: Int
let robbery: Int
let antiSocialBehavior: Int
// Other properties
enum CodingKeys: String, CodingKey {
case buglary = "Buglary"
case shoplifting = "Shoplifting"
case drugs = "Drugs"
case robbery = "Robbery"
case antiSocialBehavior = "Anti-social behavior"
// other coding keys
}
}
Also, note that properties in Swift are always camelcased and not capitalized. So, I also changed the name of your properties. Check the enum inside the struct which actually defines the mapping between property name and their encoding / decoding keys.
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.
I have an enum of type String which needs to have multiple variables that have the same value. My enum looks something like this:
class MyClass {
enum MyEnum: String {
case blahA = "blaha"
case blahB = "blahb"
...
static var blahD = "blah"
static var blahE = "blah"
}
}
The reason why I'm using static var's in the above construction is because both "blahD" and "blahE" need to reference the same String value, used in different places (don't ask me why, it just has to be this way). However, I have a method where I need to pass in the value of the enum as follows:
if let testString = myString(foo: MyEnum.blahD) {...}
I unfortunately am getting the following compilation error:
Cannot convert value of type "String" to expected argument type "MyClass.MyEnum".
How do I get around passing the above variable which has duplicate values in my enum in the method, but cast it to the type of "MyClass.MyEnum"?
You can do this if you make the extra case reference the other enum case directly instead of just assigning them the same string value:
class MyClass {
enum MyEnum: String {
case blahA = "blaha"
case blahB = "blahb"
...
case blahD = "blah"
static var blahE = MyEnum.blahD
}
}
Then you can pass MyEnum.blahE the same way you would pass MyEnum.blahD
If the function takes a value of type MyEnum, you cannot do this. The type properties blahD and blahE are simply not of that type. Only the cases of the enum are of type MyEnum.
The function parameter's type must be changed to String.
The only other way around it would be to add a case to the enum that has a raw value matching the value of those two properties: case blahDOrE = "blah". Then you could construct that case: MyEnum(rawValue: MyEnum.blahD), but I can't see that being very useful.
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)