From 878a2a5e69c28c2309441312c472b24bc981cc0d Mon Sep 17 00:00:00 2001 From: Blake Watters Date: Tue, 20 Jul 2010 15:46:43 -0400 Subject: [PATCH] Refactored RestKit. Changed classing naming conventions to better indicate object roles. Moved OCMock and UISpec dependencies in as submodules. Introduced router concept for generating paths and object serializations. --- .gitignore | 1 + .gitmodules | 7 + Code/RKClient.m | 2 +- Code/{RKManagedModel.m => RKManagedObject.m} | 11 +- Code/RKMappingFormatJSONParser.h | 2 +- Code/RKModelManager.m | 171 ----- Code/RKObject.m | 22 + Code/{RKModelSeeder.m => RKObjectSeeder.m} | 8 +- Code/{RKModelLoader.m => RKResourceLoader.m} | 36 +- Code/RKResourceManager.m | 173 +++++ Code/{RKModelMapper.m => RKResourceMapper.m} | 15 +- Code/RKStaticRouter.m | 31 + .../{RKManagedModel.h => RKManagedObject.h} | 26 +- Code/RestKit/RKModelLoader.h | 70 -- Code/RestKit/RKModelManager.h | 137 ---- Code/RestKit/RKObject.h | 18 + .../{RKModelSeeder.h => RKObjectSeeder.h} | 8 +- Code/RestKit/RKResourceLoader.h | 70 ++ Code/RestKit/RKResourceManager.h | 147 +++++ ...appableProtocol.h => RKResourceMappable.h} | 21 +- .../{RKModelMapper.h => RKResourceMapper.h} | 8 +- Code/RestKit/RKRouter.h | 29 + Code/RestKit/RKStaticRouter.h | 25 + Code/RestKit/RestKit.h | 6 +- Code/RestKit/Three20/RKRequestModel.h | 2 +- RestKit_Prefix.pch => Code/RestKit_Prefix.pch | 0 RestKit.xcodeproj/project.pbxproj | 602 ++++++++++++++---- Specs/Models/RKCat.h | 4 +- Specs/Models/RKHouse.h | 4 +- Specs/Models/RKHuman.h | 4 +- Specs/Models/RKMappableAssociation.h | 6 +- Specs/Models/RKMappableObject.h | 4 +- Specs/Models/RKMappableObject.m | 1 + Specs/Models/RKResident.h | 5 +- ...pecModel.h => RKResourceMapperSpecModel.h} | 5 +- ...pecModel.m => RKResourceMapperSpecModel.m} | 7 +- Specs/RKClientSpec.m | 13 - Specs/RKManagedModelSpec.m | 24 - Specs/RKManagedObjectSpec.m | 21 + Specs/RKModelManagerSpec.m | 27 +- Specs/RKModelMapperSpec.m | 83 ++- Specs/RKRequestSpec.m | 4 +- Specs/RKStaticRouterSpec.m | 29 + Specs/Support/OCMock | 1 + Specs/Support/OCMock.framework/Headers | 1 - Specs/Support/OCMock.framework/OCMock | 1 - Specs/Support/OCMock.framework/Resources | 1 - .../NSNotificationCenter+OCMAdditions.h | 15 - .../Versions/A/Headers/OCMArg.h | 30 - .../Versions/A/Headers/OCMConstraint.h | 48 -- .../Versions/A/Headers/OCMock.h | 10 - .../Versions/A/Headers/OCMockObject.h | 41 -- .../Versions/A/Headers/OCMockRecorder.h | 28 - .../OCMock.framework/Versions/A/OCMock | Bin 291796 -> 0 bytes .../Versions/A/Resources/Info.plist | 26 - .../Versions/A/Resources/License.txt | 15 - .../Support/OCMock.framework/Versions/Current | 1 - Specs/Support/RKSpecEnvironment.h | 39 +- Specs/Support/RKSpecResponseLoader.h | 7 +- Specs/Support/RKSpecResponseLoader.m | 27 +- Specs/Support/UISpec | 1 + Specs/Support/set_ip_address.scpt | Bin 9018 -> 9014 bytes Specs/UISpec+UISpecRunner.h | 27 + Specs/UISpec+UISpecRunner.m | 69 ++ Specs/main.m | 21 +- 65 files changed, 1336 insertions(+), 962 deletions(-) create mode 100644 .gitmodules rename Code/{RKManagedModel.m => RKManagedObject.m} (97%) delete mode 100644 Code/RKModelManager.m create mode 100644 Code/RKObject.m rename Code/{RKModelSeeder.m => RKObjectSeeder.m} (92%) rename Code/{RKModelLoader.m => RKResourceLoader.m} (84%) create mode 100644 Code/RKResourceManager.m rename Code/{RKModelMapper.m => RKResourceMapper.m} (95%) create mode 100644 Code/RKStaticRouter.m rename Code/RestKit/{RKManagedModel.h => RKManagedObject.h} (79%) delete mode 100644 Code/RestKit/RKModelLoader.h delete mode 100644 Code/RestKit/RKModelManager.h create mode 100644 Code/RestKit/RKObject.h rename Code/RestKit/{RKModelSeeder.h => RKObjectSeeder.h} (75%) create mode 100644 Code/RestKit/RKResourceLoader.h create mode 100644 Code/RestKit/RKResourceManager.h rename Code/RestKit/{RKModelMappableProtocol.h => RKResourceMappable.h} (69%) rename Code/RestKit/{RKModelMapper.h => RKResourceMapper.h} (93%) create mode 100644 Code/RestKit/RKRouter.h create mode 100644 Code/RestKit/RKStaticRouter.h rename RestKit_Prefix.pch => Code/RestKit_Prefix.pch (100%) rename Specs/Models/{RKModelMapperSpecModel.h => RKResourceMapperSpecModel.h} (81%) rename Specs/Models/{RKModelMapperSpecModel.m => RKResourceMapperSpecModel.m} (65%) delete mode 100644 Specs/RKClientSpec.m delete mode 100644 Specs/RKManagedModelSpec.m create mode 100644 Specs/RKManagedObjectSpec.m create mode 100644 Specs/RKStaticRouterSpec.m create mode 160000 Specs/Support/OCMock delete mode 120000 Specs/Support/OCMock.framework/Headers delete mode 120000 Specs/Support/OCMock.framework/OCMock delete mode 120000 Specs/Support/OCMock.framework/Resources delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/NSNotificationCenter+OCMAdditions.h delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/OCMArg.h delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/OCMConstraint.h delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/OCMock.h delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/OCMockObject.h delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Headers/OCMockRecorder.h delete mode 100755 Specs/Support/OCMock.framework/Versions/A/OCMock delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Resources/Info.plist delete mode 100644 Specs/Support/OCMock.framework/Versions/A/Resources/License.txt delete mode 120000 Specs/Support/OCMock.framework/Versions/Current create mode 160000 Specs/Support/UISpec create mode 100644 Specs/UISpec+UISpecRunner.h create mode 100644 Specs/UISpec+UISpecRunner.m diff --git a/.gitignore b/.gitignore index 0dbc13ea..147837ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # the build build +Build # temp nibs and swap files *~.nib diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..05cba502 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "Specs/Support/UISpec"] + path = Specs/Support/UISpec + url = git://github.com/twotoasters/UISpec.git + +[submodule "Specs/Support/OCMock"] + path = Specs/Support/OCMock + url = git@github.com:twotoasters/OCMock.git diff --git a/Code/RKClient.m b/Code/RKClient.m index 75d5cde0..b64f6c6d 100644 --- a/Code/RKClient.m +++ b/Code/RKClient.m @@ -7,7 +7,7 @@ // #import "RKClient.h" -#import "RKModelLoader.h" +#import "RKResourceLoader.h" #import /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/RKManagedModel.m b/Code/RKManagedObject.m similarity index 97% rename from Code/RKManagedModel.m rename to Code/RKManagedObject.m index cc93214c..bb9f877e 100644 --- a/Code/RKManagedModel.m +++ b/Code/RKManagedObject.m @@ -1,22 +1,22 @@ // -// RKManagedModel.m +// RKManagedObject.m // RestKit // // Created by Blake Watters on 8/14/09. // Copyright 2009 Two Toasters. All rights reserved. // -#import "RKManagedModel.h" +#import "RKManagedObject.h" #import "NSString+InflectionSupport.h" #import -@implementation RKManagedModel +@implementation RKManagedObject #pragma mark - #pragma mark NSManagedObject helper methods + (NSManagedObjectContext*)managedObjectContext { - return [[[RKModelManager manager] objectStore] managedObjectContext]; + return [[[RKResourceManager manager] objectStore] managedObjectContext]; } + (NSManagedObject*)objectWithId:(NSManagedObjectID*)objectId { @@ -113,6 +113,7 @@ } // TODO: This is Rails specific. Clean up! +// TODO: Moves to the router - (NSString*)resourcePathForMethod:(RKRequestMethod)method { // TODO: Support an optional RKResourceAdapter class? switch (method) { @@ -129,6 +130,8 @@ default: break; } + + return nil; } // TODO: Would be nice to specify this via an annotation in the mappings definition... diff --git a/Code/RKMappingFormatJSONParser.h b/Code/RKMappingFormatJSONParser.h index 8c6ffc1e..a5fdddb3 100644 --- a/Code/RKMappingFormatJSONParser.h +++ b/Code/RKMappingFormatJSONParser.h @@ -6,7 +6,7 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKModelMapper.h" +#import "RKResourceMapper.h" #import "JSON.h" @interface RKMappingFormatJSONParser : NSObject { diff --git a/Code/RKModelManager.m b/Code/RKModelManager.m deleted file mode 100644 index 71e93944..00000000 --- a/Code/RKModelManager.m +++ /dev/null @@ -1,171 +0,0 @@ -// -// RKModelManager.m -// RestKit -// -// Created by Jeremy Ellison on 8/14/09. -// Copyright 2009 Two Toasters. All rights reserved. -// - -#import "RKModelManager.h" - -NSString* const RKDidEnterOfflineModeNotification = @"RKDidEnterOfflineModeNotification"; -NSString* const RKDidEnterOnlineModeNotification = @"RKDidEnterOnlineModeNotification"; - -////////////////////////////////// -// Global Instance - -static RKModelManager* sharedManager = nil; - -/////////////////////////////////// - -@implementation RKModelManager - -@synthesize mapper = _mapper; -@synthesize client = _client; -@synthesize objectStore = _objectStore; -@synthesize format = _format; - -- (id)initWithBaseURL:(NSString*)baseURL { - if (self = [super init]) { - _mapper = [[RKModelMapper alloc] init]; - _client = [[RKClient clientWithBaseURL:baseURL] retain]; - self.format = RKMappingFormatJSON; - _isOnline = YES; - } - return self; -} - -+ (RKModelManager*)manager { - return sharedManager; -} - -+ (void)setManager:(RKModelManager*)manager { - [sharedManager release]; - sharedManager = [manager retain]; -} - -+ (RKModelManager*)managerWithBaseURL:(NSString*)baseURL { - RKModelManager* manager = [[[RKModelManager alloc] initWithBaseURL:baseURL] autorelease]; - if (sharedManager == nil) { - [RKModelManager setManager:manager]; - } - return manager; -} - -- (void)dealloc { - [_mapper release]; - [_client release]; - [super dealloc]; -} - -- (void)goOffline { - _isOnline = NO; - [[NSNotificationCenter defaultCenter] postNotificationName:RKDidEnterOfflineModeNotification object:[RKModelManager manager]]; -} - -- (void)goOnline { - _isOnline = YES; - [[NSNotificationCenter defaultCenter] postNotificationName:RKDidEnterOnlineModeNotification object:[RKModelManager manager]]; -} - -- (BOOL)isOnline { - return _isOnline; -} - -- (BOOL)isOffline { - return ![self isOnline]; -} - -- (void)setFormat:(RKMappingFormat)format { - _format = format; - _mapper.format = format; - if (RKMappingFormatXML == _format) { - [_client setValue:@"application/xml" forHTTPHeaderField:@"Accept"]; - } else if (RKMappingFormatJSON == _format) { - [_client setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - } -} - -#pragma mark Model Methods - -- (void)registerModel:(Class)class forElementNamed:(NSString*)elementName { - [_mapper registerModel:class forElementNamed:elementName]; -} - -///////////////////////////////////////////////////////////// -// Model Collection Loaders - -- (RKRequest*)loadModels:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate { - return [self loadModels:resourcePath fetchRequest:nil method:method params:params delegate:delegate]; -} - -- (RKRequest*)loadModels:(NSString*)resourcePath delegate:(NSObject*)delegate { - return [self loadModels:resourcePath fetchRequest:nil method:RKRequestMethodGET params:nil delegate:delegate]; -} - -- (RKRequest*)loadModels:(NSString*)resourcePath method:(RKRequestMethod)method delegate:(NSObject*)delegate { - return [self loadModels:resourcePath fetchRequest:nil method:method params:nil delegate:delegate]; -} - -- (RKRequest*)loadModels:(NSString*)resourcePath params:(NSDictionary*)params delegate:(NSObject*)delegate { - return [self loadModels:resourcePath fetchRequest:nil method:RKRequestMethodGET params:params delegate:delegate]; -} - -- (RKRequest*)loadModels:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method delegate:(NSObject*)delegate { - return [self loadModels:resourcePath fetchRequest:fetchRequest method:method params:nil delegate:delegate]; -} - -- (RKRequest*)loadModels:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate { - if ([self isOffline]) { - return nil; - } - - RKModelLoader* loader = [RKModelLoader loaderWithMapper:self.mapper]; - loader.fetchRequest = fetchRequest; - loader.delegate = delegate; - - return [_client load:resourcePath method:method params:params delegate:loader callback:loader.callback]; -} - -///////////////////////////////////////////////////////////// -// Model Instance Loaders - -- (RKRequest*)modelLoaderRequest:(id)model resourcePath:(NSString*)resourcePath method:(RKRequestMethod)method params:(RKParams*)params delegate:(NSObject*)delegate { - if (method != RKRequestMethodGET) { - NSError* error = [[[RKModelManager manager] objectStore] save]; - if (error != nil) { - NSLog(@"[RestKit] RKModelManager: Error saving managed object context before PUT/POST/DELETE: error=%@ userInfo=%@", error, error.userInfo); - } - } - - RKRequest* request = [self loadModels:resourcePath method:method params:params delegate:delegate]; - request.userData = model; - return request; -} - -- (RKRequest*)getModel:(id)model delegate:(NSObject*)delegate { - NSObject* params = [model resourceSerializationForMethod:RKRequestMethodGET]; - NSString* resourcePath = [model resourcePathForMethod:RKRequestMethodGET]; - return [self modelLoaderRequest:model resourcePath:resourcePath method:RKRequestMethodGET params:params delegate:delegate]; -} - -- (RKRequest*)postModel:(id)model delegate:(NSObject*)delegate { - NSObject* params = [model resourceSerializationForMethod:RKRequestMethodPOST]; - NSString* resourcePath = [model resourcePathForMethod:RKRequestMethodPOST]; - return [self modelLoaderRequest:model resourcePath:resourcePath method:RKRequestMethodPOST params:params delegate:delegate]; -} - -- (RKRequest*)putModel:(id)model delegate:(NSObject*)delegate { - NSObject* params = [model resourceSerializationForMethod:RKRequestMethodPUT]; - NSString* resourcePath = [model resourcePathForMethod:RKRequestMethodPUT]; - return [self modelLoaderRequest:model resourcePath:resourcePath method:RKRequestMethodPUT params:params delegate:delegate]; -} - -- (RKRequest*)deleteModel:(id)model delegate:(NSObject*)delegate { - NSObject* params = [model resourceSerializationForMethod:RKRequestMethodDELETE]; - NSString* resourcePath = [model resourcePathForMethod:RKRequestMethodDELETE]; - return [self modelLoaderRequest:model resourcePath:resourcePath method:RKRequestMethodDELETE params:params delegate:delegate]; -} - -@end - diff --git a/Code/RKObject.m b/Code/RKObject.m new file mode 100644 index 00000000..98ae0ff8 --- /dev/null +++ b/Code/RKObject.m @@ -0,0 +1,22 @@ +// +// RKObject.m +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKObject.h" + +@implementation RKObject + ++ (NSDictionary*)elementToPropertyMappings { + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + ++ (NSDictionary*)elementToRelationshipMappings { + return [NSDictionary dictionary]; +} + +@end diff --git a/Code/RKModelSeeder.m b/Code/RKObjectSeeder.m similarity index 92% rename from Code/RKModelSeeder.m rename to Code/RKObjectSeeder.m index 6e3cc1bf..f993f0a8 100644 --- a/Code/RKModelSeeder.m +++ b/Code/RKObjectSeeder.m @@ -1,16 +1,16 @@ // -// RKModelSeeder.m +// RKObjectSeeder.m // RestKit // // Created by Blake Watters on 3/4/10. // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKModelSeeder.h" +#import "RKObjectSeeder.h" -@implementation RKModelSeeder +@implementation RKObjectSeeder -- (id)initWithModelManager:(RKModelManager*)manager { +- (id)initWithResourceManager:(RKResourceManager*)manager { if (self = [self init]) { _manager = [manager retain]; } diff --git a/Code/RKModelLoader.m b/Code/RKResourceLoader.m similarity index 84% rename from Code/RKModelLoader.m rename to Code/RKResourceLoader.m index 9217b715..a4a837d3 100644 --- a/Code/RKModelLoader.m +++ b/Code/RKResourceLoader.m @@ -1,5 +1,5 @@ // -// RKModelLoader.m +// RKResourceLoader.m // RestKit // // Created by Blake Watters on 8/8/09. @@ -7,21 +7,21 @@ // #import -#import "RKModelLoader.h" +#import "RKResourceLoader.h" #import "RKResponse.h" -#import "RKModelManager.h" +#import "RKResourceManager.h" #import "Errors.h" -#import "RKManagedModel.h" +#import "RKManagedObject.h" -@implementation RKModelLoader +@implementation RKResourceLoader @synthesize mapper = _mapper, delegate = _delegate, callback = _callback, fetchRequest = _fetchRequest; -+ (id)loaderWithMapper:(RKModelMapper*)mapper { ++ (id)loaderWithMapper:(RKResourceMapper*)mapper { return [[[self alloc] initWithMapper:mapper] autorelease]; } -- (id)initWithMapper:(RKModelMapper*)mapper { +- (id)initWithMapper:(RKResourceMapper*)mapper { if (self = [self init]) { _mapper = [mapper retain]; } @@ -35,13 +35,13 @@ } - (SEL)callback { - return @selector(loadModelsFromResponse:); + return @selector(loadObjectsFromResponse:); } - (BOOL)encounteredErrorWhileProcessingRequest:(RKResponse*)response { RKRequest* request = response.request; if ([response isFailure]) { - [_delegate modelLoaderRequest:response.request didFailWithError:response.failureError response:response modelObject:(id)request.userData]; + [_delegate resourceLoadRequest:response.request didFailWithError:response.failureError response:response object:(id)request.userData]; return YES; } else if ([response isError]) { NSString* errorMessage = nil; @@ -56,7 +56,7 @@ nil]; NSError *error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKModelLoaderRemoteSystemError userInfo:userInfo]; - [_delegate modelLoaderRequest:response.request didFailWithError:error response:response modelObject:(id)request.userData]; + [_delegate resourceLoadRequest:response.request didFailWithError:error response:response object:(id)request.userData]; return YES; } @@ -72,7 +72,7 @@ // that were model mapped on a background thread. We look up the objects by ID and then // notify the delegate that the operation has completed. NSMutableArray* objects = [NSMutableArray arrayWithCapacity:[models count]]; - RKManagedObjectStore* objectStore = [[RKModelManager manager] objectStore]; + RKManagedObjectStore* objectStore = [[RKResourceManager manager] objectStore]; for (id object in models) { if ([object isKindOfClass:[NSManagedObjectID class]]) { [objects addObject:[objectStore objectWithID:(NSManagedObjectID*)object]]; @@ -82,7 +82,7 @@ } RKRequest* request = response.request; - [_delegate modelLoaderRequest:request didLoadModels:[NSArray arrayWithArray:objects] response:response modelObject:(id)request.userData]; + [_delegate resourceLoadRequest:request didLoadObjects:[NSArray arrayWithArray:objects] response:response object:(id)request.userData]; // Release the response now that we have finished all our processing [response release]; @@ -101,7 +101,7 @@ NSError *rkError = [NSError errorWithDomain:RKRestKitErrorDomain code:RKModelLoaderRemoteSystemError userInfo:userInfo]; RKRequest* request = response.request; - [_delegate modelLoaderRequest:response.request didFailWithError:rkError response:response modelObject:(id)request.userData]; + [_delegate resourceLoadRequest:response.request didFailWithError:rkError response:response object:(id)request.userData]; // Release the response now that we have finished all our processing [response release]; @@ -110,7 +110,7 @@ - (void)processLoadModelsInBackground:(RKResponse *)response { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - RKManagedObjectStore* objectStore = [[RKModelManager manager] objectStore]; + RKManagedObjectStore* objectStore = [[RKResourceManager manager] objectStore]; // TODO: Should probably relax singleton... // If the request was sent through a model, we map the results back into that object // TODO: Note that this assumption may not work in all cases, other approaches? @@ -140,10 +140,10 @@ if (self.fetchRequest) { // TODO: Get rid of objectsWithRequest on - NSArray* cachedObjects = [RKManagedModel objectsWithRequest:self.fetchRequest]; + NSArray* cachedObjects = [RKManagedObject objectsWithRequest:self.fetchRequest]; for (id object in cachedObjects) { - if ([object isKindOfClass:[RKManagedModel class]]) { + if ([object isKindOfClass:[RKManagedObject class]]) { if (NO == [results containsObject:object]) { [[objectStore managedObjectContext] deleteObject:object]; } @@ -164,7 +164,7 @@ } } - NSError* error = [[[RKModelManager manager] objectStore] save]; + NSError* error = [[[RKResourceManager manager] objectStore] save]; if (nil != error) { NSDictionary* infoDictionary = [[NSDictionary dictionaryWithObjectsAndKeys:response, @"response", error, @"error", nil] retain]; [self performSelectorOnMainThread:@selector(informDelegateOfModelLoadErrorWithInfoDictionary:) withObject:infoDictionary waitUntilDone:NO]; @@ -176,7 +176,7 @@ [pool release]; } -- (void)loadModelsFromResponse:(RKResponse*)response { +- (void)loadObjectsFromResponse:(RKResponse*)response { if (NO == [self encounteredErrorWhileProcessingRequest:response] && [response isSuccessful]) { // Retain the response to prevent this thread from dealloc'ing before we have finished processing [response retain]; diff --git a/Code/RKResourceManager.m b/Code/RKResourceManager.m new file mode 100644 index 00000000..80185160 --- /dev/null +++ b/Code/RKResourceManager.m @@ -0,0 +1,173 @@ +// +// RKResourceManager.m +// RestKit +// +// Created by Jeremy Ellison on 8/14/09. +// Copyright 2009 Two Toasters. All rights reserved. +// + +#import "RKResourceManager.h" + +NSString* const RKDidEnterOfflineModeNotification = @"RKDidEnterOfflineModeNotification"; +NSString* const RKDidEnterOnlineModeNotification = @"RKDidEnterOnlineModeNotification"; + +////////////////////////////////// +// Global Instance + +static RKResourceManager* sharedManager = nil; + +/////////////////////////////////// + +@implementation RKResourceManager + +@synthesize mapper = _mapper; +@synthesize client = _client; +@synthesize objectStore = _objectStore; +@synthesize format = _format; +@synthesize router = _router; + +- (id)initWithBaseURL:(NSString*)baseURL { + if (self = [super init]) { + _mapper = [[RKResourceMapper alloc] init]; + _router = [[RKStaticRouter alloc] init]; + _client = [[RKClient clientWithBaseURL:baseURL] retain]; + self.format = RKMappingFormatJSON; + _isOnline = YES; + } + return self; +} + ++ (RKResourceManager*)manager { + return sharedManager; +} + ++ (void)setManager:(RKResourceManager*)manager { + [sharedManager release]; + sharedManager = [manager retain]; +} + ++ (RKResourceManager*)managerWithBaseURL:(NSString*)baseURL { + RKResourceManager* manager = [[[RKResourceManager alloc] initWithBaseURL:baseURL] autorelease]; + if (sharedManager == nil) { + [RKResourceManager setManager:manager]; + } + return manager; +} + +- (void)dealloc { + [_mapper release]; + [_router release]; + [_client release]; + [super dealloc]; +} + +- (void)goOffline { + _isOnline = NO; + [[NSNotificationCenter defaultCenter] postNotificationName:RKDidEnterOfflineModeNotification object:self]; +} + +- (void)goOnline { + _isOnline = YES; + [[NSNotificationCenter defaultCenter] postNotificationName:RKDidEnterOnlineModeNotification object:self]; +} + +- (BOOL)isOnline { + return _isOnline; +} + +- (BOOL)isOffline { + return ![self isOnline]; +} + +- (void)setFormat:(RKMappingFormat)format { + _format = format; + _mapper.format = format; + if (RKMappingFormatXML == _format) { + [_client setValue:@"application/xml" forHTTPHeaderField:@"Accept"]; + } else if (RKMappingFormatJSON == _format) { + [_client setValue:@"application/json" forHTTPHeaderField:@"Accept"]; + } +} + +#pragma mark Model Methods + +- (void)registerClass:(Class)class forElementNamed:(NSString*)elementName { + [_mapper registerClass:class forElementNamed:elementName]; +} + +///////////////////////////////////////////////////////////// +// Model Collection Loaders + +- (RKRequest*)loadResource:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate { + return [self loadResource:resourcePath fetchRequest:nil method:method params:params delegate:delegate]; +} + +- (RKRequest*)loadResource:(NSString*)resourcePath delegate:(NSObject*)delegate { + return [self loadResource:resourcePath fetchRequest:nil method:RKRequestMethodGET params:nil delegate:delegate]; +} + +- (RKRequest*)loadResource:(NSString*)resourcePath method:(RKRequestMethod)method delegate:(NSObject*)delegate { + return [self loadResource:resourcePath fetchRequest:nil method:method params:nil delegate:delegate]; +} + +- (RKRequest*)loadResource:(NSString*)resourcePath params:(NSDictionary*)params delegate:(NSObject*)delegate { + return [self loadResource:resourcePath fetchRequest:nil method:RKRequestMethodGET params:params delegate:delegate]; +} + +- (RKRequest*)loadResource:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method delegate:(NSObject*)delegate { + return [self loadResource:resourcePath fetchRequest:fetchRequest method:method params:nil delegate:delegate]; +} + +- (RKRequest*)loadResource:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate { + if ([self isOffline]) { + return nil; + } + + RKResourceLoader* loader = [RKResourceLoader loaderWithMapper:self.mapper]; + loader.fetchRequest = fetchRequest; + loader.delegate = delegate; + + return [_client load:resourcePath method:method params:params delegate:loader callback:loader.callback]; +} + +///////////////////////////////////////////////////////////// +// Model Instance Loaders + +- (RKRequest*)resourceLoaderRequest:(id)model resourcePath:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate { + if (method != RKRequestMethodGET) { + NSError* error = [self.objectStore save]; + if (error != nil) { + NSLog(@"[RestKit] RKModelManager: Error saving managed object context before PUT/POST/DELETE: error=%@ userInfo=%@", error, error.userInfo); + } + } + + RKRequest* request = [self loadResource:resourcePath method:method params:params delegate:delegate]; + request.userData = model; + return request; +} + +- (RKRequest*)getObject:(NSObject*)object delegate:(NSObject*)delegate { + NSString* resourcePath = [_router pathForObject:object method:RKRequestMethodGET]; + NSObject* params = [_router serializationForObject:object method:RKRequestMethodGET]; + return [self resourceLoaderRequest:object resourcePath:resourcePath method:RKRequestMethodGET params:params delegate:delegate]; +} + +- (RKRequest*)postObject:(NSObject*)object delegate:(NSObject*)delegate { + NSString* resourcePath = [_router pathForObject:object method:RKRequestMethodPOST]; + NSObject* params = [_router serializationForObject:object method:RKRequestMethodPOST]; + return [self resourceLoaderRequest:object resourcePath:resourcePath method:RKRequestMethodPOST params:params delegate:delegate]; +} + +- (RKRequest*)putObject:(NSObject*)object delegate:(NSObject*)delegate { + NSString* resourcePath = [_router pathForObject:object method:RKRequestMethodPUT]; + NSObject* params = [_router serializationForObject:object method:RKRequestMethodPUT]; + return [self resourceLoaderRequest:object resourcePath:resourcePath method:RKRequestMethodPUT params:params delegate:delegate]; +} + +- (RKRequest*)deleteObject:(NSObject*)object delegate:(NSObject*)delegate { + NSString* resourcePath = [_router pathForObject:object method:RKRequestMethodDELETE]; + NSObject* params = [_router serializationForObject:object method:RKRequestMethodDELETE]; + return [self resourceLoaderRequest:object resourcePath:resourcePath method:RKRequestMethodDELETE params:params delegate:delegate]; +} + +@end diff --git a/Code/RKModelMapper.m b/Code/RKResourceMapper.m similarity index 95% rename from Code/RKModelMapper.m rename to Code/RKResourceMapper.m index 17dfe3da..8f6a6b12 100644 --- a/Code/RKModelMapper.m +++ b/Code/RKResourceMapper.m @@ -8,16 +8,17 @@ #import -#import "RKModelMapper.h" +#import "RKResourceMapper.h" #import "NSDictionary+RKRequestSerialization.h" #import "RKMappingFormatJSONParser.h" // Default format string for date and time objects from Rails +// TODO: Rails specifics should probably move elsewhere... static const NSString* kRKModelMapperRailsDateTimeFormatString = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; // 2009-08-08T17:23:59Z static const NSString* kRKModelMapperRailsDateFormatString = @"MM/dd/yyyy"; static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatParser"; -@interface RKModelMapper (Private) +@interface RKResourceMapper (Private) - (void)updateModel:(id)model fromElements:(NSDictionary*)elements; @@ -37,7 +38,7 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP @end -@implementation RKModelMapper +@implementation RKResourceMapper @synthesize format = _format; @synthesize dateFormats = _dateFormats; @@ -66,7 +67,7 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP [super dealloc]; } -- (void)registerModel:(Class)aClass forElementNamed:(NSString*)elementName { +- (void)registerClass:(Class)aClass forElementNamed:(NSString*)elementName { [_elementToClassMappings setObject:aClass forKey:elementName]; } @@ -176,12 +177,14 @@ static const NSString* kRKModelMapperMappingFormatParserKey = @"RKMappingFormatP /////////////////////////////////////////////////////////////////////////////// // Persistent Instance Finders +// TODO: This responsibility probaby belongs elsewhere... - (id)findOrCreateInstanceOfModelClass:(Class)class fromElements:(NSDictionary*)elements { id object = nil; + // TODO: Maybe add back to RKResourceMappable protocol. better selectors? if ([class respondsToSelector:@selector(findByPrimaryKey:)]) { - NSString* primaryKeyElement = [class primaryKeyElement]; + NSString* primaryKeyElement = [class performSelector:@selector(primaryKeyElement)]; NSNumber* primaryKey = [elements objectForKey:primaryKeyElement]; - object = [class findByPrimaryKey:primaryKey]; + object = [class performSelector:@selector(findByPrimaryKey:) withObject:primaryKey]; } // instantiate if object is nil diff --git a/Code/RKStaticRouter.m b/Code/RKStaticRouter.m new file mode 100644 index 00000000..c7b52993 --- /dev/null +++ b/Code/RKStaticRouter.m @@ -0,0 +1,31 @@ +// +// RKStaticRouter.m +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKStaticRouter.h" + +@implementation RKStaticRouter + +- (void)routeClass:(Class)class toPath:(NSString*)resourcePath { + // Turn class name into a string + // Add subdictionary with class name +} + +- (void)routeClass:(Class)class toPath:(NSString*)resourcePath forMethod:(RKRequestMethod)method { +} + +#pragma mark RKRouter + +- (NSString*)pathForObject:(NSObject*)resource method:(RKRequestMethod)method { + return nil; +} + +- (NSObject*)serializationForObject:(NSObject*)resource method:(RKRequestMethod)method { + return nil; +} + +@end diff --git a/Code/RestKit/RKManagedModel.h b/Code/RestKit/RKManagedObject.h similarity index 79% rename from Code/RestKit/RKManagedModel.h rename to Code/RestKit/RKManagedObject.h index ba330147..b7a03b53 100644 --- a/Code/RestKit/RKManagedModel.h +++ b/Code/RestKit/RKManagedObject.h @@ -1,5 +1,5 @@ // -// RKManagedModel.h +// RKManagedObject.h // RestKit // // Created by Blake Watters on 8/14/09. @@ -8,15 +8,13 @@ #import #import -#import "RKModelMappableProtocol.h" -#import "RKModelManager.h" - -@class RKManagedModel; +#import "RKResourceMappable.h" +#import "RKResourceManager.h" ///////////////////////////////////////////////////////////////////////////////////////////////// // RestKit managed models -@interface RKManagedModel : NSManagedObject { +@interface RKManagedObject : NSManagedObject { } @@ -47,7 +45,7 @@ + (NSUInteger)count; /** - * Creates a new OTManagedModel and inserts it into the managedObjectContext. + * Creates a new managed object and inserts it into the managedObjectContext. */ + (id)newObject; @@ -78,19 +76,6 @@ */ + (id)findByPrimaryKey:(id)value; -/** - * Defines the properties which the OTModelMapper maps elements to - */ -+ (NSDictionary*)elementToPropertyMappings; - -/** - * Defines the relationship properties which the OTModelMapper maps elements to - * @"user" => @"user" will map the @"user" element to an NSObject* property @"user" - * @"memberships > user" => @"users" will map the @"user" elements in the @"memberships" element - * to an NSSet* property named @"users" - */ -+ (NSDictionary*)elementToRelationshipMappings; - /** * Returns all the XML/JSON element names for the properties of this model */ @@ -104,6 +89,7 @@ // The server side name of the model? // TODO: Should be registered on the model manager somehow... // TODO: Use entity name on managed model? +// TODO: Moves to the router probably... + (NSString*)modelName; /** diff --git a/Code/RestKit/RKModelLoader.h b/Code/RestKit/RKModelLoader.h deleted file mode 100644 index 5ff1354a..00000000 --- a/Code/RestKit/RKModelLoader.h +++ /dev/null @@ -1,70 +0,0 @@ -// -// RKModelLoader.h -// RestKit -// -// Created by Blake Watters on 8/8/09. -// Copyright 2009 Two Toasters. All rights reserved. -// - -#import -#import "RKRequest.h" -#import "RKResponse.h" -#import "RKModelMapper.h" - -@protocol RKModelLoaderDelegate - -/** - * Invoked when a request sent through the model manager loads a collection of models. The model will be nil if the request was - * not dispatched with a model object instance - */ -- (void)modelLoaderRequest:(RKRequest*)request didLoadModels:(NSArray*)models response:(RKResponse*)response modelObject:(id)modelObject; - -/** - * Invoked when a request sent through the model manager encounters an error. The model will be nil if the request was - * not dispatched with a model object instance - */ -- (void)modelLoaderRequest:(RKRequest*)request didFailWithError:(NSError*)error response:(RKResponse*)response modelObject:(id)modelObject; - -@end - -@interface RKModelLoader : NSObject { - RKModelMapper* _mapper; - NSObject* _delegate; - SEL _callback; - NSFetchRequest* _fetchRequest; -} - -/** - * The model mapper this loader is working with - */ -@property (nonatomic, readonly) RKModelMapper* mapper; - -/** - * The object to be invoked with the loaded models - * - * If this object implements life-cycle methods from the RKRequestDelegate protocol, - * events from the request will be forwarded back. - */ -@property (nonatomic, retain) NSObject* delegate; - -/** - * The method to invoke to trigger model mappings. Used as the callback for a restful model mapping request - */ -@property (nonatomic, readonly) SEL callback; - -/** - * Fetch request for loading cached objects. This is used to remove objects from the local persistent store - * when model mapping operations are completed. - * - * TODO: May belong in an inherited subclass to isolate persistent/non-persistent mapping in the future. - */ -@property (nonatomic, retain) NSFetchRequest* fetchRequest; - -+ (id)loaderWithMapper:(RKModelMapper*)mapper; - -/** - * Initialize a new model loader with a model mapper - */ -- (id)initWithMapper:(RKModelMapper*)mapper; - -@end diff --git a/Code/RestKit/RKModelManager.h b/Code/RestKit/RKModelManager.h deleted file mode 100644 index 38bc82d9..00000000 --- a/Code/RestKit/RKModelManager.h +++ /dev/null @@ -1,137 +0,0 @@ -// -// RKModelManager.h -// RestKit -// -// Created by Jeremy Ellison on 8/14/09. -// Copyright 2009 Two Toasters. All rights reserved. -// - -#import "RKModelMapper.h" -#import "RKClient.h" -#import "RKManagedObjectStore.h" -#import "RKModelLoader.h" - -// Notifications -extern NSString* const RKDidEnterOfflineModeNotification; -extern NSString* const RKDidEnterOnlineModeNotification; - -@interface RKModelManager : NSObject { - RKClient* _client; - RKModelMapper* _mapper; - RKManagedObjectStore* _objectStore; - RKMappingFormat _format; - BOOL _isOnline; -} - -/** - * Return the shared instance of the model manager - */ -+ (RKModelManager*)manager; - -/** - * Set the shared instance of the model manager - */ -+ (void)setManager:(RKModelManager*)manager; - -/** - * Create and initialize a new model manager. If this is the first instance created - * it will be set as the shared instance - */ -+ (RKModelManager*)managerWithBaseURL:(NSString*)baseURL; - -/** - * Initialize a new model manager instance - */ -- (id)initWithBaseURL:(NSString*)baseURL; - -/** - * The wire format to use for communications. Either RKMappingFormatXML or RKMappingFormatJSON. - * - * Defaults to RKMappingFormatXML - */ -@property(nonatomic, assign) RKMappingFormat format; - -/** - * The REST client for this manager - */ -@property (nonatomic, retain) RKClient* client; - -/** - * Puts the manager into offline mode. Requests will not be sent. - */ -- (void)goOffline; - -/** - * Puts the manager into online mode. Requests will be sent. - */ -- (void)goOnline; - -/** - * True when we are in online mode - */ -- (BOOL)isOnline; - -/** - * Register a model mapping from a domain model class to an XML element name - */ -- (void)registerModel:(Class)class forElementNamed:(NSString*)elementName; - -/** - * The model mapper for this manager - */ -@property(nonatomic, readonly) RKModelMapper* mapper; - -/** - * A Core Data backed object store for persisting objects that have been fetched from the Web - */ -@property(nonatomic, retain) RKManagedObjectStore* objectStore; - -/** - * Fetch a resource via an HTTP GET and invoke a callback with the model for the resulting payload - */ -- (RKRequest*)loadModels:(NSString*)resourcePath delegate:(NSObject*)delegate; - -// Load via a method... -- (RKRequest*)loadModels:(NSString*)resourcePath method:(RKRequestMethod)method delegate:(NSObject*)delegate; - -/** - * Fetch a resource via a specified HTTP method - */ -- (RKRequest*)loadModels:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate; - -/** - * Fetch a resource via an HTTP GET with a dictionary of parameters and invoke a callback with the models mapped from the payload - */ -- (RKRequest*)loadModels:(NSString*)resourcePath params:(NSDictionary*)params delegate:(NSObject*)delegate; - -/** - * Fetch methods for clients that implement local caching - */ -- (RKRequest*)loadModels:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method delegate:(NSObject*)delegate; - -- (RKRequest*)loadModels:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate; - -//////////////////////////////////////////////////////// -// Model Mappable object helpers - -/** - * Update a mappable model by loading its attributes from the web - */ -- (RKRequest*)getModel:(id)model delegate:(NSObject*)delegate; - -/** - * Create a remote mappable model by POSTing the attributes to the remote resource and loading the resulting model from the payload - */ -- (RKRequest*)postModel:(id)model delegate:(NSObject*)delegate; - -/** - * Update a remote mappable model by PUTing the attributes to the remote resource and loading the resulting model from the payload - */ -- (RKRequest*)putModel:(id)model delegate:(NSObject*)delegate; - -/** - * Delete the remote instance of a mappable model by performing an HTTP DELETE on the remote resource - */ -- (RKRequest*)deleteModel:(id)model delegate:(NSObject*)delegate; - -@end diff --git a/Code/RestKit/RKObject.h b/Code/RestKit/RKObject.h new file mode 100644 index 00000000..c8beafdc --- /dev/null +++ b/Code/RestKit/RKObject.h @@ -0,0 +1,18 @@ +// +// RKResource.h +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKResourceMappable.h" + +/** + * Base class for non-managed RestKit mappable objects. + */ +@interface RKObject : NSObject { + +} + +@end diff --git a/Code/RestKit/RKModelSeeder.h b/Code/RestKit/RKObjectSeeder.h similarity index 75% rename from Code/RestKit/RKModelSeeder.h rename to Code/RestKit/RKObjectSeeder.h index 656b3025..45846485 100644 --- a/Code/RestKit/RKModelSeeder.h +++ b/Code/RestKit/RKObjectSeeder.h @@ -6,16 +6,16 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKModelManager.h" +#import "RKResourceManager.h" -@interface RKModelSeeder : NSObject { - RKModelManager* _manager; +@interface RKObjectSeeder : NSObject { + RKResourceManager* _manager; } /** * Initialize a new model seeder */ -- (id)initWithModelManager:(RKModelManager*)manager; +- (id)initWithResourceManager:(RKResourceManager*)manager; /** * Read a file from the main bundle and seed the database with its contents. diff --git a/Code/RestKit/RKResourceLoader.h b/Code/RestKit/RKResourceLoader.h new file mode 100644 index 00000000..ec9a3a6e --- /dev/null +++ b/Code/RestKit/RKResourceLoader.h @@ -0,0 +1,70 @@ +// +// RKResourceLoader.h +// RestKit +// +// Created by Blake Watters on 8/8/09. +// Copyright 2009 Two Toasters. All rights reserved. +// + +#import +#import "RKRequest.h" +#import "RKResponse.h" +#import "RKResourceMapper.h" + +@protocol RKResourceLoaderDelegate + +/** + * Invoked when a request sent through the resource manager loads a collection of objects. The model will be nil if the request was + * not dispatched through an object + */ +- (void)resourceLoadRequest:(RKRequest*)request didLoadObjects:(NSArray*)objects response:(RKResponse*)response object:(id)object; + +/** + * Invoked when a request sent through the resource manager encounters an error. The model will be nil if the request was + * not dispatched through an object + */ +- (void)resourceLoadRequest:(RKRequest*)request didFailWithError:(NSError*)error response:(RKResponse*)response object:(id)object; + +@end + +@interface RKResourceLoader : NSObject { + RKResourceMapper* _mapper; + NSObject* _delegate; + SEL _callback; + NSFetchRequest* _fetchRequest; +} + +/** + * The resource mapper this loader is working with + */ +@property (nonatomic, readonly) RKResourceMapper* mapper; + +/** + * The object to be invoked with the loaded models + * + * If this object implements life-cycle methods from the RKRequestDelegate protocol, + * events from the request will be forwarded back. + */ +@property (nonatomic, retain) NSObject* delegate; + +/** + * The method to invoke to trigger model mappings. Used as the callback for a restful model mapping request + */ +@property (nonatomic, readonly) SEL callback; + +/** + * Fetch request for loading cached objects. This is used to remove objects from the local persistent store + * when model mapping operations are completed. + * + * TODO: May belong in an inherited subclass to isolate persistent/non-persistent mapping in the future. + */ +@property (nonatomic, retain) NSFetchRequest* fetchRequest; + ++ (id)loaderWithMapper:(RKResourceMapper*)mapper; + +/** + * Initialize a new model loader with a model mapper + */ +- (id)initWithMapper:(RKResourceMapper*)mapper; + +@end diff --git a/Code/RestKit/RKResourceManager.h b/Code/RestKit/RKResourceManager.h new file mode 100644 index 00000000..62d4c7b6 --- /dev/null +++ b/Code/RestKit/RKResourceManager.h @@ -0,0 +1,147 @@ +// +// RKResourceManager.h +// RestKit +// +// Created by Jeremy Ellison on 8/14/09. +// Copyright 2009 Two Toasters. All rights reserved. +// + +#import "RKClient.h" +#import "RKResourceMapper.h" +#import "RKResourceLoader.h" +#import "RKStaticRouter.h" +#import "RKManagedObjectStore.h" + +// Notifications +extern NSString* const RKDidEnterOfflineModeNotification; +extern NSString* const RKDidEnterOnlineModeNotification; + +@interface RKResourceManager : NSObject { + RKClient* _client; + RKMappingFormat _format; + RKResourceMapper* _mapper; + NSObject* _router; + RKManagedObjectStore* _objectStore; + BOOL _isOnline; +} + +/** + * Return the shared instance of the model manager + */ ++ (RKResourceManager*)manager; + +/** + * Set the shared instance of the model manager + */ ++ (void)setManager:(RKResourceManager*)manager; + +/** + * Create and initialize a new model manager. If this is the first instance created + * it will be set as the shared instance + */ ++ (RKResourceManager*)managerWithBaseURL:(NSString*)baseURL; + +/** + * Initialize a new model manager instance + */ +- (id)initWithBaseURL:(NSString*)baseURL; + +/** + * The wire format to use for communications. Either RKMappingFormatXML or RKMappingFormatJSON. + * + * Defaults to RKMappingFormatXML + */ +@property(nonatomic, assign) RKMappingFormat format; + +/** + * The REST client for this manager + */ +@property (nonatomic, retain) RKClient* client; + +/** + * Puts the manager into offline mode. Requests will not be sent. + */ +- (void)goOffline; + +/** + * Puts the manager into online mode. Requests will be sent. + */ +- (void)goOnline; + +/** + * True when we are in online mode + */ +- (BOOL)isOnline; + +/** + * Register a resource mapping from a domain model class to a JSON/XML element name + */ +- (void)registerClass:(Class)class forElementNamed:(NSString*)elementName; + +/** + * Mapper object responsible for mapping remote HTTP resources to Cocoa objects + */ +@property(nonatomic, readonly) RKResourceMapper* mapper; + +/** + * Routing object responsible for generating paths for objects and serializing + * representations of the object for transport. + * + * Defaults to an instance of RKStaticRouter + */ +@property(nonatomic, retain) NSObject* router; + +/** + * A Core Data backed object store for persisting objects that have been fetched from the Web + */ +@property(nonatomic, retain) RKManagedObjectStore* objectStore; + +/** + * Fetch a resource via an HTTP GET and invoke a callback with the model for the resulting payload + */ +- (RKRequest*)loadResource:(NSString*)resourcePath delegate:(NSObject*)delegate; + +// Load via a method... +- (RKRequest*)loadResource:(NSString*)resourcePath method:(RKRequestMethod)method delegate:(NSObject*)delegate; + +/** + * Fetch a resource via a specified HTTP method + */ +- (RKRequest*)loadResource:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate; + +/** + * Fetch a resource via an HTTP GET with a dictionary of parameters and invoke a callback with the models mapped from the payload + */ +- (RKRequest*)loadResource:(NSString*)resourcePath params:(NSDictionary*)params delegate:(NSObject*)delegate; + +/** + * Fetch methods for clients that implement local caching + */ +- (RKRequest*)loadResource:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method delegate:(NSObject*)delegate; + +- (RKRequest*)loadResource:(NSString*)resourcePath fetchRequest:(NSFetchRequest*)fetchRequest method:(RKRequestMethod)method params:(NSObject*)params delegate:(NSObject*)delegate; + +//////////////////////////////////////////////////////// +// Model Mappable object helpers + +/** + * Update a mappable model by loading its attributes from the web + */ +- (RKRequest*)getObject:(NSObject*)object delegate:(NSObject*)delegate; + +/** + * Create a remote mappable model by POSTing the attributes to the remote resource and loading the resulting model from the payload + */ +- (RKRequest*)postObject:(NSObject*)object delegate:(NSObject*)delegate; + +/** + * Update a remote mappable model by PUTing the attributes to the remote resource and loading the resulting model from the payload + */ +- (RKRequest*)putObject:(NSObject*)object delegate:(NSObject*)delegate; + +/** + * Delete the remote instance of a mappable model by performing an HTTP DELETE on the remote resource + */ +- (RKRequest*)deleteObject:(NSObject*)object delegate:(NSObject*)delegate; + +@end diff --git a/Code/RestKit/RKModelMappableProtocol.h b/Code/RestKit/RKResourceMappable.h similarity index 69% rename from Code/RestKit/RKModelMappableProtocol.h rename to Code/RestKit/RKResourceMappable.h index 3bc63628..2245926e 100644 --- a/Code/RestKit/RKModelMappableProtocol.h +++ b/Code/RestKit/RKResourceMappable.h @@ -1,5 +1,5 @@ /* - * RKModelMappableProtocol.h + * RKResourceMappable.h * RestKit * * Created by Blake Watters on 8/14/09. @@ -9,6 +9,7 @@ #import "RKRequest.h" +// TODO: De-emphasize this and move... typedef enum { RKMappingFormatXML = 0, RKMappingFormatJSON @@ -18,7 +19,7 @@ typedef enum { * Must be implemented by all classes utilizing the RKModelMapper to map REST * responses to domain model classes */ -@protocol RKModelMappable +@protocol RKResourceMappable /** * Must return a dictionary containing mapping from XML element names to property accessors @@ -42,23 +43,11 @@ typedef enum { */ + (NSDictionary*)elementToRelationshipMappings; -// TODO: Add an errors property. This will be populated when there are errors in the mapping. +// TODO: Add an optional errors property. This will be populated when there are errors in the mapping. +// TODO: resourceParams/resourceAttributes? @optional -// TODO: Should the path/params stuff live on a different protocol? RKResource? RKManagedModel implements RKModelMappable. RKRailsResourceAdapter for path/params stuff - -/** - * Return the resourcePath for the specified HTTP method - */ -- (NSString*)resourcePathForMethod:(RKRequestMethod)method; - -/** - * Returns representation of the model parameters. - */ -// TODO: Better method signature -- (NSObject*)resourceSerializationForMethod:(RKRequestMethod)method; - /** * Must return a new instance of the model class ready for mapping. Used to initialize the model * via any method other than alloc & init. diff --git a/Code/RestKit/RKModelMapper.h b/Code/RestKit/RKResourceMapper.h similarity index 93% rename from Code/RestKit/RKModelMapper.h rename to Code/RestKit/RKResourceMapper.h index 675e7ba6..ce679c57 100644 --- a/Code/RestKit/RKModelMapper.h +++ b/Code/RestKit/RKResourceMapper.h @@ -1,5 +1,5 @@ // -// RKModelMapper.h +// RKResourceMapper.h // RestKit // // Created by Blake Watters on 3/4/10. @@ -7,7 +7,7 @@ // #import -#import "RKModelMappableProtocol.h" +#import "RKResourceMappable.h" #import "RKObjectPropertyInspector.h" /** @@ -26,7 +26,7 @@ @end -@interface RKModelMapper : NSObject { +@interface RKResourceMapper : NSObject { NSMutableDictionary* _elementToClassMappings; RKMappingFormat _format; RKObjectPropertyInspector* _inspector; @@ -67,7 +67,7 @@ * Register a mapping for a given class for an XML element with the given tag name * will blow up if the class does not respond to elementToPropertyMappings and elementToRelationshipMappings */ -- (void)registerModel:(Class)aClass forElementNamed:(NSString*)elementName; +- (void)registerClass:(Class)aClass forElementNamed:(NSString*)elementName; /////////////////////////////////////////////////////////////////////////////// // Core Mapping API diff --git a/Code/RestKit/RKRouter.h b/Code/RestKit/RKRouter.h new file mode 100644 index 00000000..af06bb45 --- /dev/null +++ b/Code/RestKit/RKRouter.h @@ -0,0 +1,29 @@ +// +// RKRouter.h +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKRequest.h" +#import "RKResourceMappable.h" +#import "RKRequestSerializable.h" + +/** + * Defines a protocol for mapping Cocoa objects to remote resource locations and + * serializables representations. + */ +@protocol RKRouter + +/** + * Returns the remote path to send requests for a given object and HTTP method + */ +- (NSString*)pathForObject:(NSObject*)resource method:(RKRequestMethod)method; + +/** + * Returns a serialization of an object suitable for exchanging with a remote system + */ +- (NSObject*)serializationForObject:(NSObject*)resource method:(RKRequestMethod)method; + +@end diff --git a/Code/RestKit/RKStaticRouter.h b/Code/RestKit/RKStaticRouter.h new file mode 100644 index 00000000..03d1a8fc --- /dev/null +++ b/Code/RestKit/RKStaticRouter.h @@ -0,0 +1,25 @@ +// +// RKStaticRouter.h +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKRouter.h" +#import "RKResourceMappable.h" + +@interface RKStaticRouter : NSObject { +} + +/** + * Register a static mapping from an object class to a resource path + */ +- (void)routeClass:(Class)class toPath:(NSString*)resourcePath; + +/** + * Register a static mapping from an object class to a resource path for a given HTTP method + */ +- (void)routeClass:(Class)class toPath:(NSString*)resourcePath forMethod:(RKRequestMethod)method; + +@end diff --git a/Code/RestKit/RestKit.h b/Code/RestKit/RestKit.h index 1d3cabea..f1760171 100644 --- a/Code/RestKit/RestKit.h +++ b/Code/RestKit/RestKit.h @@ -8,7 +8,7 @@ #import "RestKit/RKClient.h" #import "RestKit/Errors.h" -#import "RestKit/RKModelManager.h" -#import "RestKit/RKManagedModel.h" +#import "RestKit/RKResourceManager.h" +#import "RestKit/RKManagedObject.h" #import "RestKit/RKNotifications.h" -#import "RestKit/RKModelSeeder.h" +#import "RestKit/RKObjectSeeder.h" diff --git a/Code/RestKit/Three20/RKRequestModel.h b/Code/RestKit/Three20/RKRequestModel.h index 25f5ac8a..8b57bcec 100644 --- a/Code/RestKit/Three20/RKRequestModel.h +++ b/Code/RestKit/Three20/RKRequestModel.h @@ -25,7 +25,7 @@ /** * Generic class for loading a remote model using a RestKit request */ -@interface RKRequestModel : NSObject { +@interface RKRequestModel : NSObject { NSArray *_objects; BOOL _loaded; diff --git a/RestKit_Prefix.pch b/Code/RestKit_Prefix.pch similarity index 100% rename from RestKit_Prefix.pch rename to Code/RestKit_Prefix.pch diff --git a/RestKit.xcodeproj/project.pbxproj b/RestKit.xcodeproj/project.pbxproj index 38bf0685..4ac5869a 100644 --- a/RestKit.xcodeproj/project.pbxproj +++ b/RestKit.xcodeproj/project.pbxproj @@ -7,6 +7,17 @@ objects = { /* Begin PBXBuildFile section */ + 250429A911F62E0200553519 /* UISpec+UISpecRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 250429A811F62E0200553519 /* UISpec+UISpecRunner.m */; }; + 250BBF9A11F5FFF500F3FE5A /* RKObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 250BBF9811F5FFF500F3FE5A /* RKObject.h */; }; + 250BBF9B11F5FFF500F3FE5A /* RKObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 250BBF9911F5FFF500F3FE5A /* RKObject.m */; }; + 250BBFAF11F606D300F3FE5A /* RKRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 250BBFAD11F606D300F3FE5A /* RKRouter.h */; }; + 250BBFC311F608DB00F3FE5A /* RKStaticRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 250BBFC111F608DB00F3FE5A /* RKStaticRouter.h */; }; + 250BBFC411F608DB00F3FE5A /* RKStaticRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 250BBFC211F608DB00F3FE5A /* RKStaticRouter.m */; }; + 250BC22211F620F700F3FE5A /* RKObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 250BBF9911F5FFF500F3FE5A /* RKObject.m */; }; + 250BC22311F620F900F3FE5A /* RKStaticRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 250BBFC211F608DB00F3FE5A /* RKStaticRouter.m */; }; + 250BC22B11F621B400F3FE5A /* RKStaticRouterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 250BC22A11F621B400F3FE5A /* RKStaticRouterSpec.m */; }; + 250BC51111F62D6B00F3FE5A /* UISpec.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 250BC50A11F62D6B00F3FE5A /* UISpec.bundle */; }; + 250BC51211F62D6B00F3FE5A /* UISpec_1_0.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 250BC51011F62D6B00F3FE5A /* UISpec_1_0.a */; }; 2520776E113587BE00382018 /* NSDictionary+RKRequestSerializationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 2520776D113587BE00382018 /* NSDictionary+RKRequestSerializationSpec.m */; }; 25232D4F11E62C470048F9B4 /* RKJSONSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 25232D4D11E62C470048F9B4 /* RKJSONSerialization.h */; }; 25232D5011E62C470048F9B4 /* RKJSONSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 25232D4E11E62C470048F9B4 /* RKJSONSerialization.m */; }; @@ -26,13 +37,13 @@ 2525EBEC106961DD0069EBED /* RKManagedObjectStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 2525EBEA106961DD0069EBED /* RKManagedObjectStore.m */; }; 2525F9A0106C0FF40069EBED /* RKNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 2525F99E106C0FF40069EBED /* RKNotifications.h */; }; 2525F9A1106C0FF40069EBED /* RKNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 2525F99F106C0FF40069EBED /* RKNotifications.m */; }; - 252F4CC0114021B5003C6F42 /* RKModelSeeder.h in Headers */ = {isa = PBXBuildFile; fileRef = 252F4CBE114021B5003C6F42 /* RKModelSeeder.h */; }; - 252F4CC1114021B5003C6F42 /* RKModelSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4CBF114021B5003C6F42 /* RKModelSeeder.m */; }; - 252F4CC2114021B5003C6F42 /* RKModelSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4CBF114021B5003C6F42 /* RKModelSeeder.m */; }; - 252F4F9D11404322003C6F42 /* RKModelLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2580B067102E0F1000832D07 /* RKModelLoader.m */; }; - 252F4FA01140433D003C6F42 /* RKModelMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4F9F1140433D003C6F42 /* RKModelMapper.m */; }; - 252F4FA11140433D003C6F42 /* RKModelMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 252F4F9E1140433D003C6F42 /* RKModelMapper.h */; }; - 252F4FA21140433D003C6F42 /* RKModelMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4F9F1140433D003C6F42 /* RKModelMapper.m */; }; + 252F4CC0114021B5003C6F42 /* RKObjectSeeder.h in Headers */ = {isa = PBXBuildFile; fileRef = 252F4CBE114021B5003C6F42 /* RKObjectSeeder.h */; }; + 252F4CC1114021B5003C6F42 /* RKObjectSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4CBF114021B5003C6F42 /* RKObjectSeeder.m */; }; + 252F4CC2114021B5003C6F42 /* RKObjectSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4CBF114021B5003C6F42 /* RKObjectSeeder.m */; }; + 252F4F9D11404322003C6F42 /* RKResourceLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2580B067102E0F1000832D07 /* RKResourceLoader.m */; }; + 252F4FA01140433D003C6F42 /* RKResourceMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4F9F1140433D003C6F42 /* RKResourceMapper.m */; }; + 252F4FA11140433D003C6F42 /* RKResourceMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 252F4F9E1140433D003C6F42 /* RKResourceMapper.h */; }; + 252F4FA21140433D003C6F42 /* RKResourceMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4F9F1140433D003C6F42 /* RKResourceMapper.m */; }; 252F4FA9114046C9003C6F42 /* RKMappingFormatJSONParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 252F4FA7114046C9003C6F42 /* RKMappingFormatJSONParser.h */; }; 252F4FAA114046C9003C6F42 /* RKMappingFormatJSONParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4FA8114046C9003C6F42 /* RKMappingFormatJSONParser.m */; }; 252F4FAB114046C9003C6F42 /* RKMappingFormatJSONParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 252F4FA8114046C9003C6F42 /* RKMappingFormatJSONParser.m */; }; @@ -43,9 +54,9 @@ 253BBE971076AB1C00C804B2 /* NSString+InflectionSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 253BBE951076AB1C00C804B2 /* NSString+InflectionSupport.m */; }; 255DE05A10FF9DA500A85891 /* RKModelManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE05910FF9DA500A85891 /* RKModelManagerSpec.m */; }; 255DE05E10FFA05800A85891 /* RKHuman.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE05D10FFA05800A85891 /* RKHuman.m */; }; - 255DE0DB10FFAB7700A85891 /* RKModelManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FBF1D38103614E500E307AC /* RKModelManager.m */; }; + 255DE0DB10FFAB7700A85891 /* RKResourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FBF1D38103614E500E307AC /* RKResourceManager.m */; }; 255DE0DD10FFAB7E00A85891 /* RKManagedObjectStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 2525EBEA106961DD0069EBED /* RKManagedObjectStore.m */; }; - 255DE0DE10FFAB7F00A85891 /* RKManagedModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FCDDDA1035BC85005418A7 /* RKManagedModel.m */; }; + 255DE0DE10FFAB7F00A85891 /* RKManagedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FCDDDA1035BC85005418A7 /* RKManagedObject.m */; }; 255DE0E210FFABA500A85891 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 255DE0E110FFABA500A85891 /* CoreData.framework */; }; 255DE0E510FFABBB00A85891 /* RKResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18F1102DD38800320118 /* RKResponse.m */; }; 255DE0E610FFABBC00A85891 /* RKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18EE102DD38700320118 /* RKRequest.m */; }; @@ -59,25 +70,23 @@ 255DE0F010FFABE500A85891 /* NSDictionary+RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E1919102DD42F00320118 /* NSDictionary+RKRequestSerialization.m */; }; 255DE0F410FFAC0A00A85891 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 255DE0F310FFAC0A00A85891 /* SystemConfiguration.framework */; }; 255DE1B110FFB16800A85891 /* RKSpecResponseLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE1B010FFB16800A85891 /* RKSpecResponseLoader.m */; }; - 255DE37810FFC26900A85891 /* RKClientSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE37710FFC26900A85891 /* RKClientSpec.m */; }; 255DE43211010EE700A85891 /* RKRequestSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE43111010EE700A85891 /* RKRequestSpec.m */; }; 255DE43B11010F8400A85891 /* RKResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE43A11010F8400A85891 /* RKResponseSpec.m */; }; - 255DE453110112DB00A85891 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 255DE449110112DB00A85891 /* OCMock.framework */; }; - 255DE4931101134300A85891 /* OCMock.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 255DE449110112DB00A85891 /* OCMock.framework */; }; 255DE62B1104BA2B00A85891 /* RKModelMapperSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3AD010FE76C1008F47C5 /* RKModelMapperSpec.m */; }; - 255DE62C1104BA2D00A85891 /* RKManagedModelSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE03010FF9BDF00A85891 /* RKManagedModelSpec.m */; }; + 255DE62C1104BA2D00A85891 /* RKManagedObjectSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 255DE03010FF9BDF00A85891 /* RKManagedObjectSpec.m */; }; 256FD523112C6A340077F340 /* Data Model.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 256FD522112C6A340077F340 /* Data Model.xcdatamodel */; }; 256FD651112C7B780077F340 /* RKMappableObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FD64F112C7B780077F340 /* RKMappableObject.m */; }; 256FD652112C7B780077F340 /* RKMappableAssociation.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FD650112C7B780077F340 /* RKMappableAssociation.m */; }; - 256FDE55112DB0B90077F340 /* RKModelMapperSpecModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */; }; - 2580B068102E0F1000832D07 /* RKModelLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 2580B066102E0F1000832D07 /* RKModelLoader.h */; }; - 2580B069102E0F1000832D07 /* RKModelLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2580B067102E0F1000832D07 /* RKModelLoader.m */; }; + 256FDE55112DB0B90077F340 /* RKResourceMapperSpecModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 256FDE54112DB0B90077F340 /* RKResourceMapperSpecModel.m */; }; + 257EA42011F6317A00DB04C3 /* libOCMock-iPhone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 257EA41C11F6317600DB04C3 /* libOCMock-iPhone.a */; }; + 2580B068102E0F1000832D07 /* RKResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 2580B066102E0F1000832D07 /* RKResourceLoader.h */; }; + 2580B069102E0F1000832D07 /* RKResourceLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2580B067102E0F1000832D07 /* RKResourceLoader.m */; }; 25B86E0A115BEB71009761A1 /* Errors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B86E09115BEB71009761A1 /* Errors.h */; }; 25B86EDE115BEFE8009761A1 /* Errors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B86EDD115BEFE8009761A1 /* Errors.m */; }; 25B86EE0115BEFE8009761A1 /* Errors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B86EDD115BEFE8009761A1 /* Errors.m */; }; - 25FCDDDB1035BC85005418A7 /* RKManagedModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FCDDD91035BC85005418A7 /* RKManagedModel.h */; }; - 25FCDDDC1035BC85005418A7 /* RKManagedModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FCDDDA1035BC85005418A7 /* RKManagedModel.m */; }; - 25FCDE9C1035E901005418A7 /* RKModelMappableProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FCDE9B1035E901005418A7 /* RKModelMappableProtocol.h */; }; + 25FCDDDB1035BC85005418A7 /* RKManagedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FCDDD91035BC85005418A7 /* RKManagedObject.h */; }; + 25FCDDDC1035BC85005418A7 /* RKManagedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FCDDDA1035BC85005418A7 /* RKManagedObject.m */; }; + 25FCDE9C1035E901005418A7 /* RKResourceMappable.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FCDE9B1035E901005418A7 /* RKResourceMappable.h */; }; 3F032A7910FFB89100F35142 /* RKCat.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F032A7810FFB89100F35142 /* RKCat.m */; }; 3F032AA810FFBBCD00F35142 /* RKHouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F032AA710FFBBCD00F35142 /* RKHouse.m */; }; 3F032AAB10FFBC1F00F35142 /* RKResident.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F032AAA10FFBC1F00F35142 /* RKResident.m */; }; @@ -98,12 +107,11 @@ 3F4E1900102DD38800320118 /* RKResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E18F1102DD38800320118 /* RKResponse.m */; }; 3F4E191A102DD42F00320118 /* NSDictionary+RKRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F4E1918102DD42F00320118 /* NSDictionary+RKRequestSerialization.h */; }; 3F4E191B102DD42F00320118 /* NSDictionary+RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F4E1919102DD42F00320118 /* NSDictionary+RKRequestSerialization.m */; }; - 3F6C39C510FE73B3008F47C5 /* UISpec_Simulator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F6C39BD10FE738A008F47C5 /* UISpec_Simulator.a */; }; 3F6C3A2E10FE749C008F47C5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F6C3A2D10FE749C008F47C5 /* Foundation.framework */; }; 3F6C3A9410FE7519008F47C5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F6C3A9310FE7519008F47C5 /* main.m */; }; 3F6C3A9610FE7524008F47C5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F6C3A9510FE7524008F47C5 /* UIKit.framework */; }; - 3FBF1D39103614E500E307AC /* RKModelManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FBF1D37103614E500E307AC /* RKModelManager.h */; }; - 3FBF1D3A103614E500E307AC /* RKModelManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FBF1D38103614E500E307AC /* RKModelManager.m */; }; + 3FBF1D39103614E500E307AC /* RKResourceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FBF1D37103614E500E307AC /* RKResourceManager.h */; }; + 3FBF1D3A103614E500E307AC /* RKResourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FBF1D38103614E500E307AC /* RKResourceManager.m */; }; 739573C211BC15E700F44055 /* NSObject+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 739573BC11BC15E700F44055 /* NSObject+SBJSON.m */; }; 739573C311BC15E700F44055 /* NSString+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 739573BD11BC15E700F44055 /* NSString+SBJSON.m */; }; 739573C411BC15E700F44055 /* SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 739573BE11BC15E700F44055 /* SBJSON.m */; }; @@ -128,34 +136,118 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 3F6C39BC10FE738A008F47C5 /* PBXContainerItemProxy */ = { + 25042B8211F62FF500553519 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042A9511F62F2400553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = OCMock; + }; + 25042B8411F62FF500553519 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042A9511F62F2400553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 03BF2D3708F1C69500978C59; + remoteInfo = OCMockTests; + }; + 25042C5711F6309000553519 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042C5011F6309000553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = OCMock; + }; + 25042C5911F6309000553519 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042C5011F6309000553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 03BF2D3708F1C69500978C59; + remoteInfo = OCMockTests; + }; + 250BC43211F6260100F3FE5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */; proxyType = 2; remoteGlobalIDString = C76EB5D20F74586B00EF8398; remoteInfo = UISpec_Simulator; }; - 3F6C39BE10FE738A008F47C5 /* PBXContainerItemProxy */ = { + 250BC43411F6260100F3FE5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */; proxyType = 2; remoteGlobalIDString = C76EB5DA0F7458C100EF8398; remoteInfo = UISpec_Device; }; - 3F6C3A9B10FE753B008F47C5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = C76EB5D10F74586B00EF8398; - remoteInfo = UISpec_Simulator; - }; - 3FF0DF4410FE7CEA008901F7 /* PBXContainerItemProxy */ = { + 250BC43611F6260100F3FE5A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */; proxyType = 2; remoteGlobalIDString = C7D4F29310BDA39C00B00019; remoteInfo = Specs; }; + 250BC45211F6262600F3FE5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC36211F625DF00F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = OCMock; + }; + 250BC45411F6262600F3FE5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC36211F625DF00F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 03BF2D3708F1C69500978C59; + remoteInfo = OCMockTests; + }; + 250BC4E311F62D4400F3FE5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC43F11F6261700F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = OCMock; + }; + 250BC4E511F62D4400F3FE5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC43F11F6261700F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 03BF2D3708F1C69500978C59; + remoteInfo = OCMockTests; + }; + 257EA41B11F6317600DB04C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042C5011F6309000553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3F45512511E4BCD700AE56A6 /* libOCMock-iPhone.a */; + remoteInfo = "OCMock-iPhone"; + }; + 257EA42D11F6319800DB04C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042A9511F62F2400553519 /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3F45512511E4BCD700AE56A6 /* libOCMock-iPhone.a */; + remoteInfo = "OCMock-iPhone"; + }; + 257EA43211F6319800DB04C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC43F11F6261700F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3F45512511E4BCD700AE56A6 /* libOCMock-iPhone.a */; + remoteInfo = "OCMock-iPhone"; + }; + 257EA43711F6319800DB04C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 250BC36211F625DF00F3FE5A /* OCMock.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3F45512511E4BCD700AE56A6 /* libOCMock-iPhone.a */; + remoteInfo = "OCMock-iPhone"; + }; + 257EA5A511F632D700DB04C3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 25042A9511F62F2400553519 /* OCMock.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 3F45512411E4BCD700AE56A6 /* OCMock-iPhone */; + remoteInfo = "OCMock-iPhone"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -165,13 +257,55 @@ dstPath = "$(BUILT_PRODUCTS_DIR)"; dstSubfolderSpec = 0; files = ( - 255DE4931101134300A85891 /* OCMock.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 250429A711F62E0200553519 /* UISpec+UISpecRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISpec+UISpecRunner.h"; sourceTree = ""; }; + 250429A811F62E0200553519 /* UISpec+UISpecRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISpec+UISpecRunner.m"; sourceTree = ""; }; + 25042A9511F62F2400553519 /* OCMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OCMock.xcodeproj; path = /Users/blake/Projects/two_toasters/InMotion/Libraries/RestKit/Specs/Support/OCMock/Source/OCMock.xcodeproj; sourceTree = ""; }; + 25042C5011F6309000553519 /* OCMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OCMock.xcodeproj; path = OCMock/Source/OCMock.xcodeproj; sourceTree = ""; }; + 250BBF9811F5FFF500F3FE5A /* RKObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKObject.h; path = Code/RestKit/RKObject.h; sourceTree = ""; }; + 250BBF9911F5FFF500F3FE5A /* RKObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKObject.m; path = Code/RKObject.m; sourceTree = ""; }; + 250BBFAD11F606D300F3FE5A /* RKRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKRouter.h; path = Code/RestKit/RKRouter.h; sourceTree = ""; }; + 250BBFC111F608DB00F3FE5A /* RKStaticRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKStaticRouter.h; path = Code/RestKit/RKStaticRouter.h; sourceTree = ""; }; + 250BBFC211F608DB00F3FE5A /* RKStaticRouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKStaticRouter.m; path = Code/RKStaticRouter.m; sourceTree = ""; }; + 250BC22A11F621B400F3FE5A /* RKStaticRouterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKStaticRouterSpec.m; sourceTree = ""; }; + 250BC36211F625DF00F3FE5A /* OCMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OCMock.xcodeproj; path = /Users/blake/Projects/two_toasters/InMotion/Libraries/RestKit/Specs/Support/OCMock/Source/OCMock.xcodeproj; sourceTree = ""; }; + 250BC43F11F6261700F3FE5A /* OCMock.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OCMock.xcodeproj; path = /Users/blake/Projects/two_toasters/InMotion/Libraries/RestKit/Specs/Support/OCMock/Source/OCMock.xcodeproj; sourceTree = ""; }; + 250BC4ED11F62D6B00F3FE5A /* CallCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallCache.h; sourceTree = ""; }; + 250BC4EE11F62D6B00F3FE5A /* NSNumberCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSNumberCreator.h; sourceTree = ""; }; + 250BC4EF11F62D6B00F3FE5A /* Recordable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Recordable.h; sourceTree = ""; }; + 250BC4F011F62D6B00F3FE5A /* ReturnCacher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReturnCacher.h; sourceTree = ""; }; + 250BC4F111F62D6B00F3FE5A /* UIBug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIBug.h; sourceTree = ""; }; + 250BC4F211F62D6B00F3FE5A /* UIChildren.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChildren.h; sourceTree = ""; }; + 250BC4F311F62D6B00F3FE5A /* UIConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIConsole.h; sourceTree = ""; }; + 250BC4F411F62D6B00F3FE5A /* UIConsoleLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIConsoleLog.h; sourceTree = ""; }; + 250BC4F511F62D6B00F3FE5A /* UIDescendants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDescendants.h; sourceTree = ""; }; + 250BC4F611F62D6B00F3FE5A /* UIExpectation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIExpectation.h; sourceTree = ""; }; + 250BC4F711F62D6B00F3FE5A /* UIFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIFilter.h; sourceTree = ""; }; + 250BC4F811F62D6B00F3FE5A /* UIInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIInspector.h; sourceTree = ""; }; + 250BC4F911F62D6B00F3FE5A /* UILog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILog.h; sourceTree = ""; }; + 250BC4FA11F62D6B00F3FE5A /* UIMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIMatcher.h; sourceTree = ""; }; + 250BC4FB11F62D6B00F3FE5A /* UIParents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIParents.h; sourceTree = ""; }; + 250BC4FC11F62D6B00F3FE5A /* UIProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIProxy.h; sourceTree = ""; }; + 250BC4FD11F62D6B00F3FE5A /* UIQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQuery.h; sourceTree = ""; }; + 250BC4FE11F62D6B00F3FE5A /* UIQueryAll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryAll.h; sourceTree = ""; }; + 250BC4FF11F62D6B00F3FE5A /* UIQueryExpectation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryExpectation.h; sourceTree = ""; }; + 250BC50011F62D6B00F3FE5A /* UIQuerySearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQuerySearchBar.h; sourceTree = ""; }; + 250BC50111F62D6B00F3FE5A /* UIQuerySegmentedControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQuerySegmentedControl.h; sourceTree = ""; }; + 250BC50211F62D6B00F3FE5A /* UIQueryTabBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryTabBar.h; sourceTree = ""; }; + 250BC50311F62D6B00F3FE5A /* UIQueryTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryTableView.h; sourceTree = ""; }; + 250BC50411F62D6B00F3FE5A /* UIQueryTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryTableViewCell.h; sourceTree = ""; }; + 250BC50511F62D6B00F3FE5A /* UIQueryWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIQueryWebView.h; sourceTree = ""; }; + 250BC50611F62D6B00F3FE5A /* UIRedoer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRedoer.h; sourceTree = ""; }; + 250BC50711F62D6B00F3FE5A /* UISpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UISpec.h; sourceTree = ""; }; + 250BC50811F62D6B00F3FE5A /* ViewFilterSwizzler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewFilterSwizzler.h; sourceTree = ""; }; + 250BC50911F62D6B00F3FE5A /* WaitUntilIdle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaitUntilIdle.h; sourceTree = ""; }; + 250BC50A11F62D6B00F3FE5A /* UISpec.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = UISpec.bundle; sourceTree = ""; }; + 250BC51011F62D6B00F3FE5A /* UISpec_1_0.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = UISpec_1_0.a; sourceTree = ""; }; 2520776D113587BE00382018 /* NSDictionary+RKRequestSerializationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RKRequestSerializationSpec.m"; sourceTree = ""; }; 25232D4D11E62C470048F9B4 /* RKJSONSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKJSONSerialization.h; path = Code/RestKit/RKJSONSerialization.h; sourceTree = ""; }; 25232D4E11E62C470048F9B4 /* RKJSONSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKJSONSerialization.m; path = Code/RKJSONSerialization.m; sourceTree = ""; }; @@ -191,17 +325,17 @@ 2525EBEA106961DD0069EBED /* RKManagedObjectStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKManagedObjectStore.m; path = Code/RKManagedObjectStore.m; sourceTree = ""; }; 2525F99E106C0FF40069EBED /* RKNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKNotifications.h; path = Code/RestKit/RKNotifications.h; sourceTree = ""; }; 2525F99F106C0FF40069EBED /* RKNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKNotifications.m; path = Code/RKNotifications.m; sourceTree = ""; }; - 252F4CBE114021B5003C6F42 /* RKModelSeeder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelSeeder.h; path = Code/RestKit/RKModelSeeder.h; sourceTree = ""; }; - 252F4CBF114021B5003C6F42 /* RKModelSeeder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKModelSeeder.m; path = Code/RKModelSeeder.m; sourceTree = ""; }; - 252F4F9E1140433D003C6F42 /* RKModelMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelMapper.h; path = Code/RestKit/RKModelMapper.h; sourceTree = ""; }; - 252F4F9F1140433D003C6F42 /* RKModelMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKModelMapper.m; path = Code/RKModelMapper.m; sourceTree = ""; }; + 252F4CBE114021B5003C6F42 /* RKObjectSeeder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKObjectSeeder.h; path = Code/RestKit/RKObjectSeeder.h; sourceTree = ""; }; + 252F4CBF114021B5003C6F42 /* RKObjectSeeder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKObjectSeeder.m; path = Code/RKObjectSeeder.m; sourceTree = ""; }; + 252F4F9E1140433D003C6F42 /* RKResourceMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKResourceMapper.h; path = Code/RestKit/RKResourceMapper.h; sourceTree = ""; }; + 252F4F9F1140433D003C6F42 /* RKResourceMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKResourceMapper.m; path = Code/RKResourceMapper.m; sourceTree = ""; }; 252F4FA7114046C9003C6F42 /* RKMappingFormatJSONParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKMappingFormatJSONParser.h; path = Code/RKMappingFormatJSONParser.h; sourceTree = ""; }; 252F4FA8114046C9003C6F42 /* RKMappingFormatJSONParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKMappingFormatJSONParser.m; path = Code/RKMappingFormatJSONParser.m; sourceTree = ""; }; 252F55891140B93A003C6F42 /* RKObjectPropertyInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKObjectPropertyInspector.h; path = Code/RKObjectPropertyInspector.h; sourceTree = ""; }; 252F558A1140B93A003C6F42 /* RKObjectPropertyInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKObjectPropertyInspector.m; path = Code/RKObjectPropertyInspector.m; sourceTree = ""; }; 253BBE941076AB1C00C804B2 /* NSString+InflectionSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+InflectionSupport.h"; path = "Code/RestKit/NSString+InflectionSupport.h"; sourceTree = ""; }; 253BBE951076AB1C00C804B2 /* NSString+InflectionSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+InflectionSupport.m"; path = "Code/NSString+InflectionSupport.m"; sourceTree = ""; }; - 255DE03010FF9BDF00A85891 /* RKManagedModelSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedModelSpec.m; sourceTree = ""; }; + 255DE03010FF9BDF00A85891 /* RKManagedObjectSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectSpec.m; sourceTree = ""; }; 255DE05910FF9DA500A85891 /* RKModelManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKModelManagerSpec.m; sourceTree = ""; }; 255DE05C10FFA05800A85891 /* RKHuman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKHuman.h; sourceTree = ""; }; 255DE05D10FFA05800A85891 /* RKHuman.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKHuman.m; sourceTree = ""; }; @@ -209,26 +343,24 @@ 255DE0F310FFAC0A00A85891 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 255DE1AF10FFB16800A85891 /* RKSpecResponseLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKSpecResponseLoader.h; sourceTree = ""; }; 255DE1B010FFB16800A85891 /* RKSpecResponseLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKSpecResponseLoader.m; sourceTree = ""; }; - 255DE37710FFC26900A85891 /* RKClientSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKClientSpec.m; sourceTree = ""; }; 255DE43111010EE700A85891 /* RKRequestSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestSpec.m; sourceTree = ""; }; 255DE43A11010F8400A85891 /* RKResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKResponseSpec.m; sourceTree = ""; }; - 255DE449110112DB00A85891 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OCMock.framework; sourceTree = ""; }; 255DE4A4110113B700A85891 /* RKSpecEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKSpecEnvironment.h; sourceTree = ""; }; 256FD522112C6A340077F340 /* Data Model.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = "Data Model.xcdatamodel"; sourceTree = ""; }; 256FD64C112C7AF50077F340 /* RKMappableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappableObject.h; sourceTree = ""; }; 256FD64D112C7AF50077F340 /* RKMappableAssociation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappableAssociation.h; sourceTree = ""; }; 256FD64F112C7B780077F340 /* RKMappableObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableObject.m; sourceTree = ""; }; 256FD650112C7B780077F340 /* RKMappableAssociation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableAssociation.m; sourceTree = ""; }; - 256FDE53112DB0B90077F340 /* RKModelMapperSpecModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKModelMapperSpecModel.h; sourceTree = ""; }; - 256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKModelMapperSpecModel.m; sourceTree = ""; }; + 256FDE53112DB0B90077F340 /* RKResourceMapperSpecModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKResourceMapperSpecModel.h; sourceTree = ""; }; + 256FDE54112DB0B90077F340 /* RKResourceMapperSpecModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKResourceMapperSpecModel.m; sourceTree = ""; }; 256FE8D6112EE5310077F340 /* RestKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RestKit.h; path = Code/RestKit/RestKit.h; sourceTree = ""; }; - 2580B066102E0F1000832D07 /* RKModelLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelLoader.h; path = Code/RestKit/RKModelLoader.h; sourceTree = ""; }; - 2580B067102E0F1000832D07 /* RKModelLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKModelLoader.m; path = Code/RKModelLoader.m; sourceTree = ""; }; + 2580B066102E0F1000832D07 /* RKResourceLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKResourceLoader.h; path = Code/RestKit/RKResourceLoader.h; sourceTree = ""; }; + 2580B067102E0F1000832D07 /* RKResourceLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKResourceLoader.m; path = Code/RKResourceLoader.m; sourceTree = ""; }; 25B86E09115BEB71009761A1 /* Errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Errors.h; path = Code/RestKit/Errors.h; sourceTree = ""; }; 25B86EDD115BEFE8009761A1 /* Errors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Errors.m; path = Code/Errors.m; sourceTree = ""; }; - 25FCDDD91035BC85005418A7 /* RKManagedModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKManagedModel.h; path = Code/RestKit/RKManagedModel.h; sourceTree = ""; }; - 25FCDDDA1035BC85005418A7 /* RKManagedModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKManagedModel.m; path = Code/RKManagedModel.m; sourceTree = ""; }; - 25FCDE9B1035E901005418A7 /* RKModelMappableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelMappableProtocol.h; path = Code/RestKit/RKModelMappableProtocol.h; sourceTree = ""; }; + 25FCDDD91035BC85005418A7 /* RKManagedObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKManagedObject.h; path = Code/RestKit/RKManagedObject.h; sourceTree = ""; }; + 25FCDDDA1035BC85005418A7 /* RKManagedObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKManagedObject.m; path = Code/RKManagedObject.m; sourceTree = ""; }; + 25FCDE9B1035E901005418A7 /* RKResourceMappable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKResourceMappable.h; path = Code/RestKit/RKResourceMappable.h; sourceTree = ""; }; 3F032A7710FFB89100F35142 /* RKCat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKCat.h; sourceTree = ""; }; 3F032A7810FFB89100F35142 /* RKCat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKCat.m; sourceTree = ""; }; 3F032AA610FFBBCD00F35142 /* RKHouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKHouse.h; sourceTree = ""; }; @@ -254,13 +386,13 @@ 3F4E1919102DD42F00320118 /* NSDictionary+RKRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+RKRequestSerialization.m"; path = "Code/NSDictionary+RKRequestSerialization.m"; sourceTree = ""; }; 3F6C39A510FE5C95008F47C5 /* UI Spec.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UI Spec.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 3F6C39A710FE5C95008F47C5 /* UISpec-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UISpec-Info.plist"; sourceTree = ""; }; - 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UISpec.xcodeproj; path = ../UISpec/xcode/UISpec/UISpec.xcodeproj; sourceTree = SOURCE_ROOT; }; + 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UISpec.xcodeproj; path = /Users/blake/Projects/two_toasters/InMotion/Libraries/UISpec/xcode/UISpec/UISpec.xcodeproj; sourceTree = ""; }; 3F6C3A2D10FE749C008F47C5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 3F6C3A9310FE7519008F47C5 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 3F6C3A9510FE7524008F47C5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 3F6C3AD010FE76C1008F47C5 /* RKModelMapperSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKModelMapperSpec.m; sourceTree = ""; }; - 3FBF1D37103614E500E307AC /* RKModelManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKModelManager.h; path = Code/RestKit/RKModelManager.h; sourceTree = ""; }; - 3FBF1D38103614E500E307AC /* RKModelManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKModelManager.m; path = Code/RKModelManager.m; sourceTree = ""; }; + 3FBF1D37103614E500E307AC /* RKResourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKResourceManager.h; path = Code/RestKit/RKResourceManager.h; sourceTree = ""; }; + 3FBF1D38103614E500E307AC /* RKResourceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKResourceManager.m; path = Code/RKResourceManager.m; sourceTree = ""; }; 739573BC11BC15E700F44055 /* NSObject+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+SBJSON.m"; path = "Code/JSON/NSObject+SBJSON.m"; sourceTree = ""; }; 739573BD11BC15E700F44055 /* NSString+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+SBJSON.m"; path = "Code/JSON/NSString+SBJSON.m"; sourceTree = ""; }; 739573BE11BC15E700F44055 /* SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SBJSON.m; path = Code/JSON/SBJSON.m; sourceTree = ""; }; @@ -274,7 +406,7 @@ 739573D211BC15F800F44055 /* SBJsonBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBJsonBase.h; path = Code/RestKit/JSON/SBJsonBase.h; sourceTree = ""; }; 739573D311BC15F800F44055 /* SBJsonParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBJsonParser.h; path = Code/RestKit/JSON/SBJsonParser.h; sourceTree = ""; }; 739573D411BC15F800F44055 /* SBJsonWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBJsonWriter.h; path = Code/RestKit/JSON/SBJsonWriter.h; sourceTree = ""; }; - AA747D9E0F9514B9006C5449 /* RestKit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestKit_Prefix.pch; sourceTree = ""; }; + AA747D9E0F9514B9006C5449 /* RestKit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RestKit_Prefix.pch; path = Code/RestKit_Prefix.pch; sourceTree = ""; }; AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; D2AAC07E0554694100DB518D /* libRestKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRestKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -292,12 +424,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3F6C39C510FE73B3008F47C5 /* UISpec_Simulator.a in Frameworks */, 3F6C3A2E10FE749C008F47C5 /* Foundation.framework in Frameworks */, 3F6C3A9610FE7524008F47C5 /* UIKit.framework in Frameworks */, 255DE0E210FFABA500A85891 /* CoreData.framework in Frameworks */, 255DE0F410FFAC0A00A85891 /* SystemConfiguration.framework in Frameworks */, - 255DE453110112DB00A85891 /* OCMock.framework in Frameworks */, + 250BC51211F62D6B00F3FE5A /* UISpec_1_0.a in Frameworks */, + 257EA42011F6317A00DB04C3 /* libOCMock-iPhone.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -327,10 +459,9 @@ children = ( 739573BB11BC15CD00F44055 /* JSON */, 256FEA54112EF35C0077F340 /* Core */, - 256FEA5C112EF3870077F340 /* Modeling */, + 256FEA5C112EF3870077F340 /* Resources */, 2523362211E7A1080048F9B4 /* Three20 */, 3F6C3A9210FE750E008F47C5 /* Specs */, - 2580B1AA102F72D700832D07 /* Libraries */, 32C88DFF0371C24200C91783 /* Other Sources */, 256FD512112C66870077F340 /* Resources */, 0867D69AFE84028FC02AAC07 /* Frameworks */, @@ -351,6 +482,103 @@ name = Frameworks; sourceTree = ""; }; + 25042B7C11F62FF500553519 /* Products */ = { + isa = PBXGroup; + children = ( + 25042B8311F62FF500553519 /* OCMock.framework */, + 25042B8511F62FF500553519 /* OCMockTests.octest */, + 257EA42E11F6319800DB04C3 /* libOCMock-iPhone.a */, + ); + name = Products; + sourceTree = ""; + }; + 25042C5111F6309000553519 /* Products */ = { + isa = PBXGroup; + children = ( + 25042C5811F6309000553519 /* OCMock.framework */, + 25042C5A11F6309000553519 /* OCMockTests.octest */, + 257EA41C11F6317600DB04C3 /* libOCMock-iPhone.a */, + ); + name = Products; + sourceTree = ""; + }; + 250BC42C11F6260100F3FE5A /* Products */ = { + isa = PBXGroup; + children = ( + 250BC43311F6260100F3FE5A /* UISpec_Simulator.a */, + 250BC43511F6260100F3FE5A /* UISpec_Device.a */, + 250BC43711F6260100F3FE5A /* Specs.app */, + ); + name = Products; + sourceTree = ""; + }; + 250BC44C11F6262600F3FE5A /* Products */ = { + isa = PBXGroup; + children = ( + 250BC45311F6262600F3FE5A /* OCMock.framework */, + 250BC45511F6262600F3FE5A /* OCMockTests.octest */, + 257EA43811F6319800DB04C3 /* libOCMock-iPhone.a */, + ); + name = Products; + sourceTree = ""; + }; + 250BC4DD11F62D4400F3FE5A /* Products */ = { + isa = PBXGroup; + children = ( + 250BC4E411F62D4400F3FE5A /* OCMock.framework */, + 250BC4E611F62D4400F3FE5A /* OCMockTests.octest */, + 257EA43311F6319800DB04C3 /* libOCMock-iPhone.a */, + ); + name = Products; + sourceTree = ""; + }; + 250BC4EB11F62D6B00F3FE5A /* UISpec */ = { + isa = PBXGroup; + children = ( + 250BC4EC11F62D6B00F3FE5A /* Headers */, + 250BC50A11F62D6B00F3FE5A /* UISpec.bundle */, + 250BC51011F62D6B00F3FE5A /* UISpec_1_0.a */, + ); + name = UISpec; + path = UISpec/bin/UISpec; + sourceTree = ""; + }; + 250BC4EC11F62D6B00F3FE5A /* Headers */ = { + isa = PBXGroup; + children = ( + 250BC4ED11F62D6B00F3FE5A /* CallCache.h */, + 250BC4EE11F62D6B00F3FE5A /* NSNumberCreator.h */, + 250BC4EF11F62D6B00F3FE5A /* Recordable.h */, + 250BC4F011F62D6B00F3FE5A /* ReturnCacher.h */, + 250BC4F111F62D6B00F3FE5A /* UIBug.h */, + 250BC4F211F62D6B00F3FE5A /* UIChildren.h */, + 250BC4F311F62D6B00F3FE5A /* UIConsole.h */, + 250BC4F411F62D6B00F3FE5A /* UIConsoleLog.h */, + 250BC4F511F62D6B00F3FE5A /* UIDescendants.h */, + 250BC4F611F62D6B00F3FE5A /* UIExpectation.h */, + 250BC4F711F62D6B00F3FE5A /* UIFilter.h */, + 250BC4F811F62D6B00F3FE5A /* UIInspector.h */, + 250BC4F911F62D6B00F3FE5A /* UILog.h */, + 250BC4FA11F62D6B00F3FE5A /* UIMatcher.h */, + 250BC4FB11F62D6B00F3FE5A /* UIParents.h */, + 250BC4FC11F62D6B00F3FE5A /* UIProxy.h */, + 250BC4FD11F62D6B00F3FE5A /* UIQuery.h */, + 250BC4FE11F62D6B00F3FE5A /* UIQueryAll.h */, + 250BC4FF11F62D6B00F3FE5A /* UIQueryExpectation.h */, + 250BC50011F62D6B00F3FE5A /* UIQuerySearchBar.h */, + 250BC50111F62D6B00F3FE5A /* UIQuerySegmentedControl.h */, + 250BC50211F62D6B00F3FE5A /* UIQueryTabBar.h */, + 250BC50311F62D6B00F3FE5A /* UIQueryTableView.h */, + 250BC50411F62D6B00F3FE5A /* UIQueryTableViewCell.h */, + 250BC50511F62D6B00F3FE5A /* UIQueryWebView.h */, + 250BC50611F62D6B00F3FE5A /* UIRedoer.h */, + 250BC50711F62D6B00F3FE5A /* UISpec.h */, + 250BC50811F62D6B00F3FE5A /* ViewFilterSwizzler.h */, + 250BC50911F62D6B00F3FE5A /* WaitUntilIdle.h */, + ); + path = Headers; + sourceTree = ""; + }; 2523362211E7A1080048F9B4 /* Three20 */ = { isa = PBXGroup; children = ( @@ -381,8 +609,8 @@ 3F032AA710FFBBCD00F35142 /* RKHouse.m */, 3F032AA910FFBC1F00F35142 /* RKResident.h */, 3F032AAA10FFBC1F00F35142 /* RKResident.m */, - 256FDE53112DB0B90077F340 /* RKModelMapperSpecModel.h */, - 256FDE54112DB0B90077F340 /* RKModelMapperSpecModel.m */, + 256FDE53112DB0B90077F340 /* RKResourceMapperSpecModel.h */, + 256FDE54112DB0B90077F340 /* RKResourceMapperSpecModel.m */, ); path = Models; sourceTree = ""; @@ -390,10 +618,11 @@ 255DE0A110FFA43A00A85891 /* Support */ = { isa = PBXGroup; children = ( + 25042C5011F6309000553519 /* OCMock.xcodeproj */, + 250BC4EB11F62D6B00F3FE5A /* UISpec */, 255DE1AF10FFB16800A85891 /* RKSpecResponseLoader.h */, 255DE1B010FFB16800A85891 /* RKSpecResponseLoader.m */, 255DE4A4110113B700A85891 /* RKSpecEnvironment.h */, - 255DE449110112DB00A85891 /* OCMock.framework */, ); path = Support; sourceTree = ""; @@ -401,7 +630,6 @@ 255DE43011010ED400A85891 /* Core */ = { isa = PBXGroup; children = ( - 255DE37710FFC26900A85891 /* RKClientSpec.m */, 255DE43111010EE700A85891 /* RKRequestSpec.m */, 255DE43A11010F8400A85891 /* RKResponseSpec.m */, 2520776D113587BE00382018 /* NSDictionary+RKRequestSerializationSpec.m */, @@ -417,14 +645,15 @@ path = Resources; sourceTree = ""; }; - 256FD52A112C6AEC0077F340 /* Modeling */ = { + 256FD52A112C6AEC0077F340 /* Resources */ = { isa = PBXGroup; children = ( 3F6C3AD010FE76C1008F47C5 /* RKModelMapperSpec.m */, - 255DE03010FF9BDF00A85891 /* RKManagedModelSpec.m */, + 255DE03010FF9BDF00A85891 /* RKManagedObjectSpec.m */, 255DE05910FF9DA500A85891 /* RKModelManagerSpec.m */, + 250BC22A11F621B400F3FE5A /* RKStaticRouterSpec.m */, ); - name = Modeling; + name = Resources; sourceTree = ""; }; 256FEA54112EF35C0077F340 /* Core */ = { @@ -464,36 +693,33 @@ name = Core; sourceTree = ""; }; - 256FEA5C112EF3870077F340 /* Modeling */ = { + 256FEA5C112EF3870077F340 /* Resources */ = { isa = PBXGroup; children = ( - 25FCDDD91035BC85005418A7 /* RKManagedModel.h */, - 25FCDDDA1035BC85005418A7 /* RKManagedModel.m */, - 2580B066102E0F1000832D07 /* RKModelLoader.h */, - 2580B067102E0F1000832D07 /* RKModelLoader.m */, - 25FCDE9B1035E901005418A7 /* RKModelMappableProtocol.h */, - 3FBF1D37103614E500E307AC /* RKModelManager.h */, - 3FBF1D38103614E500E307AC /* RKModelManager.m */, + 3FBF1D37103614E500E307AC /* RKResourceManager.h */, + 3FBF1D38103614E500E307AC /* RKResourceManager.m */, + 25FCDE9B1035E901005418A7 /* RKResourceMappable.h */, + 250BBFAD11F606D300F3FE5A /* RKRouter.h */, + 250BBFC111F608DB00F3FE5A /* RKStaticRouter.h */, + 250BBFC211F608DB00F3FE5A /* RKStaticRouter.m */, + 25FCDDD91035BC85005418A7 /* RKManagedObject.h */, + 25FCDDDA1035BC85005418A7 /* RKManagedObject.m */, + 250BBF9811F5FFF500F3FE5A /* RKObject.h */, + 250BBF9911F5FFF500F3FE5A /* RKObject.m */, + 2580B066102E0F1000832D07 /* RKResourceLoader.h */, + 2580B067102E0F1000832D07 /* RKResourceLoader.m */, 2525EBE9106961DD0069EBED /* RKManagedObjectStore.h */, 2525EBEA106961DD0069EBED /* RKManagedObjectStore.m */, - 252F4CBE114021B5003C6F42 /* RKModelSeeder.h */, - 252F4CBF114021B5003C6F42 /* RKModelSeeder.m */, - 252F4F9E1140433D003C6F42 /* RKModelMapper.h */, - 252F4F9F1140433D003C6F42 /* RKModelMapper.m */, + 252F4CBE114021B5003C6F42 /* RKObjectSeeder.h */, + 252F4CBF114021B5003C6F42 /* RKObjectSeeder.m */, + 252F4F9E1140433D003C6F42 /* RKResourceMapper.h */, + 252F4F9F1140433D003C6F42 /* RKResourceMapper.m */, 252F4FA7114046C9003C6F42 /* RKMappingFormatJSONParser.h */, 252F4FA8114046C9003C6F42 /* RKMappingFormatJSONParser.m */, 252F55891140B93A003C6F42 /* RKObjectPropertyInspector.h */, 252F558A1140B93A003C6F42 /* RKObjectPropertyInspector.m */, ); - name = Modeling; - sourceTree = ""; - }; - 2580B1AA102F72D700832D07 /* Libraries */ = { - isa = PBXGroup; - children = ( - 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */, - ); - name = Libraries; + name = Resources; sourceTree = ""; }; 32C88DFF0371C24200C91783 /* Other Sources */ = { @@ -504,24 +730,16 @@ name = "Other Sources"; sourceTree = ""; }; - 3F6C39B710FE738A008F47C5 /* Products */ = { - isa = PBXGroup; - children = ( - 3F6C39BD10FE738A008F47C5 /* UISpec_Simulator.a */, - 3F6C39BF10FE738A008F47C5 /* UISpec_Device.a */, - 3FF0DF4510FE7CEA008901F7 /* Specs.app */, - ); - name = Products; - sourceTree = ""; - }; 3F6C3A9210FE750E008F47C5 /* Specs */ = { isa = PBXGroup; children = ( 255DE43011010ED400A85891 /* Core */, - 256FD52A112C6AEC0077F340 /* Modeling */, + 256FD52A112C6AEC0077F340 /* Resources */, 255DE0A110FFA43A00A85891 /* Support */, 255DE05B10FFA04200A85891 /* Models */, 3F6C3A9310FE7519008F47C5 /* main.m */, + 250429A711F62E0200553519 /* UISpec+UISpecRunner.h */, + 250429A811F62E0200553519 /* UISpec+UISpecRunner.m */, ); path = Specs; sourceTree = ""; @@ -574,15 +792,15 @@ 3F4E18FE102DD38800320118 /* RKRequestSerializable.h in Headers */, 3F4E18FF102DD38800320118 /* RKResponse.h in Headers */, 3F4E191A102DD42F00320118 /* NSDictionary+RKRequestSerialization.h in Headers */, - 2580B068102E0F1000832D07 /* RKModelLoader.h in Headers */, - 25FCDDDB1035BC85005418A7 /* RKManagedModel.h in Headers */, - 25FCDE9C1035E901005418A7 /* RKModelMappableProtocol.h in Headers */, - 3FBF1D39103614E500E307AC /* RKModelManager.h in Headers */, + 2580B068102E0F1000832D07 /* RKResourceLoader.h in Headers */, + 25FCDDDB1035BC85005418A7 /* RKManagedObject.h in Headers */, + 25FCDE9C1035E901005418A7 /* RKResourceMappable.h in Headers */, + 3FBF1D39103614E500E307AC /* RKResourceManager.h in Headers */, 2525EBEB106961DD0069EBED /* RKManagedObjectStore.h in Headers */, 2525F9A0106C0FF40069EBED /* RKNotifications.h in Headers */, 253BBE961076AB1C00C804B2 /* NSString+InflectionSupport.h in Headers */, - 252F4CC0114021B5003C6F42 /* RKModelSeeder.h in Headers */, - 252F4FA11140433D003C6F42 /* RKModelMapper.h in Headers */, + 252F4CC0114021B5003C6F42 /* RKObjectSeeder.h in Headers */, + 252F4FA11140433D003C6F42 /* RKResourceMapper.h in Headers */, 252F4FA9114046C9003C6F42 /* RKMappingFormatJSONParser.h in Headers */, 252F558C1140B93A003C6F42 /* RKObjectPropertyInspector.h in Headers */, 25B86E0A115BEB71009761A1 /* Errors.h in Headers */, @@ -596,6 +814,9 @@ 25232D4F11E62C470048F9B4 /* RKJSONSerialization.h in Headers */, 25232F8811E6476B0048F9B4 /* NSObject+RKJSONSerialization.h in Headers */, 2523367711E7A6800048F9B4 /* RKSearchEngine.h in Headers */, + 250BBF9A11F5FFF500F3FE5A /* RKObject.h in Headers */, + 250BBFAF11F606D300F3FE5A /* RKRouter.h in Headers */, + 250BBFC311F608DB00F3FE5A /* RKStaticRouter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -632,7 +853,7 @@ buildRules = ( ); dependencies = ( - 3F6C3A9C10FE753B008F47C5 /* PBXTargetDependency */, + 257EA5A611F632D700DB04C3 /* PBXTargetDependency */, ); name = UISpec; productName = "UI Spec"; @@ -661,6 +882,9 @@ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + ORGANIZATIONNAME = "Two Toasters"; + }; buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "RestKit" */; compatibilityVersion = "Xcode 3.1"; hasScannedForEncodings = 1; @@ -669,7 +893,23 @@ projectDirPath = ""; projectReferences = ( { - ProductGroup = 3F6C39B710FE738A008F47C5 /* Products */; + ProductGroup = 25042B7C11F62FF500553519 /* Products */; + ProjectRef = 25042A9511F62F2400553519 /* OCMock.xcodeproj */; + }, + { + ProductGroup = 25042C5111F6309000553519 /* Products */; + ProjectRef = 25042C5011F6309000553519 /* OCMock.xcodeproj */; + }, + { + ProductGroup = 250BC4DD11F62D4400F3FE5A /* Products */; + ProjectRef = 250BC43F11F6261700F3FE5A /* OCMock.xcodeproj */; + }, + { + ProductGroup = 250BC44C11F6262600F3FE5A /* Products */; + ProjectRef = 250BC36211F625DF00F3FE5A /* OCMock.xcodeproj */; + }, + { + ProductGroup = 250BC42C11F6260100F3FE5A /* Products */; ProjectRef = 3F6C39B610FE738A008F47C5 /* UISpec.xcodeproj */; }, ); @@ -683,25 +923,109 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 3F6C39BD10FE738A008F47C5 /* UISpec_Simulator.a */ = { + 25042B8311F62FF500553519 /* OCMock.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OCMock.framework; + remoteRef = 25042B8211F62FF500553519 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 25042B8511F62FF500553519 /* OCMockTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = OCMockTests.octest; + remoteRef = 25042B8411F62FF500553519 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 25042C5811F6309000553519 /* OCMock.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OCMock.framework; + remoteRef = 25042C5711F6309000553519 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 25042C5A11F6309000553519 /* OCMockTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = OCMockTests.octest; + remoteRef = 25042C5911F6309000553519 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 250BC43311F6260100F3FE5A /* UISpec_Simulator.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = UISpec_Simulator.a; - remoteRef = 3F6C39BC10FE738A008F47C5 /* PBXContainerItemProxy */; + remoteRef = 250BC43211F6260100F3FE5A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 3F6C39BF10FE738A008F47C5 /* UISpec_Device.a */ = { + 250BC43511F6260100F3FE5A /* UISpec_Device.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = UISpec_Device.a; - remoteRef = 3F6C39BE10FE738A008F47C5 /* PBXContainerItemProxy */; + remoteRef = 250BC43411F6260100F3FE5A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 3FF0DF4510FE7CEA008901F7 /* Specs.app */ = { + 250BC43711F6260100F3FE5A /* Specs.app */ = { isa = PBXReferenceProxy; fileType = wrapper.application; path = Specs.app; - remoteRef = 3FF0DF4410FE7CEA008901F7 /* PBXContainerItemProxy */; + remoteRef = 250BC43611F6260100F3FE5A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 250BC45311F6262600F3FE5A /* OCMock.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OCMock.framework; + remoteRef = 250BC45211F6262600F3FE5A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 250BC45511F6262600F3FE5A /* OCMockTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = OCMockTests.octest; + remoteRef = 250BC45411F6262600F3FE5A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 250BC4E411F62D4400F3FE5A /* OCMock.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OCMock.framework; + remoteRef = 250BC4E311F62D4400F3FE5A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 250BC4E611F62D4400F3FE5A /* OCMockTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = OCMockTests.octest; + remoteRef = 250BC4E511F62D4400F3FE5A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 257EA41C11F6317600DB04C3 /* libOCMock-iPhone.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libOCMock-iPhone.a"; + remoteRef = 257EA41B11F6317600DB04C3 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 257EA42E11F6319800DB04C3 /* libOCMock-iPhone.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libOCMock-iPhone.a"; + remoteRef = 257EA42D11F6319800DB04C3 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 257EA43311F6319800DB04C3 /* libOCMock-iPhone.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libOCMock-iPhone.a"; + remoteRef = 257EA43211F6319800DB04C3 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 257EA43811F6319800DB04C3 /* libOCMock-iPhone.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libOCMock-iPhone.a"; + remoteRef = 257EA43711F6319800DB04C3 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ @@ -711,6 +1035,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 250BC51111F62D6B00F3FE5A /* UISpec.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -751,9 +1076,9 @@ 3F6C3A9410FE7519008F47C5 /* main.m in Sources */, 255DE05A10FF9DA500A85891 /* RKModelManagerSpec.m in Sources */, 255DE05E10FFA05800A85891 /* RKHuman.m in Sources */, - 255DE0DB10FFAB7700A85891 /* RKModelManager.m in Sources */, + 255DE0DB10FFAB7700A85891 /* RKResourceManager.m in Sources */, 255DE0DD10FFAB7E00A85891 /* RKManagedObjectStore.m in Sources */, - 255DE0DE10FFAB7F00A85891 /* RKManagedModel.m in Sources */, + 255DE0DE10FFAB7F00A85891 /* RKManagedObject.m in Sources */, 255DE0E510FFABBB00A85891 /* RKResponse.m in Sources */, 255DE0E610FFABBC00A85891 /* RKRequest.m in Sources */, 255DE0E710FFABBD00A85891 /* RKParamsFileAttachment.m in Sources */, @@ -768,19 +1093,18 @@ 3F032A7910FFB89100F35142 /* RKCat.m in Sources */, 3F032AA810FFBBCD00F35142 /* RKHouse.m in Sources */, 3F032AAB10FFBC1F00F35142 /* RKResident.m in Sources */, - 255DE37810FFC26900A85891 /* RKClientSpec.m in Sources */, 255DE43211010EE700A85891 /* RKRequestSpec.m in Sources */, 255DE43B11010F8400A85891 /* RKResponseSpec.m in Sources */, 255DE62B1104BA2B00A85891 /* RKModelMapperSpec.m in Sources */, - 255DE62C1104BA2D00A85891 /* RKManagedModelSpec.m in Sources */, + 255DE62C1104BA2D00A85891 /* RKManagedObjectSpec.m in Sources */, 256FD523112C6A340077F340 /* Data Model.xcdatamodel in Sources */, 256FD651112C7B780077F340 /* RKMappableObject.m in Sources */, 256FD652112C7B780077F340 /* RKMappableAssociation.m in Sources */, - 256FDE55112DB0B90077F340 /* RKModelMapperSpecModel.m in Sources */, + 256FDE55112DB0B90077F340 /* RKResourceMapperSpecModel.m in Sources */, 2520776E113587BE00382018 /* NSDictionary+RKRequestSerializationSpec.m in Sources */, - 252F4CC2114021B5003C6F42 /* RKModelSeeder.m in Sources */, - 252F4F9D11404322003C6F42 /* RKModelLoader.m in Sources */, - 252F4FA01140433D003C6F42 /* RKModelMapper.m in Sources */, + 252F4CC2114021B5003C6F42 /* RKObjectSeeder.m in Sources */, + 252F4F9D11404322003C6F42 /* RKResourceLoader.m in Sources */, + 252F4FA01140433D003C6F42 /* RKResourceMapper.m in Sources */, 252F4FAB114046C9003C6F42 /* RKMappingFormatJSONParser.m in Sources */, 252F558B1140B93A003C6F42 /* RKObjectPropertyInspector.m in Sources */, 25B86EDE115BEFE8009761A1 /* Errors.m in Sources */, @@ -790,6 +1114,10 @@ 739573CB11BC15E700F44055 /* SBJsonBase.m in Sources */, 739573CC11BC15E700F44055 /* SBJsonParser.m in Sources */, 739573CD11BC15E700F44055 /* SBJsonWriter.m in Sources */, + 250BC22211F620F700F3FE5A /* RKObject.m in Sources */, + 250BC22311F620F900F3FE5A /* RKStaticRouter.m in Sources */, + 250BC22B11F621B400F3FE5A /* RKStaticRouterSpec.m in Sources */, + 250429A911F62E0200553519 /* UISpec+UISpecRunner.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -805,14 +1133,14 @@ 3F4E18FD102DD38800320118 /* RKRequest.m in Sources */, 3F4E1900102DD38800320118 /* RKResponse.m in Sources */, 3F4E191B102DD42F00320118 /* NSDictionary+RKRequestSerialization.m in Sources */, - 2580B069102E0F1000832D07 /* RKModelLoader.m in Sources */, - 25FCDDDC1035BC85005418A7 /* RKManagedModel.m in Sources */, - 3FBF1D3A103614E500E307AC /* RKModelManager.m in Sources */, + 2580B069102E0F1000832D07 /* RKResourceLoader.m in Sources */, + 25FCDDDC1035BC85005418A7 /* RKManagedObject.m in Sources */, + 3FBF1D3A103614E500E307AC /* RKResourceManager.m in Sources */, 2525EBEC106961DD0069EBED /* RKManagedObjectStore.m in Sources */, 2525F9A1106C0FF40069EBED /* RKNotifications.m in Sources */, 253BBE971076AB1C00C804B2 /* NSString+InflectionSupport.m in Sources */, - 252F4CC1114021B5003C6F42 /* RKModelSeeder.m in Sources */, - 252F4FA21140433D003C6F42 /* RKModelMapper.m in Sources */, + 252F4CC1114021B5003C6F42 /* RKObjectSeeder.m in Sources */, + 252F4FA21140433D003C6F42 /* RKResourceMapper.m in Sources */, 252F4FAA114046C9003C6F42 /* RKMappingFormatJSONParser.m in Sources */, 252F558D1140B93A003C6F42 /* RKObjectPropertyInspector.m in Sources */, 25B86EE0115BEFE8009761A1 /* Errors.m in Sources */, @@ -824,16 +1152,18 @@ 739573C711BC15E700F44055 /* SBJsonWriter.m in Sources */, 25232D5011E62C470048F9B4 /* RKJSONSerialization.m in Sources */, 25232F8911E6476B0048F9B4 /* NSObject+RKJSONSerialization.m in Sources */, + 250BBF9B11F5FFF500F3FE5A /* RKObject.m in Sources */, + 250BBFC411F608DB00F3FE5A /* RKStaticRouter.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 3F6C3A9C10FE753B008F47C5 /* PBXTargetDependency */ = { + 257EA5A611F632D700DB04C3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = UISpec_Simulator; - targetProxy = 3F6C3A9B10FE753B008F47C5 /* PBXContainerItemProxy */; + name = "OCMock-iPhone"; + targetProxy = 257EA5A511F632D700DB04C3 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -852,7 +1182,7 @@ GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = RestKit_Prefix.pch; + GCC_PREFIX_HEADER = Code/RestKit_Prefix.pch; GCC_VERSION = ""; HEADER_SEARCH_PATHS = ""; INSTALL_PATH = /usr/local/lib; @@ -873,7 +1203,7 @@ DSTROOT = /tmp/RestKit.dst; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = RestKit_Prefix.pch; + GCC_PREFIX_HEADER = Code/RestKit_Prefix.pch; GCC_VERSION = ""; HEADER_SEARCH_PATHS = ""; INSTALL_PATH = /usr/local/lib; @@ -993,13 +1323,13 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/UIKit.framework/Headers/UIKit.h"; - HEADER_SEARCH_PATHS = ( - "../json-framework/Source/", - ../ElementParser/Classes, - ../UISpec/src, - ); + HEADER_SEARCH_PATHS = Specs/Support/OCMock/Source; INFOPLIST_FILE = "Resources/UISpec-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Specs/Support/UISpec/bin/UISpec\"", + ); OTHER_LDFLAGS = ( "-framework", Foundation, @@ -1028,13 +1358,13 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/UIKit.framework/Headers/UIKit.h"; - HEADER_SEARCH_PATHS = ( - ../UISpec/src, - ../ElementParser/Classes, - "../json-framework/Source", - ); + HEADER_SEARCH_PATHS = Specs/Support/OCMock/Source; INFOPLIST_FILE = "Resources/UISpec-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Specs/Support/UISpec/bin/UISpec\"", + ); OTHER_LDFLAGS = ( "-framework", Foundation, diff --git a/Specs/Models/RKCat.h b/Specs/Models/RKCat.h index dc59d8fc..09711cc7 100644 --- a/Specs/Models/RKCat.h +++ b/Specs/Models/RKCat.h @@ -6,12 +6,12 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKManagedModel.h" +#import "RKManagedObject.h" @class RKHuman; -@interface RKCat : RKManagedModel { +@interface RKCat : RKManagedObject { } diff --git a/Specs/Models/RKHouse.h b/Specs/Models/RKHouse.h index 39444a30..9c1c72ac 100644 --- a/Specs/Models/RKHouse.h +++ b/Specs/Models/RKHouse.h @@ -6,10 +6,10 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKManagedModel.h" +#import "RKManagedObject.h" -@interface RKHouse : RKManagedModel { +@interface RKHouse : RKManagedObject { } diff --git a/Specs/Models/RKHuman.h b/Specs/Models/RKHuman.h index 52c77bd0..dd4f8d79 100644 --- a/Specs/Models/RKHuman.h +++ b/Specs/Models/RKHuman.h @@ -6,10 +6,10 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKManagedModel.h" +#import "RKManagedObject.h" -@interface RKHuman : RKManagedModel { +@interface RKHuman : RKManagedObject { } @property (nonatomic, retain) NSNumber* railsID; diff --git a/Specs/Models/RKMappableAssociation.h b/Specs/Models/RKMappableAssociation.h index 2655fdbc..2b0e6fb4 100644 --- a/Specs/Models/RKMappableAssociation.h +++ b/Specs/Models/RKMappableAssociation.h @@ -7,12 +7,12 @@ // #import -#import "RKModelMappableProtocol.h" +#import "RKResourceMappable.h" -@interface RKMappableAssociation : NSObject { +@interface RKMappableAssociation : NSObject { NSString* _testString; } @property (nonatomic, retain) NSString* testString; -@end \ No newline at end of file +@end diff --git a/Specs/Models/RKMappableObject.h b/Specs/Models/RKMappableObject.h index 4d4a2062..1789a341 100644 --- a/Specs/Models/RKMappableObject.h +++ b/Specs/Models/RKMappableObject.h @@ -7,10 +7,10 @@ // #import -#import "RKModelMappableProtocol.h" +#import "RKResourceMappable.h" #import "RKMappableAssociation.h" -@interface RKMappableObject : NSObject { +@interface RKMappableObject : NSObject { NSDate* _dateTest; NSNumber* _numberTest; NSString* _stringTest; diff --git a/Specs/Models/RKMappableObject.m b/Specs/Models/RKMappableObject.m index 98f09ed9..8c772bf1 100644 --- a/Specs/Models/RKMappableObject.m +++ b/Specs/Models/RKMappableObject.m @@ -7,6 +7,7 @@ // #import "RKMappableObject.h" +#import "NSDictionary+RKRequestSerialization.h" @implementation RKMappableObject diff --git a/Specs/Models/RKResident.h b/Specs/Models/RKResident.h index 783d9c69..48457ae8 100644 --- a/Specs/Models/RKResident.h +++ b/Specs/Models/RKResident.h @@ -6,12 +6,11 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKManagedModel.h" - +#import "RKManagedObject.h" @class RKHouse; -@interface RKResident : RKManagedModel { +@interface RKResident : RKManagedObject { } @property (nonatomic, retain) NSString* residableType; diff --git a/Specs/Models/RKModelMapperSpecModel.h b/Specs/Models/RKResourceMapperSpecModel.h similarity index 81% rename from Specs/Models/RKModelMapperSpecModel.h rename to Specs/Models/RKResourceMapperSpecModel.h index 6c9ecd41..6f49946d 100644 --- a/Specs/Models/RKModelMapperSpecModel.h +++ b/Specs/Models/RKResourceMapperSpecModel.h @@ -1,5 +1,5 @@ // -// RKModelMapperSpecModel.h +// RKResourceMapperSpecModel.h // RestKit // // Created by Blake Watters on 2/18/10. @@ -8,8 +8,7 @@ #import - -@interface RKModelMapperSpecModel : NSObject { +@interface RKResourceMapperSpecModel : NSObject { NSString* _name; NSNumber* _age; NSDate* _createdAt; diff --git a/Specs/Models/RKModelMapperSpecModel.m b/Specs/Models/RKResourceMapperSpecModel.m similarity index 65% rename from Specs/Models/RKModelMapperSpecModel.m rename to Specs/Models/RKResourceMapperSpecModel.m index 794955d4..b0cd3c98 100644 --- a/Specs/Models/RKModelMapperSpecModel.m +++ b/Specs/Models/RKResourceMapperSpecModel.m @@ -1,15 +1,14 @@ // -// RKModelMapperSpecModel.m +// RKResourceMapperSpecModel.m // RestKit // // Created by Blake Watters on 2/18/10. // Copyright 2010 Two Toasters. All rights reserved. // -#import "RKModelMapperSpecModel.h" +#import "RKResourceMapperSpecModel.h" - -@implementation RKModelMapperSpecModel +@implementation RKResourceMapperSpecModel @synthesize name = _name; @synthesize age = _age; diff --git a/Specs/RKClientSpec.m b/Specs/RKClientSpec.m deleted file mode 100644 index 651bdf4a..00000000 --- a/Specs/RKClientSpec.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// RKClientSpec.m -// RestKit -// -// Created by Blake Watters on 1/14/10. -// Copyright 2010 Two Toasters. All rights reserved. -// - - - -@implementation RKClientSpec - -@end diff --git a/Specs/RKManagedModelSpec.m b/Specs/RKManagedModelSpec.m deleted file mode 100644 index b1935dfa..00000000 --- a/Specs/RKManagedModelSpec.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// RKManagedModelSpec.m -// RestKit -// -// Created by Blake Watters on 1/14/10. -// Copyright 2010 Two Toasters. All rights reserved. -// - - -#import "UISpec.h" -#import "dsl/UIExpectation.h" - -#import "RKModelManager.h" -#import "RKHuman.h" - -@interface RKManagedModelSpec : NSObject { - -} - -@end - -@implementation RKManagedModelSpec - -@end \ No newline at end of file diff --git a/Specs/RKManagedObjectSpec.m b/Specs/RKManagedObjectSpec.m new file mode 100644 index 00000000..72d6d5df --- /dev/null +++ b/Specs/RKManagedObjectSpec.m @@ -0,0 +1,21 @@ +// +// RKManagedObjectSpec.m +// RestKit +// +// Created by Blake Watters on 1/14/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKSpecEnvironment.h" +#import "RKResourceManager.h" +#import "RKHuman.h" + +@interface RKManagedObjectSpec : NSObject { + +} + +@end + +@implementation RKManagedObjectSpec + +@end diff --git a/Specs/RKModelManagerSpec.m b/Specs/RKModelManagerSpec.m index 02cff6b0..451f418b 100644 --- a/Specs/RKModelManagerSpec.m +++ b/Specs/RKModelManagerSpec.m @@ -1,33 +1,30 @@ // -// RKModelManagerSpec.m +// RKResourceManagerSpec.m // RestKit // // Created by Blake Watters on 1/14/10. // Copyright 2010 Two Toasters. All rights reserved. // -#import "UISpec.h" -#import "dsl/UIExpectation.h" - -#import "RKModelManager.h" +#import "RKSpecEnvironment.h" +#import "RKResourceManager.h" #import "RKSpecResponseLoader.h" #import "RKHuman.h" - -@interface RKModelManagerSpec : NSObject { - RKModelManager* _modelManager; +@interface RKResourceManagerSpec : NSObject { + RKResourceManager* _modelManager; RKSpecResponseLoader* _responseLoader; } @end -@implementation RKModelManagerSpec +@implementation RKResourceManagerSpec - (void)beforeAll { NSString* localBaseURL = [NSString stringWithFormat:@"http://%s:3000", getenv("RKREST_IP_ADDRESS")]; - _modelManager = [RKModelManager managerWithBaseURL:localBaseURL]; + _modelManager = [RKResourceManager managerWithBaseURL:localBaseURL]; _modelManager.objectStore = [[RKManagedObjectStore alloc] initWithStoreFilename:@"RKSpecs.sqlite"]; - [_modelManager registerModel:[RKHuman class] forElementNamed:@"human"]; + [_modelManager registerClass:[RKHuman class] forElementNamed:@"human"]; _responseLoader = [[RKSpecResponseLoader alloc] init]; } @@ -44,21 +41,21 @@ - (void)itShouldHandleConnectionFailures { NSString* localBaseURL = [NSString stringWithFormat:@"http://%s:3001", getenv("RKREST_IP_ADDRESS")]; - RKModelManager* modelManager = [RKModelManager managerWithBaseURL:localBaseURL]; - [modelManager loadModel:@"/humans/1" delegate:_responseLoader callback:@selector(loadResponse:)]; + RKResourceManager* modelManager = [RKResourceManager managerWithBaseURL:localBaseURL]; + [modelManager loadResource:@"/humans/1" delegate:_responseLoader]; [_responseLoader waitForResponse]; [expectThat(_responseLoader.success) should:be(NO)]; } - (void)itShouldLoadAHuman { - [_modelManager loadModel:@"/humans/1" delegate:_responseLoader callback:@selector(loadResponse:)]; + [_modelManager loadResource:@"/humans/1" delegate:_responseLoader]; [_responseLoader waitForResponse]; RKHuman* blake = (RKHuman*) _responseLoader.response; [expectThat(blake.name) should:be(@"Blake Watters")]; } - (void)itShouldLoadAllHumans { - [_modelManager loadModels:@"/humans" delegate:_responseLoader callback:@selector(loadResponse:)]; + [_modelManager loadResource:@"/humans" delegate:_responseLoader]; [_responseLoader waitForResponse]; NSArray* humans = (NSArray*) _responseLoader.response; [expectThat([humans count]) should:be(4)]; diff --git a/Specs/RKModelMapperSpec.m b/Specs/RKModelMapperSpec.m index e78d4710..3069eacf 100644 --- a/Specs/RKModelMapperSpec.m +++ b/Specs/RKModelMapperSpec.m @@ -1,34 +1,31 @@ // -// CRTransactionSpec.m -// Cash Register +// RKResourceMapperSpec.m +// RestKit // // Created by Jeremy Ellison on 12/8/09. // Copyright 2009 Two Toasters. All rights reserved. // - -#import "UISpec.h" -#import "dsl/UIExpectation.h" - -#import "RKModelMapper.h" +#import "RKSpecEnvironment.h" +#import "RKResourceMapper.h" #import "RKMappableObject.h" #import "RKMappableAssociation.h" -#import "RKModelMapperSpecModel.h" +#import "RKResourceMapperSpecModel.h" -@interface RKModelMapperSpec : NSObject +@interface RKResourceMapperSpec : NSObject @end -@implementation RKModelMapperSpec +@implementation RKResourceMapperSpec - (void)itShouldMapFromJSON { - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; mapper.format = RKMappingFormatJSON; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_many"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_one"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"]; id result = [mapper buildModelFromString:[self jsonString]]; [expectThat(result) shouldNot:be(nil)]; @@ -44,12 +41,12 @@ } - (void)itShouldMapObjectsFromJSON { - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; mapper.format = RKMappingFormatJSON; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_many"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_one"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"]; NSArray* results = [mapper buildModelsFromString:[self jsonCollectionString]]; [expectThat([results count]) should:be(2)]; @@ -67,12 +64,12 @@ } - (void)itShouldMapFromXML { - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; mapper.format = RKMappingFormatXML; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_many"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_one"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"]; id result = [mapper buildModelFromString:[self xmlString]]; [expectThat(result) shouldNot:be(nil)]; @@ -88,12 +85,12 @@ } - (void)itShouldMapObjectsFromXML { - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; mapper.format = RKMappingFormatXML; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_many"]; - [mapper registerModel:[RKMappableAssociation class] forElementNamed:@"has_one"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"]; + [mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"]; NSArray* results = [mapper buildModelsFromString:[self xmlCollectionString]]; [expectThat([results count]) should:be(2)]; @@ -111,33 +108,33 @@ } - (void)itShouldNotUpdateNilPropertyToNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; [mapper updateObject:model ifNewPropertyValue:nil forPropertyNamed:@"name"]; [expectThat(model.name) should:be(nil)]; } - (void)itShouldBeAbleToSetNonNilPropertiesToNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; model.age = [NSNumber numberWithInt:0]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; [mapper updateObject:model ifNewPropertyValue:nil forPropertyNamed:@"age"]; [expectThat(model.age) should:be(nil)]; } - (void)itShouldBeAbleToSetNilPropertiesToNonNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; [mapper updateObject:model ifNewPropertyValue:[NSNumber numberWithInt:0] forPropertyNamed:@"age"]; [expectThat(model.age) should:be([NSNumber numberWithInt:0])]; } - (void)itShouldBeAbleToSetNonNilNSStringPropertiesToNonNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; model.name = @"Bob"; [mapper updateObject:model ifNewPropertyValue:@"Will" forPropertyNamed:@"name"]; @@ -145,8 +142,8 @@ } - (void)itShouldBeAbleToSetNonNilNSNumberPropertiesToNonNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; model.age = [NSNumber numberWithInt:16]; [mapper updateObject:model ifNewPropertyValue:[NSNumber numberWithInt:17] forPropertyNamed:@"age"]; @@ -154,8 +151,8 @@ } - (void)itShouldBeAbleToSetNonNilNSDatePropertiesToNonNil { - RKModelMapperSpecModel* model = [[RKModelMapperSpecModel alloc] autorelease]; - RKModelMapper* mapper = [[RKModelMapper alloc] init]; + RKResourceMapperSpecModel* model = [[RKResourceMapperSpecModel alloc] autorelease]; + RKResourceMapper* mapper = [[RKResourceMapper alloc] init]; model.createdAt = [NSDate date]; [mapper updateObject:model ifNewPropertyValue:[NSDate dateWithTimeIntervalSince1970:0] forPropertyNamed:@"createdAt"]; @@ -165,7 +162,7 @@ @end -@implementation RKModelMapperSpec (Private) +@implementation RKResourceMapperSpec (Private) - (NSString*)jsonString { return diff --git a/Specs/RKRequestSpec.m b/Specs/RKRequestSpec.m index 2d1288d3..c2a9a50a 100644 --- a/Specs/RKRequestSpec.m +++ b/Specs/RKRequestSpec.m @@ -6,9 +6,7 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import "UISpec.h" -#import "dsl/UIExpectation.h" - +#import "RKSpecEnvironment.h" #import "RKRequest.h" @interface RKRequestSpec : NSObject { diff --git a/Specs/RKStaticRouterSpec.m b/Specs/RKStaticRouterSpec.m new file mode 100644 index 00000000..8baa04cc --- /dev/null +++ b/Specs/RKStaticRouterSpec.m @@ -0,0 +1,29 @@ +// +// RKStaticRouterSpec.m +// RestKit +// +// Created by Blake Watters on 7/20/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "RKSpecEnvironment.h" +#import "RKStaticRouter.h" +#import "RKHuman.h" + +@interface RKStaticRouterSpec : NSObject { +} + +@end + +@implementation RKStaticRouterSpec + +-(void)itShouldReturnPathsRegisteredForSpecificRequestMethods { + RKStaticRouter* router = [[RKStaticRouter alloc] init]; + [router routeClass:[RKHuman class] toPath:@"/HumanService.asp" forMethod:RKRequestMethodGET]; +// [expectThat( +} + +-(void)itShouldReturnPathsRegisteredForTheClassAsAWhole { +} + +@end diff --git a/Specs/Support/OCMock b/Specs/Support/OCMock new file mode 160000 index 00000000..181d8cc5 --- /dev/null +++ b/Specs/Support/OCMock @@ -0,0 +1 @@ +Subproject commit 181d8cc5fffa93c9ad810e6fdd56ed699da207b8 diff --git a/Specs/Support/OCMock.framework/Headers b/Specs/Support/OCMock.framework/Headers deleted file mode 120000 index a177d2a6..00000000 --- a/Specs/Support/OCMock.framework/Headers +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Headers \ No newline at end of file diff --git a/Specs/Support/OCMock.framework/OCMock b/Specs/Support/OCMock.framework/OCMock deleted file mode 120000 index c388ea8d..00000000 --- a/Specs/Support/OCMock.framework/OCMock +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/OCMock \ No newline at end of file diff --git a/Specs/Support/OCMock.framework/Resources b/Specs/Support/OCMock.framework/Resources deleted file mode 120000 index 953ee36f..00000000 --- a/Specs/Support/OCMock.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/NSNotificationCenter+OCMAdditions.h b/Specs/Support/OCMock.framework/Versions/A/Headers/NSNotificationCenter+OCMAdditions.h deleted file mode 100644 index ae2e37d0..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/NSNotificationCenter+OCMAdditions.h +++ /dev/null @@ -1,15 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: NSNotificationCenter+OCMAdditions.h$ -// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import - -@class OCMockObserver; - - -@interface NSNotificationCenter(OCMAdditions) - -- (void)addMockObserver:(OCMockObserver *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender; - -@end diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMArg.h b/Specs/Support/OCMock.framework/Versions/A/Headers/OCMArg.h deleted file mode 100644 index b327512d..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMArg.h +++ /dev/null @@ -1,30 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: $ -// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import - -@interface OCMArg : NSObject - -// constraining arguments - -+ (id)any; -+ (void *)anyPointer; -+ (id)isNil; -+ (id)isNotNil; -+ (id)isNotEqual:(id)value; -+ (id)checkWithSelector:(SEL)selector onObject:(id)anObject; - -// manipulating arguments - -+ (id *)setTo:(id)value; - -// internal use only - -+ (id)resolveSpecialValues:(NSValue *)value; - -@end - -#define OCMOCK_ANY [OCMArg any] -#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(typeof(variable))] diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMConstraint.h b/Specs/Support/OCMock.framework/Versions/A/Headers/OCMConstraint.h deleted file mode 100644 index 8381dab9..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMConstraint.h +++ /dev/null @@ -1,48 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: $ -// Copyright (c) 2007-2009 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import - -@interface OCMConstraint : NSObject - -+ (id)constraint; -- (BOOL)evaluate:(id)value; - -// if you are looking for any, isNil, etc, they have moved to OCMArg - -+ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject; -+ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue; - -// try to use [OCMArg checkWith...] instead of constraintWithSelector in here - -@end - -@interface OCMAnyConstraint : OCMConstraint -@end - -@interface OCMIsNilConstraint : OCMConstraint -@end - -@interface OCMIsNotNilConstraint : OCMConstraint -@end - -@interface OCMIsNotEqualConstraint : OCMConstraint -{ - @public - id testValue; -} - -@end - -@interface OCMInvocationConstraint : OCMConstraint -{ - @public - NSInvocation *invocation; -} - -@end - -#define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self] -#define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)] diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMock.h b/Specs/Support/OCMock.framework/Versions/A/Headers/OCMock.h deleted file mode 100644 index 892b3cc2..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMock.h +++ /dev/null @@ -1,10 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: OCMock.h 39 2009-04-09 05:31:28Z erik $ -// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import -#import -#import -#import -#import diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockObject.h b/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockObject.h deleted file mode 100644 index a334b575..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockObject.h +++ /dev/null @@ -1,41 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: OCMockObject.h 52 2009-08-14 07:21:10Z erik $ -// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import - -@interface OCMockObject : NSProxy -{ - BOOL isNice; - BOOL expectationOrderMatters; - NSMutableArray *recorders; - NSMutableArray *expectations; - NSMutableArray *exceptions; -} - -+ (id)mockForClass:(Class)aClass; -+ (id)mockForProtocol:(Protocol *)aProtocol; -+ (id)partialMockForObject:(NSObject *)anObject; - -+ (id)niceMockForClass:(Class)aClass; -+ (id)niceMockForProtocol:(Protocol *)aProtocol; - -+ (id)observerMock; - -- (id)init; - -- (void)setExpectationOrderMatters:(BOOL)flag; - -- (id)stub; -- (id)expect; - -- (void)verify; - -// internal use only - -- (id)getNewRecorder; -- (BOOL)handleInvocation:(NSInvocation *)anInvocation; -- (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation; - -@end diff --git a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockRecorder.h b/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockRecorder.h deleted file mode 100644 index fea7b867..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Headers/OCMockRecorder.h +++ /dev/null @@ -1,28 +0,0 @@ -//--------------------------------------------------------------------------------------- -// $Id: OCMockRecorder.h 50 2009-07-16 06:48:19Z erik $ -// Copyright (c) 2004-2009 by Mulle Kybernetik. See License file for details. -//--------------------------------------------------------------------------------------- - -#import - -@interface OCMockRecorder : NSProxy -{ - id signatureResolver; - NSInvocation *recordedInvocation; - NSMutableArray *invocationHandlers; -} - -- (id)initWithSignatureResolver:(id)anObject; - -- (BOOL)matchesInvocation:(NSInvocation *)anInvocation; -- (void)releaseInvocation; - -- (id)andReturn:(id)anObject; -- (id)andReturnValue:(NSValue *)aValue; -- (id)andThrow:(NSException *)anException; -- (id)andPost:(NSNotification *)aNotification; -- (id)andCall:(SEL)selector onObject:(id)anObject; - -- (NSArray *)invocationHandlers; - -@end diff --git a/Specs/Support/OCMock.framework/Versions/A/OCMock b/Specs/Support/OCMock.framework/Versions/A/OCMock deleted file mode 100755 index 303e93375d12f6f5f04002921cb9fbc853d0da05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 291796 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%0A8*62Ay}uE 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 M^)7kzEgz8lf1+9m2><{9 diff --git a/Specs/Support/OCMock.framework/Versions/A/Resources/Info.plist b/Specs/Support/OCMock.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index 4634d14c..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - OCMock - CFBundleIdentifier - com.mulle-kybernetik.OCMock - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - OCMock - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.29 - CFBundleSignature - ???? - CFBundleVersion - 1 - NSHumanReadableCopyright - Copyright © 2004-2009 Mulle Kybernetik. - - diff --git a/Specs/Support/OCMock.framework/Versions/A/Resources/License.txt b/Specs/Support/OCMock.framework/Versions/A/Resources/License.txt deleted file mode 100644 index e2c13960..00000000 --- a/Specs/Support/OCMock.framework/Versions/A/Resources/License.txt +++ /dev/null @@ -1,15 +0,0 @@ - - Copyright (c) 2004-2009 by Mulle Kybernetik. All rights reserved. - - Permission to use, copy, modify and distribute this software and its documentation - is hereby granted, provided that both the copyright notice and this permission - notice appear in all copies of the software, derivative works or modified versions, - and any portions thereof, and that both notices appear in supporting documentation, - and that credit is given to Mulle Kybernetik in all documents and publicity - pertaining to direct or indirect use of this code or its derivatives. - - THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE - SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS - "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY - DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE - OR OF ANY DERIVATIVE WORK. \ No newline at end of file diff --git a/Specs/Support/OCMock.framework/Versions/Current b/Specs/Support/OCMock.framework/Versions/Current deleted file mode 120000 index 8c7e5a66..00000000 --- a/Specs/Support/OCMock.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -A \ No newline at end of file diff --git a/Specs/Support/RKSpecEnvironment.h b/Specs/Support/RKSpecEnvironment.h index bfb2826e..2e7f6804 100644 --- a/Specs/Support/RKSpecEnvironment.h +++ b/Specs/Support/RKSpecEnvironment.h @@ -6,16 +6,33 @@ // Copyright 2010 Two Toasters. All rights reserved. // -#import - -/** - * Redefine the OCMOCK_VALUE macro - * - * For some reason typeof and __typeof__ have changed behavior. Partial mocks that return - * primitive types were broken out of the box with OCMock - */ -#undef OCMOCK_VALUE -#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))] +//#import +// +///** +// * Redefine the OCMOCK_VALUE macro +// * +// * For some reason typeof and __typeof__ have changed behavior. Partial mocks that return +// * primitive types were broken out of the box with OCMock +// */ +//#undef OCMOCK_VALUE +//#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))] +// +//#import "UISpec.h" +//#import "dsl/UIExpectation.h" #import "UISpec.h" -#import "dsl/UIExpectation.h" +#import "UIBug.h" +#import "UIQuery.h" +#import "UIExpectation.h" + +#import +#import +#import +#import +#import + +//////////////////////////////////////////////////////////////////////////// +// OCMock - For some reason this macro is incorrect. Note the use of __typeof + +#undef OCMOCK_VALUE +#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof(variable))] diff --git a/Specs/Support/RKSpecResponseLoader.h b/Specs/Support/RKSpecResponseLoader.h index fa405d92..13ac772b 100644 --- a/Specs/Support/RKSpecResponseLoader.h +++ b/Specs/Support/RKSpecResponseLoader.h @@ -7,14 +7,15 @@ // #import -#import "RKModelLoader.h" +#import "RKResourceLoader.h" -@interface RKSpecResponseLoader : NSObject { +@interface RKSpecResponseLoader : NSObject { BOOL _awaitingResponse; BOOL _success; id _response; NSError* _failureError; NSString* _errorMessage; + NSTimeInterval _timeout; } // The object that was loaded from the web request @@ -29,6 +30,8 @@ // The error message returned by the server @property (nonatomic, readonly) NSString* errorMessage; +@property (nonatomic, assign) NSTimeInterval timeout; + // Wait for a response to load - (void)waitForResponse; - (void)loadResponse:(id)response; diff --git a/Specs/Support/RKSpecResponseLoader.m b/Specs/Support/RKSpecResponseLoader.m index fe54a7d8..5592b82a 100644 --- a/Specs/Support/RKSpecResponseLoader.m +++ b/Specs/Support/RKSpecResponseLoader.m @@ -15,6 +15,16 @@ @synthesize failureError = _failureError; @synthesize errorMessage = _errorMessage; @synthesize success = _success; +@synthesize timeout = _timeout; + +- (id)init { + if (self = [super init]) { + _timeout = 10; + _awaitingResponse = NO; + } + + return self; +} - (void)dealloc { [_response release]; @@ -25,9 +35,14 @@ - (void)waitForResponse { _awaitingResponse = YES; - while (_awaitingResponse == YES) { - [[NSRunLoop currentRunLoop] runUntilDate: - [NSDate dateWithTimeIntervalSinceNow:1.0]]; + NSDate* startDate = [NSDate date]; + + while (_awaitingResponse) { + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + if ([[NSDate date] timeIntervalSinceDate:startDate] > self.timeout) { + [NSException raise:nil format:@"*** Operation timed out after %f seconds...", self.timeout]; + _awaitingResponse = NO; + } } } @@ -38,7 +53,11 @@ _success = YES; } -- (void)modelLoaderRequest:(RKRequest*)request didFailWithError:(NSError*)error response:(RKResponse*)response model:(id)model { +- (void)resourceLoadRequest:(RKRequest*)request didLoadObjects:(NSArray*)objects response:(RKResponse*)response object:(id)object { + [self loadResponse:response]; +} + +- (void)resourceLoadRequest:(RKRequest*)request didFailWithError:(NSError*)error response:(RKResponse*)response object:(id)object { _awaitingResponse = NO; _success = NO; _failureError = [error retain]; diff --git a/Specs/Support/UISpec b/Specs/Support/UISpec new file mode 160000 index 00000000..98a723a2 --- /dev/null +++ b/Specs/Support/UISpec @@ -0,0 +1 @@ +Subproject commit 98a723a24d84d05c4a965656506f314723bf5b63 diff --git a/Specs/Support/set_ip_address.scpt b/Specs/Support/set_ip_address.scpt index 417d18e41e901ee33a3f8c5ee7a68f4c45123cd4..8c88d97a1fbdd2ca5a07ac03137cda922f760de9 100644 GIT binary patch delta 94 zcmdnxw#{ursyKUH)S~0t4c||8khNnuzP-YJ^E&ZvRt(X}>%`Y>HjsP3q9(#%$Y8*r g$6x})ra){2~qyPW_ delta 98 zcmdnyw##ipsyMsp!db`eTRfZWAZy2R?0%uz=5^xTtQew`*NLy&Y#{f5MN5Lgkine6 kh(Qlb>oFJrSw;-T43>=l?HL#ni<65O7#Vne-MhCI08OkRU;qFB diff --git a/Specs/UISpec+UISpecRunner.h b/Specs/UISpec+UISpecRunner.h new file mode 100644 index 00000000..1944cab6 --- /dev/null +++ b/Specs/UISpec+UISpecRunner.h @@ -0,0 +1,27 @@ +// +// UISpec+UISpecRunner.h +// UISpecRunner +// +// Created by Blake Watters on 7/15/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import +#import "UISpec.h" + +@interface UISpec (UISpecRunner) + +/** + * Run all UISpec classes conforming to a given protocol + */ ++(void)runSpecsConformingToProtocol:(Protocol *)protocol afterDelay:(NSTimeInterval)delay; + +/** + * Infers which set of UISpec classes to run from the following environment variables: + * UISPEC_PROTOCOL - Specifies a protocol to run + * UISPEC_SPEC - Specifies a spec class to run + * UISPEC_METHOD - Specifies an example to run (requires UISPEC_SPEC to be set) + */ ++(void)runSpecsFromEnvironmentAfterDelay:(int)seconds; + +@end diff --git a/Specs/UISpec+UISpecRunner.m b/Specs/UISpec+UISpecRunner.m new file mode 100644 index 00000000..149384b8 --- /dev/null +++ b/Specs/UISpec+UISpecRunner.m @@ -0,0 +1,69 @@ +// +// UISpec+UISpecRunner.m +// UISpecRunner +// +// Created by Blake Watters on 7/15/10. +// Copyright 2010 Two Toasters. All rights reserved. +// + +#import "UISpec+UISpecRunner.h" +#import + +@implementation UISpec (UISpecRunner) + ++(BOOL)class:(Class)class conformsToProtocol:(Protocol *)protocol { + while (class) { + if (class_conformsToProtocol(class, protocol)) { + return YES; + } + class = class_getSuperclass(class); + } + return NO; +} + ++(NSArray*)specClassesConformingToProtocol:(Protocol *)protocol { + NSMutableArray *array = [NSMutableArray array]; + int numClasses = objc_getClassList(NULL, 0); + if (numClasses > 0) { + Class *classes = malloc(sizeof(Class) * numClasses); + (void) objc_getClassList (classes, numClasses); + int i; + for (i = 0; i < numClasses; i++) { + Class c = classes[i]; + if ([self isASpec:c] && [self class:c conformsToProtocol:protocol]) { + [array addObject:c]; + } + } + free(classes); + } + return array; +} + ++(void)runSpecsConformingToProtocol:(Protocol *)protocol afterDelay:(NSTimeInterval)delay { + NSArray* specClasses = [self specClassesConformingToProtocol:protocol]; + [self performSelector:@selector(runSpecClasses:) withObject:specClasses afterDelay:delay]; +} + ++(void)runSpecsFromEnvironmentAfterDelay:(int)seconds { + char* protocolName = getenv("UISPEC_PROTOCOL"); + char* specName = getenv("UISPEC_SPEC"); + char* exampleName = getenv("UISPEC_EXAMPLE"); + if (protocolName) { + Protocol* protocol = NSProtocolFromString([NSString stringWithUTF8String:protocolName]); + NSLog(@"[UISpecRunner] Running Specs conforming to Protocol: %@", [NSString stringWithUTF8String:protocolName]); + [UISpec runSpecsConformingToProtocol:protocol afterDelay:seconds]; + } else if (exampleName) { + if (nil == specName) { + [NSException raise:nil format:@"UISPEC_EXAMPLE cannot be specified without providing UISPEC_SPEC"]; + } + NSLog(@"[UISpecRunner] Running Examples %s on Spec %s", exampleName, specName); + [UISpec runSpec:[NSString stringWithUTF8String:specName] example:[NSString stringWithUTF8String:exampleName] afterDelay:seconds]; + } else if (specName) { + NSLog(@"[UISpecRunner] Running Spec %s", specName); + [UISpec runSpec:[NSString stringWithUTF8String:specName] afterDelay:seconds]; + } else { + [UISpec runSpecsAfterDelay:seconds]; + } +} + +@end diff --git a/Specs/main.m b/Specs/main.m index a1a5b61b..7342a6a8 100644 --- a/Specs/main.m +++ b/Specs/main.m @@ -1,28 +1,23 @@ // // main.m -// RestKit +// UISpecRunner // -// Created by Jeremy Ellison on 12/7/09. -// Copyright Two Toasters 2009. All rights reserved. +// Created by Blake Watters on 4/20/10. +// Copyright 2010 Two Toasters. All rights reserved. // #import -#import +#import "UISpec.h" +#import "UISpec+UISpecRunner.h" int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - char* specName = getenv("UISPEC_RUN_SPEC"); - NSString* specToRun = [NSString stringWithFormat:@"%s", specName]; - if (specName && NO == [specToRun isEqualToString:@""]) { - NSLog(@"UISpec - Running individual spec '%@'", specToRun); - [UISpec runSpec:specToRun afterDelay:1]; - } else { - [UISpec runSpecs]; - } + // Run the specs + [UISpec runSpecsFromEnvironmentAfterDelay:0.5]; - int retVal = UIApplicationMain(argc, argv, nil, nil); + int retVal = UIApplicationMain(argc, argv, nil, @"InMotionAppDelegate"); [pool release]; return retVal; }