enum Values to NSString (iOS)

前端 未结 16 1893
悲&欢浪女
悲&欢浪女 2020-12-04 07:57

I have an enum holding several values:

enum {value1, value2, value3} myValue;

In a certain point in my app, I wish to check which value of

相关标签:
16条回答
  • 2020-12-04 08:05

    Suppose requirement is to enumerate list of languages.

    Add this to .h file

    typedef NS_ENUM(NSInteger, AvailableLanguage) {
      ENGLISH,
      GERMAN,
      CHINENSE
    };
    

    Now, in .m file simply create an array like,

    // Try to use the same naming convention throughout. 
    // That is, adding ToString after NS_ENUM name;
    
    NSString* const AvailableLanguageToString[] = {
      [ENGLISH] = @"English",
      [GERMAN]  = @"German",
      [CHINESE] = @"Chinese"
    };
    

    Thats it. Now you can use enum with easy and get string for enums using array. For example,

    - (void) setPreferredLanguage:(AvailableLanguage)language {
      // this will get the NSString* for the language.
      self.preferredLanguage = AvailableLanguageToString[language];
    }
    

    Thus, this pattern depends on accepted naming convention of NS_ENUM and companion ToString array. Try to follow this convention through out and it will become natural.

    0 讨论(0)
  • 2020-12-04 08:06

    The solution below uses the preprocessor's stringize operator, allowing for a more elegant solution. It lets you define the enum terms in just one place for greater resilience against typos.

    First, define your enum in the following way.

    #define ENUM_TABLE \
    X(ENUM_ONE),    \
    X(ENUM_TWO)    \
    
    #define X(a)    a
    typedef enum Foo {
        ENUM_TABLE
    } MyFooEnum;
    #undef X
    
    #define X(a)    @#a
    NSString * const enumAsString[] = {
        ENUM_TABLE
    };
    #undef X
    

    Now, use it in the following way:

    // Usage
    MyFooEnum t = ENUM_ONE;
    NSLog(@"Enum test - t is: %@", enumAsString[t]);
    
    t = ENUM_TWO;
    NSLog(@"Enum test - t is now: %@", enumAsString[t]);
    

    which outputs:

    2014-10-22 13:36:21.344 FooProg[367:60b] Enum test - t is: ENUM_ONE
    2014-10-22 13:36:21.344 FooProg[367:60b] Enum test - t is now: ENUM_TWO
    

    @pixel's answer pointed me in the right direction.

    0 讨论(0)
  • 2020-12-04 08:09

    Below is a example of Enum Struct that is Objective-C friendly in the event you need to use Swift Code in Legacy projects written in Objective-C.

    Example:

    contentType.filename. toString()

    returns "filename"


    contentType.filename. rawValue

    returns the Int Value, 1 (since its the second item on struct)

    @objc enum contentType:Int {
    
        //date when content was created [RFC2183]
        case creationDate
    
        //name to be used when creating file    [RFC2183]
        case filename
    
        //whether or not processing is required [RFC3204]
        case handling
    
        //date when content was last modified   [RFC2183]
        case modificationDate
    
        //original field name in form   [RFC7578]
        case name
    
        //Internet media type (and parameters) of the preview output desired from a processor by the author of the MIME content [RFC-ietf-appsawg-text-markdown-12]
        case previewType
    
        //date when content was last read   [RFC2183]
        case readDate
    
        //approximate size of content in octets [RFC2183]
        case size
    
        //type or use of audio content  [RFC2421]
        case voice
    
        func toString() -> String {
            switch self {
            case .creationDate:
                return "creation-date"
            case .filename:
                return "filename"
            case .handling:
                return "handling"
            case .modificationDate:
                return "modification-date"
            case .name:
                return "name"
            case .previewType:
                return "preview-type"
            case .readDate:
                    return "read-date"
            case .size:
                return "size"
            case .voice:
                return "voice"
            }
        }//eom
    }//eo-enum
    
    0 讨论(0)
  • 2020-12-04 08:11

    You could use X macros - they are perfect for this.

    Benefits 1. the relationship between the actual enum value and the string value is in one place. 2. you can use regular switch statements later in your code.

    Detriment 1. The initial setup code is a bit obtuse, and uses fun macros.

    The code

    #define X(a, b, c) a b,
    enum ZZObjectType {
        ZZOBJECTTYPE_TABLE
    };
    typedef NSUInteger TPObjectType;
    #undef X
    
    #define XXOBJECTTYPE_TABLE \
    X(ZZObjectTypeZero, = 0, "ZZObjectTypeZero") \
    X(ZZObjectTypeOne, = 1, "ZZObjectTypeOne") \
    X(ZZObjectTypeTwo, = 2, "ZZObjectTypeTwo") \
    X(ZZObjectTypeThree, = 3, "ZZObjectTypeThree") \
    
    + (NSString*)nameForObjectType:(ZZObjectType)objectType {
    #define X(a, b, c) @c, [NSNumber numberWithInteger:a],
        NSDictionary *returnValue = [NSDictionary dictionaryWithObjectsAndKeys:ZZOBJECTTYPE_TABLE nil];
    #undef X
        return [returnValue objectForKey:[NSNumber numberWithInteger:objectType]];
    }
    
    + (ZZObjectType)objectTypeForName:(NSString *)objectTypeString {
    #define X(a, b, c) [NSNumber numberWithInteger:a], @c,
        NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:ZZOBJECTSOURCE_TABLE nil];
    #undef X
        NSUInteger value = [(NSNumber *)[dictionary objectForKey:objectTypeString] intValue];
        return (ZZObjectType)value;
    }
    

    Now you can do:

    NSString *someString = @"ZZObjectTypeTwo"
    ZZObjectType objectType = [[XXObject objectTypeForName:someString] intValue];
    switch (objectType) {
        case ZZObjectTypeZero:
            //
            break;
        case ZZObjectTypeOne:
            //
            break;
        case ZZObjectTypeTwo:
            //
            break;
    }
    

    This pattern has been around since the 1960's (no kidding!): http://en.wikipedia.org/wiki/X_Macro

    0 讨论(0)
  • 2020-12-04 08:11
    1. a macro:

      #define stringWithLiteral(literal) @#literal
      
    2. an enum:

      typedef NS_ENUM(NSInteger, EnumType) {
          EnumType0,
          EnumType1,
          EnumType2
      };
      
    3. an array:

      static NSString * const EnumTypeNames[] = {
          stringWithLiteral(EnumType0),
          stringWithLiteral(EnumType1),
          stringWithLiteral(EnumType2)
      };
      
    4. using:

      EnumType enumType = ...;
      NSString *enumName = EnumTypeNames[enumType];
      

    ==== EDIT ====

    Copy the following code to your project and run.

    #define stringWithLiteral(literal) @#literal
    
    typedef NS_ENUM(NSInteger, EnumType) {
        EnumType0,
        EnumType1,
        EnumType2
    };
    
    static NSString * const EnumTypeNames[] = {
        stringWithLiteral(EnumType0),
        stringWithLiteral(EnumType1),
        stringWithLiteral(EnumType2)
    };
    
    - (void)test {
        EnumType enumType = EnumType1;
        NSString *enumName = EnumTypeNames[enumType];
        NSLog(@"enumName: %@", enumName);
    }
    
    0 讨论(0)
  • 2020-12-04 08:13

    If I can offer another solution that has the added benefit of type checking, warnings if you are missing an enum value in your conversion, readability, and brevity.

    For your given example: typedef enum { value1, value2, value3 } myValue; you can do this:

    NSString *NSStringFromMyValue(myValue type) {
        const char* c_str = 0;
    #define PROCESS_VAL(p) case(p): c_str = #p; break;
        switch(type) {
                PROCESS_VAL(value1);
                PROCESS_VAL(value2);
                PROCESS_VAL(value3);
        }
    #undef PROCESS_VAL
    
        return [NSString stringWithCString:c_str encoding:NSASCIIStringEncoding];
    }
    

    As a side note. It is a better approach to declare your enums as so:

    typedef NS_ENUM(NSInteger, MyValue) {
        Value1 = 0,
        Value2,
        Value3
    }
    

    With this you get type-safety (NSInteger in this case), you set the expected enum offset (= 0).

    0 讨论(0)
提交回复
热议问题