Skip to content

Instantly share code, notes, and snippets.

@erikkerber
Last active August 29, 2015 13:56
Show Gist options
  • Save erikkerber/9086494 to your computer and use it in GitHub Desktop.
Save erikkerber/9086494 to your computer and use it in GitHub Desktop.
/*
* Example usage
*
* id<MyProtocol> mockProtocol = [DynamicObject new];
*
* mockProtocol.mockProperty = SomeEnum;
* mockProtocol.mockString = @"Foo";
*
*/
#import "DynamicObject.h"
#import <objc/runtime.h>
@interface DynamicObject()
@property (nonatomic, strong) NSMutableDictionary *properties;
@end
@implementation DynamicObject
- (instancetype)init
{
self = [super init];
if (self) {
_properties = [NSMutableDictionary dictionary];
}
return self;
}
- (void)dealloc
{
self.properties = nil;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [[self class] instanceMethodSignatureForSelector:@selector(foo:)];
}
- (id)foo:(id)key
{
return self.properties[key];
}
- (void)setFoo:(id)key value:(id)value
{
self.properties[key] = value;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
__unsafe_unretained id argument;
[anInvocation getArgument:&argument atIndex:2];
if (argument) {
NSString *setterName = NSStringFromSelector(anInvocation.selector);
NSRange range = NSMakeRange(3, [setterName length]-4);
NSString *propertyName = [setterName substringWithRange:range];
propertyName = [NSString stringWithFormat:@"%@%@",[[propertyName substringToIndex:1] lowercaseString],[propertyName substringFromIndex:1]];
NSMethodSignature *signature = [anInvocation methodSignature];
const char* argType = [signature getArgumentTypeAtIndex:2];
#pragma message ("Holy hack batman. It is freaking hard to determine if the argument is a primitive (enum)")
if ((NSInteger)argument < 10) {
BOOL o = [argument respondsToSelector:@selector(isKindOfClass:)];
argument = @((NSInteger)argument);
}
[self performSelector:@selector(setFoo:value:) withObject:propertyName withObject:argument];
} else {
[self performSelector:@selector(foo:) withObject:argument];
}
}
- (id)valueForKey:(NSString *)key
{
return self.properties[key];
}
- (void)setValue:(id)value forKey:(NSString *)key
{
self.properties[key] = value;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment