Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging a Swift enum using NSLog

Tags:

swift

nslog

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'
like image 977
zoul Avatar asked Jun 05 '14 13:06

zoul


People also ask

Can enum conform to Swift protocol?

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.

Can Swift enums have methods?

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.

Can enum be inherited Swift?

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.

How do I enum in Swift?

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.


4 Answers

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.

like image 72
rickster Avatar answered Oct 18 '22 20:10

rickster


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
like image 21
matt Avatar answered Oct 18 '22 21:10

matt


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

like image 5
Chris Amelinckx Avatar answered Oct 18 '22 21:10

Chris Amelinckx


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.

like image 1
67cherries Avatar answered Oct 18 '22 22:10

67cherries