4 Replies
      Latest reply on Mar 14, 2019 3:32 AM by eskimo
      iOSDev2017 Level 1 Level 1 (0 points)

        Have a objc compatible enum as

        var str = "Hello, playground"

         

        @objc public enum TestEnum:Int{

            case String1

            case String2

        }

         

        let testValue = TestEnum.String1

         

        print( testValue) //prints TestEnum

        print(String(describing: testValue)) //prints TestEnum

         

        Is there a singleline statement that would print String1?

        I could get it working only by defining another function in TestEnum to return String as below:

         

        @objc public enum TestEnum:Int{

            case String1

            case String2

          

        public var name:String{

                get{

                    switch self {

                    case .String1:

                        return "String1"

                    default:

                        return "String2"

                    }

                }}

        }

         

        print( testValue.name) //prints String1

        • Re: Print Enum name of @objc Integer Enum
          Claude31 Level 8 Level 8 (5,775 points)

          It works in Swift

           

          public enum TestEnum: Int {
              case String1
              case String2
          }
          
          let testValue = TestEnum.String1

           

          print( testValue) //prints String1

          print(String(describing: testValue)) //prints String1

            • Re: Print Enum name of @objc Integer Enum
              iOSDev2017 Level 1 Level 1 (0 points)

              yes, Swift enum works as expctec.

              But need to have @objc Enum to support Xamarin platform.

              Is there a way for objective C compatible Enum like above?

                • Re: Print Enum name of @objc Integer Enum
                  Claude31 Level 8 Level 8 (5,775 points)

                  Interesting discussion here

                   

                  https://stackoverflow.com/questions/24113126/how-to-get-the-name-of-enumeration-value-in-swift/31893968

                   

                  But solution proposed should not work in Playground.

                   

                  Quote:

                  "

                  Important catch, this only works for Swift enums. If you tag it @objc to allow binding support on OS X, this will not work. – Claus Jørgensen Feb 4 '16 at 23:17

                   

                  Great Swift-specific answer; however, if you need to do this on a non-swift enum, such as to print the (Objective C) CLAuthorizationStatus enum's value inside your locationManager didChangeAuthorizationStatus delegate callback, you'd need to define a protocol extension. For example: extension CLAuthorizationStatus: CustomStringConvertable { public var description: String { switch self { case .AuthorizedAlways: return "AuthorizedAlways" <etc> } } } - once you've done this, it should work as you'd expect: print("Auth status: (\status))". – Jeffro Apr 27 '16 at 19:41

                  "

              • Re: Print Enum name of @objc Integer Enum
                eskimo Apple Staff Apple Staff (11,355 points)

                Is there a singleline statement that would print String1?

                No.  Under the covers, C enums are represented by integer values; the C runtime does not have a copy of the string representation.  For this to work in Swift, the Swift importer would have to generate these string representation and make them available to the Swift runtime.  It does not do that, probably for good reasons [1].

                Adding a conformance to CustomStringConvertable is one way to address this, but it’s not my preferred way.  There’s a general guidance in Swift that you should not conform a type you don’t ‘own’ to a protocol you don’t define.  That’s because there’s a potential for confusion if two subsystems within your process add conflicting conformances.

                I generally solve this problem by adding a custom property to the enum to return the description I want.  For example:

                import CoreLocation
                
                extension CLAuthorizationStatus {
                    var debug: String {
                        switch self {
                        case .notDetermined: return "not determined"
                        case .restricted: return "restricted"
                        case .denied: return "denied"
                        case .authorizedAlways: return "authorised always"
                        @unknown default: return "unknown \(self.rawValue)"
                        }
                    }
                }
                
                let s = CLAuthorizationStatus.authorizedAlways
                print(s.debug)

                Note that this use a Swift 5 feature (@unknown default) to handle the ‘framework added a new case’ situation.  See SE-0192 Handling Future Enum Cases for the details.

                Share and Enjoy

                Quinn “The Eskimo!”
                Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                let myEmail = "eskimo" + "1" + "@apple.com"

                [1] I suspect that the main concerne here is the amount of space used by these strings.  Apple’s SDKs contain a lot of enums.