I wanted to make an enum with the Contacts framework CNLabeledValue's CNPhoneNumber type which are defined as:
// Generic labels
CONTACTS_EXTERN NSString * const CNLabelHome NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelWork NS_AVAILABLE(10_11, 9_0);
CONTACTS_EXTERN NSString * const CNLabelSchool NS_AVAILABLE(10_15, 13_0);
CONTACTS_EXTERN NSString * const CNLabelOther NS_AVAILABLE(10_11, 9_0);
I did something like this:
enum CNLabeledValueType: String {
case home
case work
case school
case other
var rawValue: String {
switch self {
case .home:
return CNLabelHome
case .work:
return CNLabelHome
case .school:
return CNLabelSchool
default:
return CNLabelOther
}
}
}
But I think I still need to do some map the enum to the correct runtime strings, do I need to also override the init of the enum somehow?
What I would like to achieve would be the same result as if this would be possible:
enum CNLabeledValueType: String {
case home = CNLabelHome
case work = CNLabelWork
case school = CNLabelSchool
case other = CNLabelOther
}
But it is not possible because Swift enums require that "Raw value for enum must be a String literal" as the compiler complains. So is there any way to make something similar using computed properties to be possible to switch by case string and also get the correct string computed value at runtime for each case?
You can implement init(rawValue:) like this:
init?(rawValue: String) {
switch rawValue {
case CNLabelHome:
self = .home
case CNLabelWork:
self = .work
case CNLabelSchool:
self = .school
case CNLabelOther:
self = .other
default:
return nil
}
}
Also note that you have a typo in the rawValue implementation. The second case should return CNLabelWork. I also suggest not to use default: in the raw value switch statement:
var rawValue: String {
switch self {
case .home:
return CNLabelHome
case .work:
return CNLabelWork
case .school:
return CNLabelSchool
case .other:
return CNLabelOther
}
}
This way, when you want to add a new label, an error will appear at the switch statement, so you won't forget to add another case.
Related
I'm kinda block for this scenario , I have a enum which have the same value now the question here is that they have different usecases how can I put a condition for this to case in switch:
supposed I have this:
enum ApiType: String, CaseIterable {
case dashboard = "dashboardRootIdApi"
case profile = "profileRootIdApi"
case usemeInLogin = "authenticationAccessIdApi"
case usemeInLogout = "authenticationAccessIdApi"
}
and from my usecases classes:
func authenticationDtoScreen(for: ApiType) -> UIControllerSharedScreen {
switch myType {
case .usemeInLogin: {
return UIControllerScreenConfiguration(
for: .usemeInLogin,
title: "Login"
)
}
case .usemeInLogout: {
return UIControllerScreenConfiguration(
for: .usemeInLogout,
title: "Logout"
)
}
}
}
I know .usemeInLogout will never be happend cause of this .usemeInLogin.
Those string values don't have to be the raw value of your enum. It can be a calulated property:
enum ApiType: CaseIterable {
case dashboard
case profile
case usemeInLogin
case usemeInLogout
var apiType: String {
switch self {
case .dashboard: return "dashboardRootIdApi"
case .profile: return "profileRootIdApi"
case .usemeInLogin, .usemeInLogout: return "authenticationAccessIdApi"
}
}
}
Its a bit hard without context, but I'd suggest using simple enum for use case differentiation:
enum MyType: String {
case usemeInLogin
case usemeInLogout
}
And if needed, have a map from this enum to String, like:
var map: [MyType:String] = [:]
map[.usemeInLogin] = "something"
map[.usemeInLogout] = "something"
I'm trying to use enum to classify items. As such, I've ended up with having enums inside of enums. And I'm not entirely sure on how this whole enum thing works.
But what I want to do is tap into the enum MaterialClassification, and then if theres a second enum, like in case clay, tap into that enum's value to return it as a string.
enum MaterialClassification {
case clay(value: Clay)
case flux//(value: Fluxs)
case glassFormer
case stain//(value: Clay)
case accessoryMaterial
case all//(value: Clay)
}
extension MaterialClassification {
var materiaIdentifier: String {
switch self {
case .clay:
return "clay"
case .flux:
return "flux"
case .glassFormer:
return "glassFormer"
case .stain:
return "stain"
case .accessoryMaterial:
return "accessoryMaterial"
case .all:
return "all"
}
}
}
enum Clay {
case iskaolin// = "Kaolin"
case isPrimaryKaolin// = "Primary Kaolin"
case isSecondaryKaolin //= "Secondary Kaolin"
case isBallClay //= "Ball Clay"
case isStoneware// = "Stoneware"
case isFireClay //= "Fire Clay"
case isEarthenware// = "Earthenware"
case isVolcanicClay// = "Volcanic"
}
extension Clay {
var clayType: String {
switch self {
case .iskaolin:
return "Kaolin"
case .isPrimaryKaolin:
return "Primary Kaolin"
case .isSecondaryKaolin:
return "Secondary Kaolin"
case .isBallClay:
return "Ball Clay"
case .isStoneware:
return "Stoneware"
case .isFireClay:
return "Fire Clay"
case .isEarthenware:
return "Earthenware"
case .isVolcanicClay:
return "Volcanic Clay"
}
}
}
My goal is to be able to return the nested string when needed. For example:
materialClassification: MaterialClassification.clay(type: Clay.isPrimaryKaolin)
I need a way to return "Primary Kaolin". But I can't figure out how to connect the 2 enums.
If I understand your question correctly, you want to access associated types' properties. You can add a new property to your MaterialClassification enum and use it to access your cases.
Something like this should work
var type: String? {
switch self {
case .clay(let clay):
return clay.clayType
case .flux(let flux):
return flux.fluxType
case .stain(let stain):
return stain.stainType
case .glassFormer, .accessoryMaterial, .all:
return nil
}
}
As per documentation and this thread, among others, for an enum of Ints I can print the case name as a string by simply doing this:
enum TestEnum: Int {
case one
case two
case three
}
let testEnum = TestEnum.two
print(testEnum)
// prints "two"
Which works of course. But if I try to do the same thing with CKAccountStatus, it prints the name of the enum:
import CloudKit
let testStatus = CKAccountStatus.noAccount
print(testStatus)
// prints "CKAccountStatus"
CKAccountStatus is an enum of Ints, just like the test enum above:
public enum CKAccountStatus : Int {
case couldNotDetermine
case available
case restricted
case noAccount
}
What am I doing wrong and/or why is this happening?
Your TestEnum is a swift enum. CKAccountStatus could be Objective C enum.
You can achieve it by confirming the CustomStringConvertible protocol by adding:
extension CKAccountStatus: CustomStringConvertible {
public var description: String {
switch self {
case .noAccount:
return "noAccount"
case .available:
return "available"
case .restricted:
return "restricted"
case .couldNotDetermine:
return "couldNotDetermine"
}
}
}
let testStatus = CKAccountStatus.available
print(testStatus) // available
I've got an enum in Swift. It's kind of like
enum LegalArgs {
case AsString(String)
case AsBool(Bool)
... etc
}
I want to access this enum conditionally by type. So if I have an instance of LegalArgs, I can pass T and get back a T? if the instance was of that type. Otherwise I will have to duplicate a bunch of code for different cases.
My current code looks a bit like this:
String? maybeAsString(arg: LegalArgs) {
switch arg {
case .AsString(let str):
return str;
default:
return nil;
}
}
The problem is that I've got to duplicate this function for every case in the enum.
You can use a generic asType function:
enum LegalArgs {
case AsString(String)
case AsBool(Bool)
case AsNumber(Int)
func asType<T>(type: T.Type) -> T? {
switch self {
case AsString(let str): return str as? T
case AsBool(let bol): return bol as? T
case AsNumber(let num): return num as? T
}
}
}
// usage
LegalArgs.AsBool(true).asType(Bool.self) // true
LegalArgs.AsBool(true).asType(String.self) // nil
I need to convert an enum to a string, using this variable:
var bloodType:HKBloodTypeObject? = healthKitStore.bloodTypeWithError(&error);
And this enum:
enum HKBloodType : Int {
case NotSet
case APositive
case ANegative
case BPositive
case BNegative
case ABPositive
case ABNegative
case OPositive
case ONegative
}
I know that there are other questions similar to this, but I haven't found any answers that worked for me.
As simple description: the HKBloodTypeObject as wrapper of HKBloodType parameter that is in the HealthKit storage.
extension HKBloodTypeObject {
func string()->String {
switch self.bloodType {
case .abNegative:
return "AB-"
case .abPositive:
return "AB+"
case .aNegative:
return "A-"
case .aPositive:
return "A+"
case .bNegative:
return "B-"
case .bPositive:
return "B+"
case .oNegative:
return "O-"
case .oPositive:
return "O+"
default:
return "Not Set"
}
}
}
the best way to use this extension of HKBloodType enum.
Hope lines of code above 'll help you.
Create a en extension to HKBloodType that implements CustomStringConvertible (Printable for Swift < 2), see here: https://stackoverflow.com/a/24707744/335974