Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MisterSavage

macrumors 601
Original poster
Nov 10, 2018
4,860
5,761
If I create and print the contents of a simple enum it works as I would expect:

enum State : Int {

case noData

case loaded

}


state = .loaded

print("state is \(state)")​

That prints out "state is loaded".

But this statement doesn't work as I would expect:

print("self.traitCollection.userInterfaceIdiom is \(self.traitCollection.userInterfaceIdiom)")​

That prints out "self.traitCollection.userInterfaceIdiom is UIUserInterfaceIdiom". I'm confused why it isn't printing "phone", which it actually is set to. If I checked if "self.traitCollection.userInterfaceIdiom == .phone" that returns true. userInterfaceIdiom is defined as a UIUserInterfaceIdiom, which is an enum. So why is it printing "UIUserInterfaceIdiom" instead of "phone"?
 

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
That's a great question; I'm going to explore this some more, but I would assume it has something to do with a direct reference like in your first example, versus a computed property maybe?
[doublepost=1555901908][/doublepost]Fascinatingly, if x is my userInterfaceIdiom, x.rawValue actually does print meaningful data, even though the enum object itself just prints the enum type. If you print the rawValue, you get 0 for phone, 1 for pad and presumably 2 for TV but untested; Weirdly 0 is used for phone - I would've expected 0 to be unspecified looking at the implementation. No clue what int unspecified would be set to then.

Unspecified is -1 which makes sense.
[doublepost=1555902601][/doublepost](I know I post a lot now but I'm experimenting as I write)

It seems having a variable with a getter function associated with a custom enum still prints the expected state value and not just the type; Odd indeed.
[doublepost=1555903318][/doublepost]I have found the answer!

Swift prints enum prettily like in your original case, if the enum is defined in Swift. UIUserInterfaceIdiom is originally implemented in Objective-C, so you'll need to write a protocol extension if you want pretty printing like that. Alternatively add in-code-location RawValue conversions.

Here's a StackOverflow article that to a certain degree talks about the same thing; There are some very relevant comments and some that are less so:

https://stackoverflow.com/questions...e-name-of-enumeration-value-in-swift/31893968
 
Last edited:
  • Like
Reactions: grandM

MisterSavage

macrumors 601
Original poster
Nov 10, 2018
4,860
5,761
Fascinatingly, if x is my userInterfaceIdiom, x.rawValue actually does print meaningful data, even though the enum object itself just prints the enum type. If you print the rawValue, you get 0 for phone, 1 for pad and presumably 2 for TV but untested; Weirdly 0 is used for phone - I would've expected 0 to be unspecified looking at the implementation. No clue what int unspecified would be set to then.

Yes!! This is actually what screwed me up. I actually thought the code wasn't working because I expected unspecified to be zero. It wasn't until later that I tried a conditional where 'trait == phone' and found that it worked.

I found this in the documentation that made it more clear to me: "Swift enumeration cases don’t have an integer value set by default, unlike languages like C and Objective-C. In the CompassPoint example above, north, south, east and west don’t implicitly equal 0, 1, 2 and 3. Instead, the different enumeration cases are values in their own right, with an explicitly defined type of CompassPoint."

Swift prints enum prettily like in your original case, if the enum is defined in Swift. UIUserInterfaceIdiom is originally implemented in Objective-C, so you'll need to write a protocol extension if you want pretty printing like that. Alternatively add in-code-location RawValue conversions.

Thank you so much for looking into this and explaining it to me. I was baffled why it wasn't working. I don't need it printed nice now that I know it works, but it was bothering me that I didn't understand why.
 

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
I found this in the documentation that made it more clear to me: "Swift enumeration cases don’t have an integer value set by default, unlike languages like C and Objective-C. In the CompassPoint example above, north, south, east and west don’t implicitly equal 0, 1, 2 and 3. Instead, the different enumeration cases are values in their own right, with an explicitly defined type of CompassPoint."

Hmmm. Yes, but the " : Int" part gives it a rawValue of Int that is automatically incremented. I'm assuming that the reason it doesn't increment starting from 0 is because it is explicitly initialised at -1 in the Obj-C implementation, and that part just becomes invisible in the Swift shim we looked at.

Thank you so much for looking into this and explaining it to me. I was baffled why it wasn't working. I don't need it printed nice now that I know it works, but it was bothering me that I didn't understand why.

You're welcome . Baffled me at first too, and well, when code does that I do get a bit obsessed with figuring out why. If someone asked a question very specific to brain**** or similarly esoteric language that I neither have n'or want to get into I wouldn't research it cause I don't care enough, but this was a learning experience for me as well so we both won from it :). This is why it can be good to sometimes try and answer questions you don't know the answer to too - You might wind up learning something.
 
  • Like
Reactions: MisterSavage

MisterSavage

macrumors 601
Original poster
Nov 10, 2018
4,860
5,761
Hmmm. Yes, but the " : Int" part gives it a rawValue of Int that is automatically incremented.
Again yes!!! Normally I don't even specify the " : Int" when I create an enum but since they specifically did I was expecting them to start at zero.

You're welcome . Baffled me at first too, and well, when code does that I do get a bit obsessed with figuring out why. If someone asked a question very specific to brain**** or similarly esoteric language that I neither have n'or want to get into I wouldn't research it cause I don't care enough, but this was a learning experience for me as well so we both won from it :). This is why it can be good to sometimes try and answer questions you don't know the answer to too - You might wind up learning something.

I could have just let it go but I was really curious as to why it worked that way. I was a little hesitant to post it because I thought it might be a stupid question!
 

casperes1996

macrumors 604
Jan 26, 2014
7,599
5,771
Horsens, Denmark
I could have just let it go but I was really curious as to why it worked that way. I was a little hesitant to post it because I thought it might be a stupid question!

Don't hesitate on the basis of fearing stupid questions. Even if it is stupid, not asking won't make you smarter ;). Plus, it's often more about the way you ask than the question itself - Stupid questions do exist, but what's worse is good questions asked in a stupid way cause it's just so frustrating to work with; Since your question style was rather good in this case, I don't think you really have to worry ;). So always just ask away
 
  • Like
Reactions: MisterSavage
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.