views:

73

answers:

4

I am attempting to instantiate classes from different XML sources. The cases of the class names are inconsistent (camel, upper, lower) across these sources. Does an equivalent to NSClassFromString exist for this? For example, something allowing for:

Person *person = [[NSClassFromCaseInsensitiveString("Person") alloc] init];
Person *person = [[NSClassFromCaseInsensitiveString("person") alloc] init];
Person *person = [[NSClassFromCaseInsensitiveString("PERSON") alloc] init];
+5  A: 

make a NSString case insensitive by using any of the capitalization methods in NSString (-capitalizedString for instance) then use it as the param for NSClassFromString

Edit: here is code based on your Person example. (Assuming stringFromXML is a NSString that you parsed from your XML code that could contain any form of the word "person"

NSString *personString = stringFromXML;
Person *person = NSClassFromString([personString capitalizedString]);
Jesse Naugher
this will only work as long as you don't have camelCased class names
cobbal
yes i agree, and if that is the case, your answer is the only viable solution. I didn't see the mention of Camel and assumed from the example it would be simple names :)
Jesse Naugher
Thanks Jesse. However, I do need to support camel cased class names. Appreciate the answer though!
Kevin Sylvestre
+3  A: 

You're probably stuck with searching the class list, obtainable from objc_getClassList

cobbal
Thanks, I guess I'll have to write my own case insensitive matcher.
Kevin Sylvestre
+1  A: 

You could use the NSString capitalization methods, if you are guaranteed that the class name will look like that. A general function as you describe is not available, and likely won't be, for the simple reason that class names are not case insensitive.

@interface Person : NSObject  
{ 

} 

@end 

@interface PERSON : NSObject
{

}

@end

will work and declare two different class types. Though in all honesty, having classes with identical names except case would just be bad style in the first place.

bobDevil
+3  A: 

Please don't do this. You're letting arbitrary (I'm assuming downloaded-over-HTTP) XML instantiate arbitrary classes in your app. This is bad, and it's difficult to know how bad because it can instantiate any class loaded in your app (including ones in private frameworks).

Consider using something like

NSDictionary * classesByLowercaseString = [NSDictionary dictionaryWithObjectsAndKeys:
  [Person class], @"person",
  [Blah class[, @"blah",
  nil];
[classesByLowercaseString objectForKey:[xmlClassName lowercaseString]];

Also note that XML tag names are supposed to be case-sensitive.

tc.
+1 for security note here. Scope the list of possible model classes explicitly.
quixoto
+1 really is the best way to go
cobbal