I’m trying to log an enum:
enum CKAccountStatus : Int {
case CouldNotDetermine
case Available
case Restricted
case NoAccount
}
NSLog("%i", CKAccountStatus.Available)
The compiler complains:
Type 'CKAccountStatus' does not conform to protocol 'CVarArg'
Why? I have tried to cast the value:
NSLog("%i", CKAccountStatus.Available as Int)
But that doesn’t fly either:
Cannot convert the expression's type '()' to type 'String'
Yes, enums can conform protocols. You can use Swift's own protocols or custom protocols. By using protocols with Enums you can add more capabilities.
Swift's Enum can have methods. It can have instance methods and you can use it to return expression value for the UI. Let's look at the code above. I defined a string array named marriedStrings using the fireprivate access limiter.
In Swift language, we have Structs, Enum and Classes. Struct and Enum are passed by copy but Classes are passed by reference. Only Classes support inheritance, Enum and Struct don't.
In Swift, we can also assign values to each enum case. For example, enum Size : Int { case small = 10 case medium = 12 ... } Here, we have assigned values 29 and 31 to enum cases small and medium respectively.
Get the enum's underlying Int
value:CKAccountStatus.Available.rawValue
.
Enums are not strictly integers in Swift, but if they're declared with an underlying type you can get it with rawValue
— whatever that underlying type is. (enum Foo: String
will give you strings for the rawValue
, etc.) If an enum doesn't have an underlying type, rawValue
has nothing to give you. In APIs imported from ObjC, any enum defined with NS_ENUM
has an underlying integer type (typically Int
).
If you'd like to print any enum more descriptively, you might consider making an extension on the enum type that adopts the Printable
protocol.
An enum is effectively opaque. It might have raw values, which you can get; but many enums don't. (You don't have to declare the enum as having a type, and if you don't, there are no raw values.) What I would do is give the enum a description
method and call it explicitly.
The only way to distinguish the enum's current value is through a switch statement, so your description
method will handle each case, and each case of the switch statement will return a different descriptive value.
enum Suit {
case Hearts, Diamonds, Spades, Clubs
func description () -> String {
switch self {
case Hearts:
return "hearts"
case Diamonds:
return "diamonds"
case Spades:
return "spades"
case Clubs:
return "clubs"
}
}
}
var suit = Suit.Diamonds
println("suit \(suit.description())") // suit diamonds
This is my approach:
enum UserMode : String
{
case Hold = "Hold";
case Selecting = "Selecting";
case Dragging = "Dragging";
}
Then, whenever I need to print the raw value:
//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;
Doing
NSLog("CurrentMode \(_currMode.rawValue)");
Will print:
CurrentMode Selecting
From the Swift docs:
If you are familiar with C, you will know that C enumerations assign related names to a set of integer values. Enumerations in Swift are much more flexible, and do not have to provide a value for each member of the enumeration. If a value (known as a “raw” value) is provided for each enumeration member, the value can be a string, a character, or a value of any integer or floating-point type.
Therefore you cannot try to cast it to and Int. As far as your first problem it seems that NSLog()
is looking for a parameter of type C-variable, which does not apply to Swift enums.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With