Created
March 17, 2011 01:40
-
-
Save chadpod/873705 to your computer and use it in GitHub Desktop.
Django Piston -> HTTPRiot -> Core Data parser/converter. Was using this approach prior to moving over to RestKit framework (http://restkit.org/).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// HRObject.m | |
// | |
// Created by Chad Podoski on 11/23/09. | |
// Copyright 2009 Shacked Software. All rights reserved. | |
// | |
#import "HRObject.h" | |
#import "AppDelegate_Shared.h" | |
@interface HRObject (Private) | |
+ (void)populateObject:(id)object withDictionary:(NSDictionary *)dict; | |
+ (id)managedObjectForEntity:(NSString *)entity uuid:(NSString *)uuid; | |
@end | |
@implementation HRObject | |
+ (void)initialize { | |
[self setDelegate:self]; | |
[self setBaseURL:[NSURL URLWithString:SSBaseApiUrl]]; | |
[self setFormat:HRDataFormatJSON]; | |
//NSDictionary *params = [NSDictionary dictionaryWithObject:@"1234567" forKey:@"api_key"]; | |
//[self setDefaultParams:params]; | |
} | |
/** | |
* Called when the resource was succeffully fetched and encoded | |
* | |
* @param connection The connection object for the current request | |
* @param resource The converted objc representation of the response data returned by the server. | |
* @param object Any custom object you passed in while making the request. | |
*/ | |
+ (void)restConnection:(NSURLConnection *)connection didReturnResource:(id)resource object:(id)object { | |
/* Converts from the HTTPRiot model class to Core Data Model class and CRUD in managed object context */ | |
NSMutableSet *responseSet = [self convertToCoreData:resource]; | |
if (!IsEmpty(object) && [object respondsToSelector:@selector(httpRiotResponseReceived:)]) { | |
[object performSelector:@selector(httpRiotResponseReceived:) withObject:responseSet]; | |
} | |
} | |
/** | |
* Called when the connection receieves any type of response | |
* | |
* @param connection The connection object for the current request | |
* @param response The response object returned by the server. | |
* @param object Any custom object you passed in while making the request. | |
*/ | |
+ (void)restConnection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response object:(id)object { | |
NSLog(@"RESPONSE STATUS WAS:%i", [response statusCode]); | |
} | |
/** | |
* Called when the connection fails in situations where the server is not available, etc. | |
* | |
* @param connection The connection object for the current request | |
* @param error The error returned by the connection. | |
* @param object Any custom object you passed in while making the request. | |
*/ | |
+ (void)restConnection:(NSURLConnection *)connection didFailWithError:(NSError *)error object:(id)object { | |
AlertWithMessage([error localizedDescription]); | |
} | |
/** | |
* Called when the connection receieves a statusCode that isn't a success code. | |
* | |
* @param connection The connection object for the current request | |
* @param error The error returned by the connection. | |
* @param response The response object returned by the server. | |
* @param object Any custom object you passed in while making the request. | |
*/ | |
+ (void)restConnection:(NSURLConnection *)connection didReceiveError:(NSError *)error response:(NSHTTPURLResponse *)response object:(id)object { | |
AlertWithMessage([error localizedDescription]); | |
} | |
/** | |
* Called when the HRFormatter recieved an error parsing the response data. | |
* | |
* @param connection The connection object for the current request | |
* @param error The parser error returned by the formatter. | |
* @param body A string representation of the response body returned by the server. | |
* @param object Any custom object you passed in while making the request. | |
*/ | |
+ (void)restConnection:(NSURLConnection *)connection didReceiveParseError:(NSError *)error responseBody:(NSString *)body object:(id)object { | |
AlertWithMessage([error localizedDescription]); | |
} | |
#pragma mark - Core Data Methods | |
+ (NSMutableSet *)convertToCoreData:(id)resource { | |
NSMutableSet *result; | |
/* Determine if we are dealing with a single object or an array of objects */ | |
if ([resource isKindOfClass:[NSDictionary class]]) { | |
NSDictionary *dict = (NSDictionary *)resource; | |
NSString *entity = [dict valueForKey:SSEntityKey]; | |
NSString *uuid = [dict valueForKey:SSUuidKey]; | |
/* Make sure object an entity name and an uuid */ | |
if (!IsEmpty(entity) && !IsEmpty(uuid)) { | |
result = [NSMutableSet setWithCapacity:1]; | |
/* Class name needs to be prefixed with class prefix for this project */ | |
id object = [self managedObjectForEntity:entity uuid:uuid]; | |
// NSLog(@"******************************"); | |
// NSLog(@"BEFORE %@", object); | |
[self populateObject:object withDictionary:resource]; | |
// NSLog(@"------------------------------"); | |
// NSLog(@"AFTER %@", object); | |
[result addObject:object]; | |
} | |
}else if ([resource isKindOfClass:[NSArray class]]) { | |
result = [NSMutableSet setWithCapacity:[(NSArray *)resource count]]; | |
for (id object in resource) { | |
[result unionSet:[self convertToCoreData:object]]; | |
} | |
} | |
return result; | |
} | |
+ (void)populateObject:(id)object withDictionary:(NSDictionary *)dict { | |
NSArray *keys = [dict allKeys]; | |
for (NSString *key in keys) { | |
id value = [dict valueForKey:key]; | |
key = [key capitalizedString]; | |
key = [key stringByReplacingOccurrencesOfString:@"_" withString:@""]; | |
/* An NSArray value indicates that this is a relation */ | |
if ([value isKindOfClass:[NSArray class]]) { | |
/* Recursive build the relation */ | |
NSMutableSet *relationSet = [self convertToCoreData:value]; | |
/* Add relation to object */ | |
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"add%@:", key]); | |
if ([object respondsToSelector:selector]) { | |
[object performSelector:selector withObject:relationSet]; | |
} | |
} | |
/* A NSDictionary indicate a 1-to-1 relationship from Django Piston */ | |
else if ([value isKindOfClass:[NSDictionary class]]) { | |
NSMutableSet *relationSet = [self convertToCoreData:value]; | |
if (!IsEmpty(relationSet) && [relationSet count] == 1) { | |
/* Add object to model */ | |
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"set%@:", key]); | |
if ([object respondsToSelector:selector]) { | |
[object performSelector:selector withObject:[relationSet anyObject]]; | |
} | |
} | |
} | |
/* It is a simple attribute */ | |
else { | |
SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@:", key]); | |
if ([object respondsToSelector:setter]) { | |
if (!IsEmpty(value) && ![value isEqual:[NSNull null]]) { | |
if ([value isKindOfClass:[NSString class]]) { | |
if (![value isEqualToString:@"<null>"]) { | |
/* Just lowercase the first character */ | |
key = [key stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[key substringToIndex:1] lowercaseString]]; | |
SEL getter = NSSelectorFromString(key); | |
if ([object respondsToSelector:getter]) { | |
NSManagedObject *mObject = (NSManagedObject*)object; | |
NSPropertyDescription *propDesc = [[[[mObject class] entityDescription] | |
propertiesByName] objectForKey:key]; | |
if ([propDesc isMemberOfClass:[NSAttributeDescription class]]) { | |
NSAttributeDescription *attribDesc = (NSAttributeDescription*)propDesc; | |
if ([attribDesc attributeType] == NSDateAttributeType) { | |
NSDate *date = [NSDate dateFromString:value]; | |
if (!IsEmpty(date)) { | |
[object performSelector:setter withObject:date]; | |
} | |
} | |
else if ([attribDesc attributeType] == NSDecimalAttributeType) { | |
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:value]; | |
if (!IsEmpty(number)) { | |
[object performSelector:setter withObject:number]; | |
} | |
} | |
else { | |
[object performSelector:setter withObject:value]; | |
} | |
} | |
} | |
} | |
} | |
else { | |
[object performSelector:setter withObject:value]; | |
} | |
} | |
} | |
} | |
} | |
} | |
+ (id)managedObjectForEntity:(NSString *)entity uuid:(NSString *)uuid { | |
id object; | |
NSManagedObjectContext *moc = [(AppDelegate_Shared*)[[UIApplication sharedApplication] delegate] managedObjectContext]; | |
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; | |
[request setEntity:[NSEntityDescription entityForName:entity inManagedObjectContext:moc]]; | |
[request setPredicate:[NSPredicate predicateWithFormat:@"uuid = %@", uuid]]; | |
NSError *error = nil; | |
NSArray *results = [moc executeFetchRequest:request error:&error]; | |
if (error) { | |
NSLog(@"%@", error); | |
} | |
else if (!IsEmpty(results)) { | |
object = [results objectAtIndex:0]; | |
} | |
else { | |
object = [NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:moc];; | |
} | |
return object; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment