diff --git a/Code/CoreData/RKManagedObjectLoader.h b/Code/CoreData/RKManagedObjectLoader.h index 674769af..911457b7 100644 --- a/Code/CoreData/RKManagedObjectLoader.h +++ b/Code/CoreData/RKManagedObjectLoader.h @@ -34,6 +34,14 @@ BOOL _deleteObjectOnFailure; } +/** + A reference to a RestKit managed object store for interacting with Core Data + + @see RKManagedObjectStore + */ @property (nonatomic, retain) RKManagedObjectStore* objectStore; ++ (id)loaderWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore; +- (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore; + @end diff --git a/Code/CoreData/RKManagedObjectLoader.m b/Code/CoreData/RKManagedObjectLoader.m index 951a0bb3..597dab31 100644 --- a/Code/CoreData/RKManagedObjectLoader.m +++ b/Code/CoreData/RKManagedObjectLoader.m @@ -32,11 +32,25 @@ @synthesize objectStore = _objectStore; -- (id)init { - self = [super init]; ++ (id)loaderWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore { + return [[self alloc] initWithURL:URL mappingProvider:mappingProvider objectStore:objectStore]; +} + +- (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore { + self = [self initWithURL:URL mappingProvider:mappingProvider]; + if (self) { + _objectStore = [objectStore retain]; + } + + return self; +} + +- (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider { + self = [super initWithURL:URL mappingProvider:mappingProvider]; if (self) { _managedObjectKeyPaths = [[NSMutableSet alloc] init]; } + return self; } diff --git a/Code/Network/RKURL.h b/Code/Network/RKURL.h index 2ed78a6a..dac4dd19 100644 --- a/Code/Network/RKURL.h +++ b/Code/Network/RKURL.h @@ -33,6 +33,7 @@ @property (nonatomic, readonly) NSString* resourcePath; @property (nonatomic, readonly) NSDictionary* queryParams; ++ (id)URLWithURL:(NSURL *)URL; - (id)initWithBaseURLString:(NSString*)baseURLString resourcePath:(NSString*)resourcePath; - (id)initWithBaseURLString:(NSString*)baseURLString resourcePath:(NSString*)resourcePath queryParams:(NSDictionary*)queryParams; + (RKURL*)URLWithBaseURLString:(NSString*)baseURLString resourcePath:(NSString*)resourcePath; diff --git a/Code/Network/RKURL.m b/Code/Network/RKURL.m index 5ba594f4..56827cfd 100644 --- a/Code/Network/RKURL.m +++ b/Code/Network/RKURL.m @@ -27,6 +27,10 @@ @synthesize resourcePath = _resourcePath; @synthesize queryParams = _queryParams; ++ (id)URLWithURL:(NSURL *)URL { + return [self URLWithBaseURLString:[URL absoluteString] resourcePath:nil]; +} + + (RKURL*)URLWithBaseURLString:(NSString*)baseURLString resourcePath:(NSString*)resourcePath { return [[[self alloc] initWithBaseURLString:baseURLString resourcePath:resourcePath] autorelease]; } diff --git a/Code/ObjectMapping/RKObjectLoader.h b/Code/ObjectMapping/RKObjectLoader.h index c2eb0907..3cb4dfe1 100644 --- a/Code/ObjectMapping/RKObjectLoader.h +++ b/Code/ObjectMapping/RKObjectLoader.h @@ -3,7 +3,7 @@ // RestKit // // Created by Blake Watters on 8/8/09. -// Copyright 2009 Two Toasters +// Copyright 2009 RestKit // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ @class RKObjectMappingProvider; @class RKObjectLoader; -@class RKObjectManager; @protocol RKObjectLoaderDelegate @@ -130,16 +129,14 @@ * @default nil * @see RKObjectMappingProvider */ -// TODO: Rename to responseMapping @property (nonatomic, retain) RKObjectMapping* objectMapping; /** - * The object manager that initialized this loader. The object manager is responsible - * for supplying the mapper and object store used after HTTP transport is completed + A mapping provider containing object mapping configurations for mapping remote + object representations into local domain objects. + + @see RKObjectMappingProvider */ -//@property (nonatomic, readonly) RKObjectManager* objectManager; - -// TODO: Comment... @property (nonatomic, retain) RKObjectMappingProvider *mappingProvider; /** @@ -192,18 +189,20 @@ /////////////////////////////////////////////////////////////////////////////////////////// /** - * Initialize and return an object loader for a resource path against an object manager. The resource path - * specifies the remote location to load data from, while the object manager is responsible for supplying - * mapping and persistence details. + Initialize and return an autoreleased object loader targeting a remote URL using a mapping provider + + @param URL A RestKit RKURL targetting a particular baseURL and resourcePath + @param mappingProvider A mapping provider containing object mapping configurations for processing loaded payloads */ -+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate DEPRECATED_ATTRIBUTE; - -- (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider; ++ (id)loaderWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider; /** - * Initialize a new object loader with an object manager, a request, and a delegate + Initialize and return an autoreleased object loader targeting a remote URL using a mapping provider + + @param URL A RestKit RKURL targetting a particular baseURL and resourcePath + @param mappingProvider A mapping provider containing object mapping configurations for processing loaded payloads */ -- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate DEPRECATED_ATTRIBUTE; +- (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider; /** * Handle an error in the response preventing it from being mapped, called from -isResponseMappable @@ -211,3 +210,9 @@ - (void)handleResponseError; @end + +@class RKObjectManager; +@interface RKObjectLoader (Deprecations) ++ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate DEPRECATED_ATTRIBUTE; +- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate DEPRECATED_ATTRIBUTE; +@end diff --git a/Code/ObjectMapping/RKObjectLoader.m b/Code/ObjectMapping/RKObjectLoader.m index 6ee9c8d0..e89759db 100644 --- a/Code/ObjectMapping/RKObjectLoader.m +++ b/Code/ObjectMapping/RKObjectLoader.m @@ -47,17 +47,8 @@ @synthesize serializationMIMEType = _serializationMIMEType; @synthesize sourceObject = _sourceObject; -+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate { - return [[[self alloc] initWithResourcePath:resourcePath objectManager:objectManager delegate:delegate] autorelease]; -} - -- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate { - if ((self = [super initWithURL:[objectManager.client URLForResourcePath:resourcePath] delegate:delegate])) { - _mappingProvider = [objectManager.mappingProvider retain]; - [objectManager.client setupRequest:self]; - } - - return self; ++ (id)loaderWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider { + return [[self alloc] initWithURL:URL mappingProvider:mappingProvider]; } - (id)initWithURL:(NSURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider { @@ -391,3 +382,20 @@ } @end + +@implementation RKObjectLoader (Deprecations) + ++ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate { + return [[[self alloc] initWithResourcePath:resourcePath objectManager:objectManager delegate:delegate] autorelease]; +} + +- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id)delegate { + if ((self = [self initWithURL:[RKURL URLWithURL:[objectManager.client URLForResourcePath:resourcePath]] mappingProvider:objectManager.mappingProvider])) { + [objectManager.client setupRequest:self]; + _delegate = delegate; + } + + return self; +} + +@end diff --git a/Code/ObjectMapping/RKObjectManager.h b/Code/ObjectMapping/RKObjectManager.h index 2d23ebb1..d7a67f26 100644 --- a/Code/ObjectMapping/RKObjectManager.h +++ b/Code/ObjectMapping/RKObjectManager.h @@ -22,6 +22,7 @@ #import "RKObjectLoader.h" #import "RKObjectRouter.h" #import "RKObjectMappingProvider.h" +#import "RKObjectPaginator.h" @protocol RKParser; @@ -351,6 +352,13 @@ typedef enum { */ - (RKObjectLoader*)deleteObject:(id)object mapResponseWith:(RKObjectMapping*)objectMapping delegate:(id)delegate; +// TODO: Document all of these... +- (Class)objectLoaderClass; +- (id)loaderWithResourcePath:(NSString *)resourcePath; +- (id)loaderWithURL:(NSURL *)URL; +- (RKObjectPaginator *)paginatorWithResourcePathPattern:(NSString *)resourcePathPattern; +- (id)loaderForObject:(id)object method:(RKRequestMethod)method; + /** These methods are provided for situations where the remote system you are working with has slightly different conventions than the default methods provide. They return fully initialized object loaders that are ready for dispatch, but @@ -364,7 +372,7 @@ typedef enum { the best place to begin work if you need to create a slightly different collection loader than what is provided by the loadObjects family of methods. */ -- (RKObjectLoader*)objectLoaderWithResourcePath:(NSString*)resourcePath delegate:(id)delegate; +- (RKObjectLoader*)objectLoaderWithResourcePath:(NSString*)resourcePath delegate:(id)delegate DEPRECATED_ATTRIBUTE; /** Returns an object loader configured for transmitting an object instance across the wire. A request will be constructed @@ -375,6 +383,6 @@ typedef enum { // TODO: Cleanup this comment */ -- (RKObjectLoader*)objectLoaderForObject:(id)object method:(RKRequestMethod)method delegate:(id)delegate; +- (RKObjectLoader*)objectLoaderForObject:(id)object method:(RKRequestMethod)method delegate:(id)delegate DEPRECATED_ATTRIBUTE; @end diff --git a/Code/ObjectMapping/RKObjectManager.m b/Code/ObjectMapping/RKObjectManager.m index 525c3a42..efb3f54b 100644 --- a/Code/ObjectMapping/RKObjectManager.m +++ b/Code/ObjectMapping/RKObjectManager.m @@ -137,6 +137,59 @@ static RKObjectManager* sharedManager = nil; ///////////////////////////////////////////////////////////// #pragma mark - Object Collection Loaders +- (Class)objectLoaderClass { + Class managedObjectLoaderClass = NSClassFromString(@"RKManagedObjectLoader"); + if (self.objectStore && managedObjectLoaderClass) { + return managedObjectLoaderClass; + } + + return [RKObjectLoader class]; +} + +- (id)loaderWithResourcePath:(NSString *)resourcePath { + RKURL *URL = [RKURL URLWithBaseURLString:self.client.baseURL resourcePath:resourcePath]; + return [self loaderWithURL:URL]; +} + +- (id)loaderWithURL:(NSURL *)URL { + RKObjectLoader *loader = [[self objectLoaderClass] loaderWithURL:URL mappingProvider:self.mappingProvider]; + if ([loader isKindOfClass:[RKManagedObjectLoader class]]) { + [(RKManagedObjectLoader *)loader setObjectStore:self.objectStore]; + } + [self.client setupRequest:loader]; + + return loader; +} + +- (NSURL *)baseURL { + // TODO: Turn RKClient baseURL into an NSURL and proxy... + return [NSURL URLWithString:self.client.baseURL]; +} + +- (RKObjectPaginator *)paginatorWithResourcePathPattern:(NSString *)resourcePathPattern { + return [RKObjectPaginator paginatorWithBaseURL:[self baseURL] + resourcePathPattern:resourcePathPattern + mappingProvider:self.mappingProvider]; +} + +- (id)loaderForObject:(id)object method:(RKRequestMethod)method { + NSString* resourcePath = [self.router resourcePathForObject:object method:method]; + RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath]; + loader.method = method; + loader.sourceObject = object; + loader.targetObject = object; + loader.serializationMIMEType = self.serializationMIMEType; + loader.serializationMapping = [self.mappingProvider serializationMappingForClass:[object class]]; + + if (self.inferMappingsFromObjectTypes) { + RKObjectMapping* objectMapping = [self.mappingProvider objectMappingForClass:[object class]]; + RKLogDebug(@"Auto-selected object mapping %@ for object of type %@", objectMapping, NSStringFromClass([object class])); + loader.objectMapping = objectMapping; + } + + return loader; +} + - (RKObjectLoader*)objectLoaderWithResourcePath:(NSString*)resourcePath delegate:(id)delegate { RKObjectLoader* objectLoader = nil; Class managedObjectLoaderClass = NSClassFromString(@"RKManagedObjectLoader"); @@ -151,7 +204,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)loadObjectsAtResourcePath:(NSString*)resourcePath delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderWithResourcePath:resourcePath delegate:delegate]; + RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath]; + loader.delegate = delegate; loader.method = RKRequestMethodGET; [loader send]; @@ -160,7 +214,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)loadObjectsAtResourcePath:(NSString*)resourcePath objectMapping:(RKObjectMapping*)objectMapping delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderWithResourcePath:resourcePath delegate:delegate]; + RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath]; + loader.delegate = delegate; loader.method = RKRequestMethodGET; loader.objectMapping = objectMapping; @@ -173,43 +228,35 @@ static RKObjectManager* sharedManager = nil; #pragma mark - Object Instance Loaders - (RKObjectLoader*)objectLoaderForObject:(id)object method:(RKRequestMethod)method delegate:(id)delegate { - NSString* resourcePath = [self.router resourcePathForObject:object method:method]; - RKObjectLoader* loader = [self objectLoaderWithResourcePath:resourcePath delegate:delegate]; - loader.method = method; - loader.sourceObject = object; - loader.targetObject = object; - loader.serializationMIMEType = self.serializationMIMEType; - loader.serializationMapping = [self.mappingProvider serializationMappingForClass:[object class]]; - - if (self.inferMappingsFromObjectTypes) { - RKObjectMapping* objectMapping = [self.mappingProvider objectMappingForClass:[object class]]; - RKLogDebug(@"Auto-selected object mapping %@ for object of type %@", objectMapping, NSStringFromClass([object class])); - loader.objectMapping = objectMapping; - } - - return loader; + RKObjectLoader *loader = [self loaderForObject:object method:method]; + loader.delegate = delegate; + return loader; } - (RKObjectLoader*)getObject:(id)object delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodGET delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodGET]; + loader.delegate = delegate; [loader send]; return loader; } - (RKObjectLoader*)postObject:(id)object delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodPOST delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodPOST]; + loader.delegate = delegate; [loader send]; return loader; } - (RKObjectLoader*)putObject:(id)object delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodPUT delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodPUT]; + loader.delegate = delegate; [loader send]; return loader; } - (RKObjectLoader*)deleteObject:(id)object delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodDELETE delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodDELETE]; + loader.delegate = delegate; [loader send]; return loader; } @@ -219,7 +266,8 @@ static RKObjectManager* sharedManager = nil; #pragma mark - Block Configured Object Loaders - (RKObjectLoader*)loadObjectsAtResourcePath:(NSString*)resourcePath delegate:(id)delegate block:(void(^)(RKObjectLoader*))block { - RKObjectLoader* loader = [self objectLoaderWithResourcePath:resourcePath delegate:delegate]; + RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath]; + loader.delegate = delegate; loader.method = RKRequestMethodGET; // Yield to the block for setup @@ -231,7 +279,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)sendObject:(id)object delegate:(id)delegate block:(void(^)(RKObjectLoader*))block { - RKObjectLoader* loader = [self objectLoaderWithResourcePath:nil delegate:delegate]; + RKObjectLoader* loader = [self loaderWithResourcePath:nil]; + loader.delegate = delegate; loader.sourceObject = object; loader.targetObject = object; loader.serializationMIMEType = self.serializationMIMEType; @@ -284,7 +333,8 @@ static RKObjectManager* sharedManager = nil; #pragma mark - Object Instance Loaders for Non-nested JSON - (RKObjectLoader*)getObject:(id)object mapResponseWith:(RKObjectMapping*)objectMapping delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodGET delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodGET]; + loader.delegate = delegate; if ([object isMemberOfClass:[objectMapping objectClass]]) { loader.targetObject = object; } else { @@ -296,7 +346,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)postObject:(id)object mapResponseWith:(RKObjectMapping*)objectMapping delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodPOST delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodPOST]; + loader.delegate = delegate; if ([object isMemberOfClass:[objectMapping objectClass]]) { loader.targetObject = object; } else { @@ -308,7 +359,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)putObject:(id)object mapResponseWith:(RKObjectMapping*)objectMapping delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodPUT delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodPUT]; + loader.delegate = delegate; if ([object isMemberOfClass:[objectMapping objectClass]]) { loader.targetObject = object; } else { @@ -320,7 +372,8 @@ static RKObjectManager* sharedManager = nil; } - (RKObjectLoader*)deleteObject:(id)object mapResponseWith:(RKObjectMapping*)objectMapping delegate:(id)delegate { - RKObjectLoader* loader = [self objectLoaderForObject:object method:RKRequestMethodDELETE delegate:delegate]; + RKObjectLoader* loader = [self loaderForObject:object method:RKRequestMethodDELETE]; + loader.delegate = delegate; if ([object isMemberOfClass:[objectMapping objectClass]]) { loader.targetObject = object; } else { diff --git a/Specs/Runner/RKSpecEnvironment.m b/Specs/Runner/RKSpecEnvironment.m index ce0a9c97..b3a4406a 100644 --- a/Specs/Runner/RKSpecEnvironment.m +++ b/Specs/Runner/RKSpecEnvironment.m @@ -137,14 +137,6 @@ id RKSpecParseFixture(NSString* fileName) { @implementation RKSpec -//- (void)failWithException:(NSException *) e { -// printf("%s:%i: error: %s\n", -// [[[e userInfo] objectForKey:SenTestFilenameKey] cString], -// [[[e userInfo] objectForKey:SenTestLineNumberKey] intValue], -// [[[e userInfo] objectForKey:SenTestDescriptionKey] cString]); -// [e raise]; -//} - @end @implementation SenTestCase (MethodSwizzling)