Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Created March 5, 2012 09:54
Show Gist options
  • Save oleksii-demedetskyi/1977683 to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/1977683 to your computer and use it in GitHub Desktop.
ParamGenerator
//
// ParamBuilder.h
// Petbox
//
// Created by Алексей Демедецкий on 02.03.12.
// Copyright (c) 2012 Ciklum. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ParamBuilder : NSObject
- (NSDictionary*)buildDictionary;
@end
//
// ParamBuilder.m
// Petbox
//
// Created by Алексей Демедецкий on 02.03.12.
// Copyright (c) 2012 Ciklum. All rights reserved.
//
#import "ParamBuilder.h"
@interface ParamBuilder()
@property (nonatomic, readonly) NSMutableDictionary* dict;
@end
static NSString *PropertyNameFromSetter(NSString *setterName)
{
setterName = [setterName substringFromIndex:3]; // Remove "set"
NSString *firstChar = [[setterName substringToIndex:1] lowercaseString];
NSString *tail = [setterName substringFromIndex:1];
tail = [tail substringToIndex:[tail length] - 1]; // Remove ":"
return [firstChar stringByAppendingString:tail]; // Convert first char to lowercase.
}
static id DynamicDictionaryGetter(id self, SEL _cmd)
{
ParamBuilder* _self = self;
return [_self.dict objectForKey:NSStringFromSelector(_cmd)];
}
static void DynamicDictionarySetter(id self, SEL _cmd, id value)
{
ParamBuilder* _self = self;
NSString *key = PropertyNameFromSetter(NSStringFromSelector(_cmd));
if (value == nil)
{
[_self.dict removeObjectForKey:key];
}
else
{
[_self.dict setObject:value forKey:key];
}
}
@implementation ParamBuilder
objection_register(ParamBuilder);
@synthesize dict = _dict;
- (id)init
{
self = [super init];
if (self) {
_dict = [NSMutableDictionary dictionary];
}
return self;
}
- (NSDictionary *)buildDictionary
{
return [self.dict copy];
}
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
NSString *selStr = NSStringFromSelector(sel);
// Only handle selectors beginning with "set", ending with a colon and with no intermediate colons.
// Also, to simplify PropertyNameFromSetter, we requre a length of at least 5 (2 + "set").
if ([selStr rangeOfString:@":"].location == NSNotFound)
{
DLog(@"Generating dynamic accessor -%@", selStr);
return class_addMethod(self, sel, (IMP)DynamicDictionaryGetter, @encode(id(*)(id, SEL)));
}
if ([selStr hasPrefix:@"set"] &&
[selStr hasSuffix:@":"] &&
[selStr rangeOfString:@":" options:0 range:NSMakeRange(0, [selStr length] - 1)].location == NSNotFound &&
[selStr length] >= 6)
{
DLog(@"Generating dynamic accessor -%@ for property \"%@\"",
selStr, PropertyNameFromSetter(selStr));
return class_addMethod(self, sel, (IMP)DynamicDictionarySetter, @encode(id(*)(id, SEL, id)));
}
else
{
return [super resolveInstanceMethod:sel];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment