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
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 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.
I want to declare a function which I can only use for a single specific enum case.
For example I have CustomTextFieldTypes enum. This has the following cases and functions.
enum CustomTextFieldTypes {
case CardType
case CardNumber
case CardExpiryDate
case CardName
case CCVNumber
func inputCardNumber(cardNumber: String!, cardNumberTextField: XCUIElement?) {
cardNumberTextField?.typeText(cardNumber)
}
func inputCardCCVNumber(cardCCVNumber: String!, cardCCVNumberTextField: XCUIElement?) {
cardCCVNumberTextField?.typeText(cardCCVNumber)
}
}
Now I want to call the inputCardNumber(...) function only for the CustomTextFieldTypes.CardNumber case. I can do the following...
CustomTextFieldTypes.CardNumber.inputCardNumber(...)
But at the same time I can do this...
CustomTextFieldTypes.CardExpiryDate.inputCardNumber(...) or
CustomTextFieldTypes.CardNumber.inputCardNumber(...)
I only want to call the inputCardNumber(...) function for the CardNumber case. Not from another case the enum itself. How do I achieve this?
Thanks in advance for any help
EDIT- Here's some background on what I'm doing. I was writing a UI test which would input text into text fields. I wanted to keep the input code away from my test file and I started "Experimenting" with enums and enum functions. I was wondering if I could have a function explicitly available for an enum case. Judging from the comments I cannot do this (I checked online but didn't get far). It's not a bad architecture or anything, I was just splitting up test code..
Thanks for everyone for replying.
You can perform a switch on self in order to execute certain code for certain cases. Here's an example:
enum CustomTextFieldTypes {
case cardType
case cardNumber
case cardExpiryDate
case cardName
case ccvNumber
func inputCardNumber(cardNumber: String!, cardNumberTextField: XCUIElement?) {
switch self {
case .cardNumber:
cardNumberTextField?.typeText(cardNumber)
default:
return
}
}
}
No need to use a switch when you only want to match a single case:
enum CustomTextFieldTypes {
case cardType
case cardNumber
case cardExpiryDate
case cardName
case ccvNumber
func inputCardNumber(cardNumber: String!, cardNumberTextField: XCUIElement?) {
if case .cardNumber = self {
cardNumberTextField?.typeText(cardNumber)
}
}
}
Dont know exactly why are XCUIElements needed but do something like this
//MARK: Declaration
enum CustomTextFieldTypes {
case CardType(String)
case CardNumber(String)
case CardExpiryDate(String)
case CardName(String)
case CCVNumber(String)
}
//MARK: Definition
var cardNumber = CustomTextFieldTypes.CardNumber("123")
var cardExpiry = CustomTextFieldTypes.CardExpiryDate("10-10-2016")
//MARK: Usage
func useCard(type: CustomTextFieldTypes)
{
switch type {
case .CardNumber(let numberString):
print(numberString)
case .CardType(let cardtype):
print(cardtype)
case .CardExpiryDate(let expiryDate):
print(expiryDate)
case .CardName(let name):
print(name)
case .CCVNumber(let ccvnumber):
print(ccvnumber)
}
}
useCard(cardNumber)
useCard(cardExpiry)
If you really neeed XCUIElement then change case CardType(String) to case CardType(String, XCUIElement) and update all the other code as well
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