Neil Edwards
Neil Edwards

Reputation: 227

Find an integer value in Objective-C enum

Is it possible in Objective-C to see if a int value is in a particular enum? For instance, in this enum:

enum  {
  ValidationLoginFailed         = 2000,
  ValidationSessionTokenExpired = 2001,
  ValidationSessionTokenInvalid = 2002,
  ValidationEmailNotFound       = 2003  
}; 
typedef int ValidationStatusCodes;

is it possible to see if an arbitrary integer value is in the ValidationStatusCodes enum?

[ValidationStatusCodes contains:intResponseCode]

or at least

[self intIsInRangeofEnum:ValidationStatusCodes forValue:intResponseCode]

Upvotes: 7

Views: 19862

Answers (5)

jaysqrd
jaysqrd

Reputation: 375

This question is a little dated, but the standard I have seen in software design is to use a bitmask where each of these values is a discrete state with a bit-shift. In some cases, your enum values can be combinations of other values.

enum  {
  ValidationLoginFailed         = 0, //0
  ValidationSessionTokenExpired = 1 << 0, //1
  ValidationSessionTokenInvalid = 1 << 1, //2
  ValidationEmailNotFound       = 1 << 2  //4
}; 
typedef int ValidationStatusCodes;

For your use-case you would & your result with all of the items in the set:

int allStates = (ValidationLoginFailed | ValidationSessionTokenExpired | 
   ValidationSessionTokenInvalid | ValidationEmailNotFound); //7

if(val & allStates){
   //some logic here
}

Upvotes: 1

kovpas
kovpas

Reputation: 9593

Well, as long as this question is up again. There's a nice open source project JREnum

Which allows to do the following thing:

JREnumDeclare( ValidationStatusCodes,
  ValidationLoginFailed         = 2000,
  ValidationSessionTokenExpired = 2001,
  ValidationSessionTokenInvalid = 2002,
  ValidationEmailNotFound       = 2003  
); 

And then ValidationStatusCodesByValue() returns NSDictionary which keys are corresponding NSNumbers. So:

if ([ValidationStatusCodesByValue() objectForKey:@(intResponseCode)])
    ...

Upvotes: 0

Chuck
Chuck

Reputation: 237010

There's no simpler way than just doing

(ValidationLoginFailed == intResponseCode ||
ValidationSessionTokenExpired == intResponseCode ||
ValidationSessionTokenInvalid == intResponseCode ||
ValidationEmailNotFound == intResponseCode)

In general, C is not very helpful for doing dynamic things or reflecting on types, and enums are a C feature.

Upvotes: 9

Neil Edwards
Neil Edwards

Reputation: 227

[UPDATE]

Found this method in some C++ posts which, although not entirely dynamic, does the trick with minimal fuss:

Add range extents to enum entries:

enum  {
  ValidationLoginFailed=2000,
  ValidationSessionTokenExpired=2001,
  ValidationSessionTokenInvalid=2002,
  ValidationEmailNotFound=2003
  ValidationSucccesMIN=ValidationLoginFailed,
  ValidationSucccesMAX=ValidationEmailNotFound,
  ValdationValidSuccessCode=9999,
  ValdationInvalidCode=10000

}; 
typedef int ValidationStatusCodes;

then something along these lines:

-(ValidationStatusCodes)isReponseCodeValid{

for (int i=ValidationSucccesMIN; i<=ValidationSucccesMAX; i++) {
    if(returnCode==i){
        return ValdationValidSuccessCode;
    }
}

return ValdationInvalidCode;
}

obviously there are far more than just these 4 codes in the final app and there will a block of corresponding error ones too.

Upvotes: -3

David Gelhar
David Gelhar

Reputation: 27900

Not with an enum. An enum is not an objective-C object, so you can't send it messages as you're doing.

Maybe use an NSDictionary?

Upvotes: 3

Related Questions