Skip to content

Instantly share code, notes, and snippets.

@daltonclaybrook
Last active September 23, 2017 03:45
Show Gist options
  • Save daltonclaybrook/df67ace8511e948baf0c to your computer and use it in GitHub Desktop.
Save daltonclaybrook/df67ace8511e948baf0c to your computer and use it in GitHub Desktop.
//
// MOPModel.m
// MormonPanus
//
// Created by Dalton Claybrook on 8/29/14.
// Copyright (c) 2014 Space Factory Studios. All rights reserved.
//
#import "MOPModel.h"
#import <objc/runtime.h>
@implementation MOPModel
#pragma mark - Initializers
+ (NSArray *)modelsFromCloudModels:(NSArray *)models
{
NSMutableArray *newModels = [NSMutableArray arrayWithCapacity:models.count];
for (id<MOPCloudModel> model in models)
{
MOPModel *newModel = [[self alloc] initWithCloudModel:model];
[newModels addObject:newModel];
}
return [newModels copy];
}
- (instancetype)initWithCloudModel:(id<MOPCloudModel>)model
{
self = [super init];
if (self)
{
[self updateValuesWithModel:model];
}
return self;
}
#pragma mark - NSObject
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
// no-op. prevents exceptions.
NSLog(@"key: %@ does not exist. value: %@", key, value);
}
#pragma mark - Public
- (NSString *)modifiedKeyForKey:(NSString *)key
{
return key;
}
#pragma mark - Private
- (void)updateValuesWithModel:(id<MOPCloudModel>)model
{
for (NSString *key in [model allKeys])
{
NSString *modKey = [self modifiedKeyForKey:key];
id value = model[key];
if ([self propertyTypeMatchesForKey:modKey value:value])
{
[self setValue:value forKey:modKey];
}
}
}
- (BOOL)propertyTypeMatchesForKey:(NSString *)key value:(id)value
{
BOOL matches = NO;
objc_property_t property = class_getProperty([self class], [key cStringUsingEncoding:NSASCIIStringEncoding]);
if (property != NULL)
{
const char *attr = property_getAttributes(property);
NSString *attrString = [NSString stringWithCString:attr encoding:NSASCIIStringEncoding];
NSArray *components = [attrString componentsSeparatedByString:@","];
for (NSString *component in components)
{
if (component.length > 1 && [[component substringToIndex:1] isEqualToString:@"T"])
{
NSScanner *scanner = [NSScanner scannerWithString:component];
[scanner scanUpToString:@"\"" intoString:NULL];
[scanner scanString:@"\"" intoString:NULL];
NSString *pName = nil;
[scanner scanUpToString:@"\"" intoString:&pName];
Class class = NSClassFromString(pName);
if (class && [value isKindOfClass:class])
{
matches = YES;
}
break;
}
}
}
return matches;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment