Skip to content

Instantly share code, notes, and snippets.

@jakehawken
Last active July 3, 2016 04:28
Show Gist options
  • Save jakehawken/79d8d5d28546ace743bca4c8160f36b5 to your computer and use it in GitHub Desktop.
Save jakehawken/79d8d5d28546ace743bca4c8160f36b5 to your computer and use it in GitHub Desktop.
An auto-mapper for inflating custom data objects from a given NSDictionary. This is a highly dangerous / unsafe category on NSObject, mainly done just as a fun exercise to see if it could be done. Can't say I recommend you use it.
@implementation NSObject (DataMapping)
- (instancetype)initByAutoMappingFromDictionary:(NSDictionary *)dictionary
{
Class thisClass = [self class];
self = [thisClass init];
if (self)
{
[self mapDictionaryValues:dictionary];
}
return self;
}
- (void)mapDictionaryValues:(NSDictionary *)dictionary
{
NSArray *dictKeys = [dictionary allKeys];
for (NSString *key in dictKeys)
{
[self attemptToSetPropertyWithObject:dictionary[key] forKey:key];
}
}
#pragma - mark private / helper methods
- (void)attemptToSetPropertyWithObject:(NSObject *)object forKey:(NSString *)key
{
SEL selectorFromString = [self setterSelectorFromKeyString:key];
if ([self respondsToSelector:selectorFromString])
{
[self performSelector:selectorFromString withObject:object];
}
}
- (SEL)setterSelectorFromKeyString:(NSString *)inputString
{
NSString *capitalizedString = [inputString capitalizedString];
NSString *selectorString = [NSString stringWithFormat:@"set%@:", capitalizedString];
return NSSelectorFromString(selectorString);
}
@end
@jakebromberg
Copy link

jakebromberg commented Jul 1, 2016

Shouldn't you call self = [super init] in your initializer? In fact, you don't want to call +alloc again because your object is already allocated.

@jakebromberg
Copy link

jakebromberg commented Jul 1, 2016

I see you're stripping out spaces. What is the goal of your method? Isn't the onus on the caller to provide valid inputs? There's a whole host of invalid characters (including the +[NSCharacterSet whitespaceCharacterSet]) the caller could provide. Are you sure accounting for these rules is something you want to take the burden of?

@jakehawken
Copy link
Author

Shouldn't you call self = [super init] in your initializer? In fact, you don't want to call +alloc again because your object is already allocated.

Very good point.

@jakehawken
Copy link
Author

I see you're stripping out spaces. What is the goal of your method? Isn't the onus on the caller to provide valid inputs? There's a whole host of invalid characters (including the +[NSCharacterSet whitespaceCharacterSet]) the caller could provide. Are you sure accounting for these rules is something you want to take the burden of?

Also a great point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment