For this project component, you will use the skills you gained in this unit’s study activities to implement the Smart Homes, Inc. store locator application’s user interface, allowing the user to browse the results returned from submitting search parameters in the search input interface. When the user taps the submit button to send the search parameters, the application should do the following:
- Use the BBYOPEN API to retrieve a list of stores using the search parameters.
- Display the list of returned stores in a scrollable table with the closest store at the top and the farthest store at the bottom.
Your completed assignment should achieve the following:
- Demonstrate an ability to integrate third-party application programming interfaces to communicate with a Web service.
- Construct an iOS application that communicates with a third-party Web service without blocking the user interface.
- Demonstrate the ability to troubleshoot network communication errors when using a third-party Web service integrated with an iOS application.
When complete, submit your assignment in the assignment area as a .zip file containing all of the files you created to build your solution.
****** Hint ******
All you need to do what the SHNetworkDelegate.h tells you to do, namely:
/** * The following method retrieves an array of Store objects from the BBYOpen API. * * @param aZipcode The string representing the zipcode to retrieve stores for. * @param distance The string representing the distance radius in miles to search around the supplied zipcode. * @param delegate Any object that must conform to the
– (void)attemptRetrieveStoresWithZipcode:(NSString *)aZipcode distance:(NSString *)distance andDelegate:(id)delegate;
All you need to do is call the above method and ensure that you implement the didRetrieveStores: delegate method defined in SHNetworkDelegate.h
IT4781-U02A1-AlexBenavides/.DS_Store
__MACOSX/IT4781-U02A1-AlexBenavides/._.DS_Store
IT4781-U02A1-AlexBenavides/Default
__MACOSX/IT4781-U02A1-AlexBenavides/._Default
IT4781-U02A1-AlexBenavides/Icon@2x
__MACOSX/IT4781-U02A1-AlexBenavides/._Icon@2x
IT4781-U02A1-AlexBenavides/Icon_57x57
__MACOSX/IT4781-U02A1-AlexBenavides/._Icon_57x57
IT4781-U02A1-AlexBenavides/StoreLocator/.DS_Store
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/._.DS_Store
IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/.DS_Store
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/._.DS_Store
IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/SHAppDelegate.h
//
// SHAppDelegate.h
// StoreLocator
//
// Created by Fredrick Gabelmann on 8/17/12.
// Copyright (c) 2012 Smart Homes. All rights reserved.
//
#import
@interface SHAppDelegate : UIResponder
@property (strong, nonatomic) UIWindow *window;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/._SHAppDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/SHAppDelegate.m
//
// SHAppDelegate.m
// StoreLocator
//
// Created by Fredrick Gabelmann on 8/17/12.
// Copyright (c) 2012 Smart Homes. All rights reserved.
//
#import “SHAppDelegate.h”
#import “SHNetworkDelegate.h”
@implementation SHAppDelegate
– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Configure Network Layer
[[SHNetworkDelegate sharedDelegate] configureNetworkLayer];
// Override point for customization after application launch.
return YES;
}
– (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
– (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
– (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
– (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
– (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/AppDelegate/._SHAppDelegate.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/._AppDelegate
IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/.DS_Store
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/._.DS_Store
IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/SHViewController.h
//
// SHViewController.h
// StoreLocator
//
// Created by Fredrick Gabelmann on 8/17/12.
// Copyright (c) 2012 Smart Homes. All rights reserved.
//
#import
@interface SHViewController : UIViewController
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/._SHViewController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/SHViewController.m
//
// SHViewController.m
// StoreLocator
//
// Created by Fredrick Gabelmann on 8/17/12.
// Copyright (c) 2012 Smart Homes. All rights reserved.
//
#import “SHViewController.h”
@interface SHViewController ()
@end
@implementation SHViewController
– (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
– (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Controllers/._SHViewController.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/._Controllers
IT4781-U02A1-AlexBenavides/StoreLocator/Data Model/Store.h
//
// Profile.h
// sartorii
//
// Created by Gabelmann Fredrick on 5/4/12.
// Copyright (c) 2012 Reticent Media, Inc. All rights reserved.
//
#import
@interface Store : NSObject
#pragma mark – Properites
@property (strong, nonatomic) NSString *region;
@property (strong, nonatomic) NSString *city;
@property (strong, nonatomic) NSString *address;
@property (strong, nonatomic) NSString *longName;
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *country;
@property (assign) float lng;
@property (strong, nonatomic) NSString *postalCode;
@property (strong, nonatomic) NSString *phone;
@property (strong, nonatomic) NSString *hours;
@property (assign) NSInteger storeId;
@property (assign) float lat;
@property (strong, nonatomic) NSString *fullPostalCode;
@property (assign) float distance;
#pragma mark – Initializers
– (id)initForStores:(RKObjectManager *)objectManager;
#pragma mark – Requests
– (void)getStoresWithZipcode:(NSString *)aZipcode distance:(NSString *)aDistance andDelegate:(id)delegate;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Data Model/._Store.h
IT4781-U02A1-AlexBenavides/StoreLocator/Data Model/Store.m
//
// Profile.m
// sartorii
//
// Created by Gabelmann Fredrick on 5/4/12.
// Copyright (c) 2012 Reticent Media, Inc. All rights reserved.
//
#import “Store.h”
@interface Store ()
@property (nonatomic, strong) RKObjectManager *manager;
@end
@implementation Store
#pragma mark – Properties
@synthesize region;
@synthesize city;
@synthesize address;
@synthesize longName;
@synthesize name;
@synthesize country;
@synthesize lng;
@synthesize postalCode;
@synthesize phone;
@synthesize hours;
@synthesize storeId;
@synthesize lat;
@synthesize fullPostalCode;
@synthesize distance;
@synthesize manager;
#pragma mark – Initializers
– (id)initForStores:(RKObjectManager *)objectManager
{
self = [super init];
if (self) {
self.manager = objectManager;
RKObjectMapping *successResponseMapping = [RKObjectMapping mappingForClass:[Store class]];
[successResponseMapping mapAttributes:@”region”, @”city”, @”address”, @”longName”, @”name”, @”country”, @”lng”, @”postalCode”, @”phone”, @”hours”, @”storeId”, @”lat”, @”fullPostalCode”, @”distance”, nil];
[self.manager.mappingProvider setMapping:successResponseMapping forKeyPath:@”stores”];
}
return self;
}
#pragma mark – Requests
– (void)getStoresWithZipcode:(NSString *)aZipcode distance:(NSString *)aDistance andDelegate:(id)delegate
{
[self.manager loadObjectsAtResourcePath:[NSString stringWithFormat:@”/stores(area(%@,%@))?apiKey=%@&format=json”, aZipcode, aDistance, kBbyopenApiKey] delegate:delegate];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Data Model/._Store.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/._Data Model
IT4781-U02A1-AlexBenavides/StoreLocator/en.lproj/InfoPlist.strings
/* Localized versions of Info.plist keys */
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/en.lproj/._InfoPlist.strings
IT4781-U02A1-AlexBenavides/StoreLocator/en.lproj/MainStoryboard_iPad.storyboard
IT4781-U02A1-AlexBenavides/StoreLocator/en.lproj/MainStoryboard_iPhone.storyboard
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/._en.lproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/.DS_Store
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/._.DS_Store
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/.gitignore
# the build
Build
build
# DerivedData
Docs/API
# temp nibs and swap files
*~.nib
*.swp
*.orig
# OS X folder attributes
.DS_Store
# user-specific XCode stuff
*.mode1v3
*.mode2v3
*.pbxuser
*.perspectivev3
*.xcuserdatad
Examples/RKDiscussionBoardExample/discussion_board_backend/public/system/attachments/*
test-reports/
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._.gitignore
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/.gitmodules
[submodule “Examples/RKCatalog/Server”]
path = Examples/RKCatalog/Server
url = git://github.com/RestKit/RKCatalog-Server.git
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._.gitmodules
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/.rvmrc
rvm use 1.9.2@RestKit
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._.rvmrc
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/CoreData.h
//
// CoreData.h
// RestKit
//
// Created by Blake Watters on 9/30/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “ObjectMapping.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKManagedObjectStore.h”
#import “RKManagedObjectSeeder.h”
#import “RKManagedObjectMapping.h”
#import “RKManagedObjectMappingOperation.h”
#import “RKManagedObjectCaching.h”
#import “RKInMemoryManagedObjectCache.h”
#import “RKFetchRequestManagedObjectCache.h”
#import “RKSearchableManagedObject.h”
#import “RKSearchWord.h”
#import “RKObjectPropertyInspector+CoreData.h”
#import “RKObjectMappingProvider+CoreData.h”
#import “NSManagedObjectContext+RKAdditions.h”
#import “NSManagedObject+RKAdditions.h”
#import “NSEntityDescription+RKAdditions.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._CoreData.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSEntityDescription+RKAdditions.h
//
// NSEntityDescription+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 3/22/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
The key for retrieving the name of the attribute that acts as
the primary key from the user info dictionary of the receiving NSEntityDescription.
**Value**: @”primaryKeyAttribute”
*/
extern NSString * const RKEntityDescriptionPrimaryKeyAttributeUserInfoKey;
/**
The substitution variable used in predicateForPrimaryKeyAttribute.
**Value**: @”PRIMARY_KEY_VALUE”
@see predicateForPrimaryKeyAttribute
*/
extern NSString * const RKEntityDescriptionPrimaryKeyAttributeValuePredicateSubstitutionVariable;
/**
Provides extensions to NSEntityDescription for various common tasks.
*/
@interface NSEntityDescription (RKAdditions)
/**
The name of the attribute that acts as the primary key for the receiver.
The primary key attribute can be configured in two ways:
1. From within the Xcode Core Data editing view by
adding the desired attribute’s name as the value for the
key `primaryKeyAttribute` to the user info dictionary.
1. Programmatically, by retrieving the NSEntityDescription instance and
setting the property’s value.
Programmatically configured values take precedence over the user info
dictionary.
*/
@property (nonatomic, retain) NSString *primaryKeyAttributeName;
/**
The attribute description object for the attribute designated as the primary key for the receiver.
*/
@property (nonatomic, readonly) NSAttributeDescription *primaryKeyAttribute;
/**
The class representing the value of the attribute designated as the primary key for the receiver.
*/
@property (nonatomic, readonly) Class primaryKeyAttributeClass;
/**
Returns a cached predicate specifying that the primary key attribute is equal to the $PRIMARY_KEY_VALUE
substitution variable.
This predicate is cached to avoid parsing overhead during object mapping operations
and must be evaluated using [NSPredicate predicateWithSubstitutionVariables:]
@return A cached predicate specifying the value of the primary key attribute is equal to the $PRIMARY_KEY_VALUE
substitution variable.
*/
– (NSPredicate *)predicateForPrimaryKeyAttribute;
/**
Returns a predicate specifying that the value of the primary key attribute is equal to a given
value. This predicate is constructed by evaluating the cached predicate returned by the
predicateForPrimaryKeyAttribute with a dictionary of substitution variables specifying that
$PRIMARY_KEY_VALUE is equal to the given value.
**NOTE**: This method considers the type of the receiver’s primary key attribute when constructing
the predicate. It will coerce the given value into either an NSString or an NSNumber as
appropriate. This behavior is a convenience to avoid annoying issues related to Core Data’s
handling of predicates for NSString and NSNumber types that were not appropriately casted.
@return A predicate speciying that the value of the primary key attribute is equal to a given value.
*/
– (NSPredicate *)predicateForPrimaryKeyAttributeWithValue:(id)value;
/**
Coerces the given value into the class representing the primary key. Currently support NSString
and NSNumber coercsions.
@bug **NOTE** This API is temporary and will be deprecated and replaced.
@since 0.10.1
*/
– (id)coerceValueForPrimaryKey:(id)primaryKeyValue;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSEntityDescription+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSEntityDescription+RKAdditions.m
//
// NSEntityDescription+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 3/22/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import “NSEntityDescription+RKAdditions.h”
NSString * const RKEntityDescriptionPrimaryKeyAttributeUserInfoKey = @”primaryKeyAttribute”;
NSString * const RKEntityDescriptionPrimaryKeyAttributeValuePredicateSubstitutionVariable = @”PRIMARY_KEY_VALUE”;
static char primaryKeyAttributeNameKey, primaryKeyPredicateKey;
@implementation NSEntityDescription (RKAdditions)
– (void)setPredicateForPrimaryKeyAttribute:(NSString *)primaryKeyAttribute
{
NSPredicate *predicate = (primaryKeyAttribute) ? [NSPredicate predicateWithFormat:@”%K == $PRIMARY_KEY_VALUE”, primaryKeyAttribute] : nil;
objc_setAssociatedObject(self,
&primaryKeyPredicateKey,
predicate,
OBJC_ASSOCIATION_RETAIN);
}
#pragma mark – Public
– (NSAttributeDescription *)primaryKeyAttribute
{
return [[self attributesByName] valueForKey:[self primaryKeyAttributeName]];
}
– (Class)primaryKeyAttributeClass
{
NSAttributeDescription *attributeDescription = [self primaryKeyAttribute];
if (attributeDescription) {
return NSClassFromString(attributeDescription.attributeValueClassName);
}
return nil;
}
– (NSString *)primaryKeyAttributeName
{
// Check for an associative object reference
NSString *primaryKeyAttribute = (NSString *) objc_getAssociatedObject(self, &primaryKeyAttributeNameKey);
// Fall back to the userInfo dictionary
if (! primaryKeyAttribute) {
primaryKeyAttribute = [self.userInfo valueForKey:RKEntityDescriptionPrimaryKeyAttributeUserInfoKey];
// If we have loaded from the user info, ensure we have a predicate
if (! [self predicateForPrimaryKeyAttribute]) {
[self setPredicateForPrimaryKeyAttribute:primaryKeyAttribute];
}
}
return primaryKeyAttribute;
}
– (void)setPrimaryKeyAttributeName:(NSString *)primaryKeyAttributeName
{
objc_setAssociatedObject(self,
&primaryKeyAttributeNameKey,
primaryKeyAttributeName,
OBJC_ASSOCIATION_RETAIN);
[self setPredicateForPrimaryKeyAttribute:primaryKeyAttributeName];
}
– (NSPredicate *)predicateForPrimaryKeyAttribute
{
return (NSPredicate *) objc_getAssociatedObject(self, &primaryKeyPredicateKey);
}
– (id)coerceValueForPrimaryKey:(id)primaryKeyValue
{
id searchValue = primaryKeyValue;
Class theClass = [self primaryKeyAttributeClass];
if (theClass) {
// TODO: This coercsion behavior should be pluggable and reused from the mapper
if ([theClass isSubclassOfClass:[NSNumber class]] && ![searchValue isKindOfClass:[NSNumber class]]) {
// Handle NSString -> NSNumber
if ([searchValue isKindOfClass:[NSString class]]) {
searchValue = [NSNumber numberWithDouble:[searchValue doubleValue]];
}
} else if ([theClass isSubclassOfClass:[NSString class]] && ![searchValue isKindOfClass:[NSString class]]) {
// Coerce to string
if ([searchValue respondsToSelector:@selector(stringValue)]) {
searchValue = [searchValue stringValue];
}
}
}
return searchValue;
}
– (NSPredicate *)predicateForPrimaryKeyAttributeWithValue:(id)value
{
id substitutionValue = [self coerceValueForPrimaryKey:value];
NSDictionary *variables = [NSDictionary dictionaryWithObject:substitutionValue
forKey:RKEntityDescriptionPrimaryKeyAttributeValuePredicateSubstitutionVariable];
return [[self predicateForPrimaryKeyAttribute] predicateWithSubstitutionVariables:variables];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSEntityDescription+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObject+ActiveRecord.h
//
// NSManagedObject+ActiveRecord.h
//
// Adapted from https://github.com/magicalpanda/MagicalRecord
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
// Created by Chad Podoski on 3/18/11.
//
#import
/**
Extensions to NSManagedObjectContext for RestKit’s Active Record pattern implementation
*/
@interface NSManagedObjectContext (ActiveRecord)
+ (NSManagedObjectContext *)defaultContext;
+ (void)setDefaultContext:(NSManagedObjectContext *)context;
+ (NSManagedObjectContext *)contextForCurrentThread;
@end
/**
Provides extensions to NSManagedObject implementing a low-ceremony querying
interface.
*/
@interface NSManagedObject (ActiveRecord)
/**
* The NSEntityDescription for the Subclass
* defaults to the subclass className, may be overridden
*/
+ (NSEntityDescription*)entity;
/**
* Returns an initialized NSFetchRequest for the entity, with no predicate
*/
+ (NSFetchRequest*)fetchRequest;
/**
* Fetches all objects from the persistent store identified by the fetchRequest
*/
+ (NSArray*)objectsWithFetchRequest:(NSFetchRequest*)fetchRequest;
/**
* Retrieves the number of objects that would be retrieved by the fetchRequest,
* if executed
*/
+ (NSUInteger)countOfObjectsWithFetchRequest:(NSFetchRequest*)fetchRequest;
/**
* Fetches all objects from the persistent store via a set of fetch requests and
* returns all results in a single array.
*/
+ (NSArray*)objectsWithFetchRequests:(NSArray*)fetchRequests;
/**
* Fetches the first object identified by the fetch request. A limit of one will be
* applied to the fetch request before dispatching.
*/
+ (id)objectWithFetchRequest:(NSFetchRequest*)fetchRequest;
/**
* Fetches all objects from the persistent store by constructing a fetch request and
* applying the predicate supplied. A short-cut for doing filtered searches on the objects
* of this class under management.
*/
+ (NSArray*)objectsWithPredicate:(NSPredicate*)predicate;
/**
* Fetches the first object matching a predicate from the persistent store. A fetch request
* will be constructed for you and a fetch limit of 1 will be applied.
*/
+ (id)objectWithPredicate:(NSPredicate*)predicate;
/**
* Fetches all managed objects of this class from the persistent store as an array
*/
+ (NSArray*)allObjects;
/**
* Returns a count of all managed objects of this class in the persistent store. On
* error, will populate the error argument
*/
+ (NSUInteger)count:(NSError**)error;
/**
* Returns a count of all managed objects of this class in the persistent store. Deprecated
* use the error form above
*
* @deprecated
*/
+ (NSUInteger)count DEPRECATED_ATTRIBUTE;
/**
* Creates a new managed object and inserts it into the managedObjectContext.
*/
+ (id)object;
/**
* Returns YES when an object has not been saved to the managed object context yet
*/
– (BOOL)isNew;
/**
Finds the instance of the receiver’s entity with the given value for the primary key attribute
in the managed object context for the current thread.
@param primaryKeyValue The value for the receiving entity’s primary key attribute.
@return The object with the primary key attribute equal to the given value or nil.
*/
+ (id)findByPrimaryKey:(id)primaryKeyValue;
/**
Finds the instance of the receiver’s entity with the given value for the primary key attribute in
the given managed object context.
@param primaryKeyValue The value for the receiving entity’s primary key attribute.
@param context The managed object context to find the instance in.
@return The object with the primary key attribute equal to the given value or nil.
*/
+ (id)findByPrimaryKey:(id)primaryKeyValue inContext:(NSManagedObjectContext *)context;
////////////////////////////////////////////////////////////////////////////////////////////////////
+ (NSManagedObjectContext*)currentContext;
+ (void)handleErrors:(NSError *)error;
+ (NSArray *)executeFetchRequest:(NSFetchRequest *)request;
+ (NSArray *)executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)createFetchRequest;
+ (NSFetchRequest *)createFetchRequestInContext:(NSManagedObjectContext *)context;
+ (NSEntityDescription *)entityDescription;
+ (NSEntityDescription *)entityDescriptionInContext:(NSManagedObjectContext *)context;
+ (NSArray *)propertiesNamed:(NSArray *)properties;
+ (id)createEntity;
+ (id)createInContext:(NSManagedObjectContext *)context;
– (BOOL)deleteEntity;
– (BOOL)deleteInContext:(NSManagedObjectContext *)context;
+ (BOOL)truncateAll;
+ (BOOL)truncateAllInContext:(NSManagedObjectContext *)context;
+ (NSArray *)ascendingSortDescriptors:(id)attributesToSortBy, …;
+ (NSArray *)descendingSortDescriptors:(id)attributesToSortyBy, …;
+ (NSNumber *)numberOfEntities;
+ (NSNumber *)numberOfEntitiesWithContext:(NSManagedObjectContext *)context;
+ (NSNumber *)numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm;
+ (NSNumber *)numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (BOOL) hasAtLeastOneEntity;
+ (BOOL) hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestAll;
+ (NSFetchRequest *)requestAllInContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestAllWhere:(NSString *)property isEqualTo:(id)value;
+ (NSFetchRequest *)requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestFirstWithPredicate:(NSPredicate *)searchTerm;
+ (NSFetchRequest *)requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue;
+ (NSFetchRequest *)requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm;
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (NSArray *)findAll;
+ (NSArray *)findAllInContext:(NSManagedObjectContext *)context;
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm;
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
/*+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;*/
+ (NSArray *)findAllWithPredicate:(NSPredicate *)searchTerm;
+ (NSArray *)findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (NSNumber *)maxValueFor:(NSString *)property;
+ (id) objectWithMinValueFor:(NSString *)property;
+ (id) objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context;
+ (id)findFirst;
+ (id)findFirstInContext:(NSManagedObjectContext *)context;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (id)findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending;
+ (id)findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, …;
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, …;
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue;
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context;
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue;
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context;
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending;
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE
+ (NSFetchedResultsController *)fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath;
+ (NSFetchedResultsController *)fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context;
+ (NSFetchedResultsController *)fetchRequest:(NSFetchRequest *)request groupedBy:(NSString *)group;
+ (NSFetchedResultsController *)fetchRequest:(NSFetchRequest *)request groupedBy:(NSString *)group inContext:(NSManagedObjectContext *)context;
+ (NSFetchedResultsController *)fetchRequestAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;
+ (NSFetchedResultsController *)fetchRequestAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
#endif
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObject+ActiveRecord.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObject+ActiveRecord.m
//
// NSManagedObject+ActiveRecord.m
//
// Adapted from https://github.com/magicalpanda/MagicalRecord
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
// Created by Chad Podoski on 3/18/11.
//
#import
#import “NSManagedObject+ActiveRecord.h”
#import “RKManagedObjectStore.h”
#import “RKLog.h”
#import “RKFixCategoryBug.h”
#import “NSEntityDescription+RKAdditions.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
static NSUInteger const kActiveRecordDefaultBatchSize = 10;
static NSNumber *defaultBatchSize = nil;
static NSManagedObjectContext *defaultContext = nil;
RK_FIX_CATEGORY_BUG(NSManagedObjectContext_ActiveRecord)
@implementation NSManagedObjectContext (ActiveRecord)
+ (NSManagedObjectContext *)defaultContext {
return defaultContext;
}
+ (void)setDefaultContext:(NSManagedObjectContext *)newDefaultContext {
[newDefaultContext retain];
[defaultContext release];
defaultContext = newDefaultContext;
}
+ (NSManagedObjectContext *)contextForCurrentThread {
NSAssert([RKManagedObjectStore defaultObjectStore], @”[RKManagedObjectStore defaultObjectStore] cannot be nil”);
return [[RKManagedObjectStore defaultObjectStore] managedObjectContextForCurrentThread];
}
@end
RK_FIX_CATEGORY_BUG(NSManagedObject_ActiveRecord)
@implementation NSManagedObject (ActiveRecord)
#pragma mark – RKManagedObject methods
+ (NSEntityDescription*)entity {
NSString* className = [NSString stringWithCString:class_getName([self class]) encoding:NSASCIIStringEncoding];
return [NSEntityDescription entityForName:className inManagedObjectContext:[NSManagedObjectContext contextForCurrentThread]];
}
+ (NSFetchRequest*)fetchRequest {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [self entity];
[fetchRequest setEntity:entity];
return fetchRequest;
}
+ (NSArray*)objectsWithFetchRequest:(NSFetchRequest*)fetchRequest {
NSError* error = nil;
NSArray* objects = [[NSManagedObjectContext contextForCurrentThread] executeFetchRequest:fetchRequest error:&error];
if (objects == nil) {
RKLogError(@”Error: %@”, [error localizedDescription]);
}
return objects;
}
+ (NSUInteger)countOfObjectsWithFetchRequest:(NSFetchRequest*)fetchRequest {
NSError* error = nil;
NSUInteger objectCount = [[NSManagedObjectContext contextForCurrentThread] countForFetchRequest:fetchRequest error:&error];
if (objectCount == NSNotFound) {
RKLogError(@”Error: %@”, [error localizedDescription]);
}
return objectCount;
}
+ (NSArray*)objectsWithFetchRequests:(NSArray*)fetchRequests {
NSMutableArray* mutableObjectArray = [[NSMutableArray alloc] init];
for (NSFetchRequest* fetchRequest in fetchRequests) {
[mutableObjectArray addObjectsFromArray:[self objectsWithFetchRequest:fetchRequest]];
}
NSArray* objects = [NSArray arrayWithArray:mutableObjectArray];
[mutableObjectArray release];
return objects;
}
+ (id)objectWithFetchRequest:(NSFetchRequest*)fetchRequest {
[fetchRequest setFetchLimit:1];
NSArray* objects = [self objectsWithFetchRequest:fetchRequest];
if ([objects count] == 0) {
return nil;
} else {
return [objects objectAtIndex:0];
}
}
+ (NSArray*)objectsWithPredicate:(NSPredicate*)predicate {
NSFetchRequest* fetchRequest = [self fetchRequest];
[fetchRequest setPredicate:predicate];
return [self objectsWithFetchRequest:fetchRequest];
}
+ (id)objectWithPredicate:(NSPredicate*)predicate {
NSFetchRequest* fetchRequest = [self fetchRequest];
[fetchRequest setPredicate:predicate];
return [self objectWithFetchRequest:fetchRequest];
}
+ (NSArray*)allObjects {
return [self objectsWithPredicate:nil];
}
+ (NSUInteger)count:(NSError**)error {
NSFetchRequest* fetchRequest = [self fetchRequest];
return [[NSManagedObjectContext contextForCurrentThread] countForFetchRequest:fetchRequest error:error];
}
+ (NSUInteger)count {
NSError *error = nil;
return [self count:&error];
}
+ (id)object {
id object = [[self alloc] initWithEntity:[self entity] insertIntoManagedObjectContext:[NSManagedObjectContext contextForCurrentThread]];
return [object autorelease];
}
– (BOOL)isNew {
NSDictionary *vals = [self committedValuesForKeys:nil];
return [vals count] == 0;
}
+ (id)findByPrimaryKey:(id)primaryKeyValue inContext:(NSManagedObjectContext *)context {
NSPredicate *predicate = [[self entityDescriptionInContext:context] predicateForPrimaryKeyAttributeWithValue:primaryKeyValue];
if (! predicate) {
RKLogWarning(@”Attempt to findByPrimaryKey for entity with nil primaryKeyAttribute. Set the primaryKeyAttributeName and try again! %@”, self);
return nil;
}
return [self findFirstWithPredicate:predicate inContext:context];
}
+ (id)findByPrimaryKey:(id)primaryKeyValue {
return [self findByPrimaryKey:primaryKeyValue inContext:[NSManagedObjectContext contextForCurrentThread]];
}
#pragma mark – MagicalRecord Ported Methods
+ (NSManagedObjectContext*)currentContext; {
return [NSManagedObjectContext contextForCurrentThread];
}
+ (void)setDefaultBatchSize:(NSUInteger)newBatchSize
{
@synchronized(defaultBatchSize)
{
defaultBatchSize = [NSNumber numberWithUnsignedInteger:newBatchSize];
}
}
+ (NSInteger)defaultBatchSize
{
if (defaultBatchSize == nil)
{
[self setDefaultBatchSize:kActiveRecordDefaultBatchSize];
}
return [defaultBatchSize integerValue];
}
+ (void)handleErrors:(NSError *)error
{
if (error)
{
NSDictionary *userInfo = [error userInfo];
for (NSArray *detailedError in [userInfo allValues])
{
if ([detailedError isKindOfClass:[NSArray class]])
{
for (NSError *e in detailedError)
{
if ([e respondsToSelector:@selector(userInfo)])
{
RKLogError(@”Error Details: %@”, [e userInfo]);
}
else
{
RKLogError(@”Error Details: %@”, e);
}
}
}
else
{
RKLogError(@”Error: %@”, detailedError);
}
}
RKLogError(@”Error Domain: %@”, [error domain]);
RKLogError(@”Recovery Suggestion: %@”, [error localizedRecoverySuggestion]);
}
}
+ (NSArray *)executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context
{
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
[self handleErrors:error];
return results;
}
+ (NSArray *)executeFetchRequest:(NSFetchRequest *)request
{
return [self executeFetchRequest:request inContext:[self currentContext]];
}
+ (id)executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context
{
[request setFetchLimit:1];
NSArray *results = [self executeFetchRequest:request inContext:context];
if ([results count] == 0)
{
return nil;
}
return [results objectAtIndex:0];
}
+ (id)executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request
{
return [self executeFetchRequestAndReturnFirstObject:request inContext:[self currentContext]];
}
#if TARGET_OS_IPHONE
+ (void)performFetch:(NSFetchedResultsController *)controller
{
NSError *error = nil;
if (![controller performFetch:&error])
{
[self handleErrors:error];
}
}
#endif
+ (NSEntityDescription *)entityDescriptionInContext:(NSManagedObjectContext *)context
{
NSString *entityName = NSStringFromClass([self class]);
return [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
}
+ (NSEntityDescription *)entityDescription
{
return [self entityDescriptionInContext:[self currentContext]];
}
+ (NSArray *)propertiesNamed:(NSArray *)properties
{
NSEntityDescription *description = [self entityDescription];
NSMutableArray *propertiesWanted = [NSMutableArray array];
if (properties)
{
NSDictionary *propDict = [description propertiesByName];
for (NSString *propertyName in properties)
{
NSPropertyDescription *property = [propDict objectForKey:propertyName];
if (property)
{
[propertiesWanted addObject:property];
}
else
{
RKLogError(@”Property ‘%@’ not found in %@ properties for %@”, propertyName, [propDict count], NSStringFromClass(self));
}
}
}
return propertiesWanted;
}
+ (NSArray *)sortAscending:(BOOL)ascending attributes:(id)attributesToSortBy, …
{
NSMutableArray *attributes = [NSMutableArray array];
if ([attributesToSortBy isKindOfClass:[NSArray class]])
{
id attributeName;
va_list variadicArguments;
va_start(variadicArguments, attributesToSortBy);
while ((attributeName = va_arg(variadicArguments, id))!= nil)
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:attributeName ascending:ascending];
[attributes addObject:sortDescriptor];
[sortDescriptor release];
}
va_end(variadicArguments);
}
else if ([attributesToSortBy isKindOfClass:[NSString class]])
{
va_list variadicArguments;
va_start(variadicArguments, attributesToSortBy);
[attributes addObject:[[[NSSortDescriptor alloc] initWithKey:attributesToSortBy ascending:ascending] autorelease] ];
va_end(variadicArguments);
}
return attributes;
}
+ (NSArray *)ascendingSortDescriptors:(id)attributesToSortBy, …
{
return [self sortAscending:YES attributes:attributesToSortBy];
}
+ (NSArray *)descendingSortDescriptors:(id)attributesToSortyBy, …
{
return [self sortAscending:NO attributes:attributesToSortyBy];
}
+ (NSFetchRequest *)createFetchRequestInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[self entityDescriptionInContext:context]];
return request;
}
+ (NSFetchRequest *)createFetchRequest
{
return [self createFetchRequestInContext:[self currentContext]];
}
#pragma mark –
#pragma mark Number of Entities
+ (NSNumber *)numberOfEntitiesWithContext:(NSManagedObjectContext *)context
{
NSError *error = nil;
NSUInteger count = [context countForFetchRequest:[self createFetchRequestInContext:context] error:&error];
[self handleErrors:error];
return [NSNumber numberWithUnsignedInteger:count];
}
+ (NSNumber *)numberOfEntities
{
return [self numberOfEntitiesWithContext:[self currentContext]];
}
+ (NSNumber *)numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSError *error = nil;
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:searchTerm];
NSUInteger count = [context countForFetchRequest:request error:&error];
[self handleErrors:error];
return [NSNumber numberWithUnsignedInteger:count];
}
+ (NSNumber *)numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm;
{
return [self numberOfEntitiesWithPredicate:searchTerm
inContext:[self currentContext]];
}
+ (BOOL)hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context
{
return [[self numberOfEntitiesWithContext:context] intValue] > 0;
}
+ (BOOL)hasAtLeastOneEntity
{
return [self hasAtLeastOneEntityInContext:[self currentContext]];
}
#pragma mark –
#pragma mark Reqest Helpers
+ (NSFetchRequest *)requestAll
{
return [self createFetchRequestInContext:[self currentContext]];
}
+ (NSFetchRequest *)requestAllInContext:(NSManagedObjectContext *)context
{
return [self createFetchRequestInContext:context];
}
+ (NSFetchRequest *)requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:[NSPredicate predicateWithFormat:@”%K = %@”, property, value]];
return request;
}
+ (NSFetchRequest *)requestAllWhere:(NSString *)property isEqualTo:(id)value
{
return [self requestAllWhere:property isEqualTo:value inContext:[self currentContext]];
}
+ (NSFetchRequest *)requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:searchTerm];
[request setFetchLimit:1];
return request;
}
+ (NSFetchRequest *)requestFirstWithPredicate:(NSPredicate *)searchTerm
{
return [self requestFirstWithPredicate:searchTerm inContext:[self currentContext]];
}
+ (NSFetchRequest *)requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context;
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:[NSPredicate predicateWithFormat:@”%K = %@”, attribute, searchValue]];
return request;
}
+ (NSFetchRequest *)requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue;
{
return [self requestFirstByAttribute:attribute withValue:searchValue inContext:[self currentContext]];
}
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestAllInContext:context];
NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:sortTerm ascending:ascending];
[request setSortDescriptors:[NSArray arrayWithObject:sortBy]];
[sortBy release];
return request;
}
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending
{
return [self requestAllSortedBy:sortTerm
ascending:ascending
inContext:[self currentContext]];
}
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestAllInContext:context];
[request setPredicate:searchTerm];
[request setIncludesSubentities:NO];
[request setFetchBatchSize:[self defaultBatchSize]];
if (sortTerm != nil){
NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:sortTerm ascending:ascending];
[request setSortDescriptors:[NSArray arrayWithObject:sortBy]];
[sortBy release];
}
return request;
}
+ (NSFetchRequest *)requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm;
{
NSFetchRequest *request = [self requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:[self currentContext]];
return request;
}
#pragma mark Finding Data
#pragma mark –
+ (NSArray *)findAllInContext:(NSManagedObjectContext *)context
{
return [self executeFetchRequest:[self requestAllInContext:context] inContext:context];
}
+ (NSArray *)findAll
{
return [self findAllInContext:[self currentContext]];
}
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestAllSortedBy:sortTerm ascending:ascending inContext:context];
return [self executeFetchRequest:request inContext:context];
}
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending
{
return [self findAllSortedBy:sortTerm
ascending:ascending
inContext:[self currentContext]];
}
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:context];
return [self executeFetchRequest:request inContext:context];
}
+ (NSArray *)findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm
{
return [self findAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:[self currentContext]];
}
#pragma mark –
#pragma mark NSFetchedResultsController helpers
#if TARGET_OS_IPHONE
+ (NSFetchedResultsController *)fetchRequestAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSString *cacheName = nil;
#ifdef STORE_USE_CACHE
cacheName = [NSString stringWithFormat:@”ActiveRecord-Cache-%@”, NSStringFromClass(self)];
#endif
NSFetchRequest *request = [self requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:context];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:group
cacheName:cacheName];
return [controller autorelease];
}
+ (NSFetchedResultsController *)fetchRequestAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending
{
return [self fetchRequestAllGroupedBy:group
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
inContext:[self currentContext]];
}
+ (NSFetchedResultsController *)fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context
{
NSFetchedResultsController *controller = [self fetchRequestAllGroupedBy:groupingKeyPath
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
inContext:context];
[self performFetch:controller];
return controller;
}
+ (NSFetchedResultsController *)fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath
{
return [self fetchAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
groupBy:groupingKeyPath
inContext:[self currentContext]];
}
+ (NSFetchedResultsController *)fetchRequest:(NSFetchRequest *)request groupedBy:(NSString *)group inContext:(NSManagedObjectContext *)context
{
NSString *cacheName = nil;
#ifdef STORE_USE_CACHE
cacheName = [NSString stringWithFormat:@”ActiveRecord-Cache-%@”, NSStringFromClass([self class])];
#endif
NSFetchedResultsController *controller =
[[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:group
cacheName:cacheName];
[self performFetch:controller];
return [controller autorelease];
}
+ (NSFetchedResultsController *)fetchRequest:(NSFetchRequest *)request groupedBy:(NSString *)group
{
return [self fetchRequest:request
groupedBy:group
inContext:[self currentContext]];
}
#endif
#pragma mark –
+ (NSArray *)findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:searchTerm];
return [self executeFetchRequest:request
inContext:context];
}
+ (NSArray *)findAllWithPredicate:(NSPredicate *)searchTerm
{
return [self findAllWithPredicate:searchTerm
inContext:[self currentContext]];
}
+ (id)findFirstInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirst
{
return [self findFirstInContext:[self currentContext]];
}
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestFirstByAttribute:attribute withValue:searchValue inContext:context];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue
{
return [self findFirstByAttribute:attribute
withValue:searchValue
inContext:[self currentContext]];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestFirstWithPredicate:searchTerm];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm
{
return [self findFirstWithPredicate:searchTerm inContext:[self currentContext]];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestAllSortedBy:property ascending:ascending withPredicate:searchterm inContext:context];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending
{
return [self findFirstWithPredicate:searchterm
sortedBy:property
ascending:ascending
inContext:[self currentContext]];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:searchTerm];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes
{
return [self findFirstWithPredicate:searchTerm
andRetrieveAttributes:attributes
inContext:[self currentContext]];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, …
{
NSFetchRequest *request = [self requestAllSortedBy:sortBy
ascending:ascending
withPredicate:searchTerm
inContext:context];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, …
{
return [self findFirstWithPredicate:searchTerm
sortedBy:sortBy
ascending:ascending
inContext:[self currentContext]
andRetrieveAttributes:attributes];
}
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self createFetchRequestInContext:context];
[request setPredicate:[NSPredicate predicateWithFormat:@”%K = %@”, attribute, searchValue]];
return [self executeFetchRequest:request inContext:context];
}
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue
{
return [self findByAttribute:attribute
withValue:searchValue
inContext:[self currentContext]];
}
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context
{
NSPredicate *searchTerm = [NSPredicate predicateWithFormat:@”%K = %@”, attribute, searchValue];
NSFetchRequest *request = [self requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context];
return [self executeFetchRequest:request];
}
+ (NSArray *)findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending
{
return [self findByAttribute:attribute
withValue:searchValue
andOrderBy:sortTerm
ascending:ascending
inContext:[self currentContext]];
}
+ (id)createInContext:(NSManagedObjectContext *)context
{
NSString *entityName = NSStringFromClass([self class]);
return [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
}
+ (id)createEntity
{
NSManagedObject *newEntity = [self createInContext:[self currentContext]];
return newEntity;
}
– (BOOL)deleteInContext:(NSManagedObjectContext *)context
{
[context deleteObject:self];
return YES;
}
– (BOOL)deleteEntity
{
[self deleteInContext:[[self class] currentContext]];
return YES;
}
+ (BOOL)truncateAllInContext:(NSManagedObjectContext *)context
{
NSArray *allEntities = [self findAllInContext:context];
for (NSManagedObject *obj in allEntities)
{
[obj deleteInContext:context];
}
return YES;
}
+ (BOOL)truncateAll
{
[self truncateAllInContext:[self currentContext]];
return YES;
}
+ (NSNumber *)maxValueFor:(NSString *)property
{
NSManagedObject *obj = [[self class] findFirstByAttribute:property
withValue:[NSString stringWithFormat:@”max(%@)”, property]];
return [obj valueForKey:property];
}
+ (id)objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [[self class] createFetchRequestInContext:context];
NSPredicate *searchFor = [NSPredicate predicateWithFormat:@”SELF = %@ AND %K = min(%@)”, self, property, property];
[request setPredicate:searchFor];
return [[self class] executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (id)objectWithMinValueFor:(NSString *)property
{
return [[self class] objectWithMinValueFor:property inContext:[self currentContext]];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObject+ActiveRecord.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObject+RKAdditions.h
//
// NSManagedObject+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 3/14/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@class RKManagedObjectStore, RKManagedObjectMapping;
/**
Provides extensions to NSManagedObject for various common tasks.
*/
@interface NSManagedObject (RKAdditions)
/**
The receiver’s managed object store.
*/
– (RKManagedObjectStore *)managedObjectStore;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObject+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObject+RKAdditions.m
//
// NSManagedObject+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 3/14/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “NSManagedObject+RKAdditions.h”
#import “NSManagedObjectContext+RKAdditions.h”
@implementation NSManagedObject (RKAdditions)
– (RKManagedObjectStore *)managedObjectStore
{
return self.managedObjectContext.managedObjectStore;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObject+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObjectContext+RKAdditions.h
//
// NSManagedObjectContext+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 3/14/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@class RKManagedObjectStore;
/**
Provides extensions to NSManagedObjectContext for various common tasks.
*/
@interface NSManagedObjectContext (RKAdditions)
/**
The receiver’s managed object store.
*/
@property (nonatomic, assign) RKManagedObjectStore *managedObjectStore;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObjectContext+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/NSManagedObjectContext+RKAdditions.m
//
// NSManagedObjectContext+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 3/14/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import “NSManagedObjectContext+RKAdditions.h”
static char NSManagedObject_RKManagedObjectStoreAssociatedKey;
@implementation NSManagedObjectContext (RKAdditions)
– (RKManagedObjectStore *)managedObjectStore
{
return (RKManagedObjectStore *) objc_getAssociatedObject(self, &NSManagedObject_RKManagedObjectStoreAssociatedKey);
}
– (void)setManagedObjectStore:(RKManagedObjectStore *)managedObjectStore
{
objc_setAssociatedObject(self, &NSManagedObject_RKManagedObjectStoreAssociatedKey, managedObjectStore, OBJC_ASSOCIATION_ASSIGN);
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._NSManagedObjectContext+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKEntityByAttributeCache.h
//
// RKEntityByAttributeCache.h
// RestKit
//
// Created by Blake Watters on 5/1/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import
/**
Instances of RKEntityByAttributeCache provide an in-memory caching mechanism
for managed objects instances of an entity in a managed object context with
the value of one of the object’s attributes acting as the cache key. When loaded,
the cache will retrieve all instances of an entity from the store and build a
dictionary mapping values for the given cache key attribute to the managed object
ID for all objects matching the value. The cache can then be used to quickly retrieve
objects by attribute value for the cache key without executing another fetch request
against the managed object context. This can provide a large performance improvement
when a large number of objects are being retrieved using a particular attribute as
the key.
RKEntityByAttributeCache instances are used by the RKEntityCache to provide
caching for multiple entities at once.
@see RKEntityCache
*/
@interface RKEntityByAttributeCache : NSObject
///—————————————————————————–
/// @name Creating a Cache
///—————————————————————————–
/**
Initializes the receiver with a given entity, attribute, and managed object context.
@param entity The Core Data entity description for the managed objects being cached.
@param attributeName The name of an attribute within the cached entity that acts as the cache key.
@param managedObjectContext The managed object context the cache retrieves the cached
objects from
@return The receiver, initialized with the given entity, attribute, and managed object
context.
*/
– (id)initWithEntity:(NSEntityDescription *)entity attribute:(NSString *)attributeName managedObjectContext:(NSManagedObjectContext *)context;
///—————————————————————————–
/// @name Getting Cache Identity
///—————————————————————————–
/**
The Core Data entity description for the managed objects being cached.
*/
@property (nonatomic, readonly) NSEntityDescription *entity;
/**
An attribute that is part of the cached entity that acts as the cache key.
*/
@property (nonatomic, readonly) NSString *attribute;
/**
The managed object context the receiver fetches cached objects from.
*/
@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext;
/**
A Boolean value determining if the receiever monitors the managed object context
for changes and updates the cache entries using the notifications emitted.
*/
@property (nonatomic, assign) BOOL monitorsContextForChanges;
///—————————————————————————–
/// @name Loading and Flushing the Cache
///—————————————————————————–
/**
Loads the cache by finding all instances of the configured entity and building
an association between the value of the cached attribute’s value and the
managed object ID for the object.
*/
– (void)load;
/**
Flushes the cache by releasing all cache attribute value to managed object ID
associations.
*/
– (void)flush;
///—————————————————————————–
/// @name Inspecting Cache State
///—————————————————————————–
/**
A Boolean value indicating if the cache has loaded associations between cache
attribute values and managed object ID’s.
*/
– (BOOL)isLoaded;
/**
Returns a count of the total number of cached objects.
*/
– (NSUInteger)count;
/**
Returns the total number of cached objects with a given value for
the attribute acting as the cache key.
@param attributeValue The value for the cache key attribute to retrieve
a count of the objects with a matching value.
@return The number of objects in the cache with the given value for the cache
attribute of the receiver.
*/
– (NSUInteger)countWithAttributeValue:(id)attributeValue;
/**
Returns the number of unique attribute values contained within the receiver.
@return The number of unique attribute values within the receiver.
*/
– (NSUInteger)countOfAttributeValues;
/**
Returns a Boolean value that indicates whether a given object is present
in the cache.
@param object An object.
@return YES if object is present in the cache, otherwise NO.
*/
– (BOOL)containsObject:(NSManagedObject *)object;
/**
Returns a Boolean value that indicates whether one of more objects is present
in the cache with a given value of the cache key attribute.
@param attributeValue The value with which to check the cache for objects with
a matching value.
@return YES if one or more objects with the given value for the cache key
attribute is present in the cache, otherwise NO.
*/
– (BOOL)containsObjectWithAttributeValue:(id)attributeValue;
/**
Returns the first object with a matching value for the cache key attribute.
@param attributeValue A value for the cache key attribute.
@return An object with the value of attribute matching attributeValue or nil.
*/
– (NSManagedObject *)objectWithAttributeValue:(id)attributeValue;
/**
Returns the collection of objects with a matching value for the cache key attribute.
@param attributeValue A value for the cache key attribute.
@return An array of objects with the value of attribute matching attributeValue or
an empty array.
*/
– (NSArray *)objectsWithAttributeValue:(id)attributeValue;
///—————————————————————————–
/// @name Managing Cached Objects
///—————————————————————————–
/**
Adds a managed object to the cache.
The object must be an instance of the cached entity.
@param object The managed object to add to the cache.
*/
– (void)addObject:(NSManagedObject *)object;
/**
Removes a managed object from the cache.
The object must be an instance of the cached entity.
@param object The managed object to remove from the cache.
*/
– (void)removeObject:(NSManagedObject *)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKEntityByAttributeCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKEntityByAttributeCache.m
//
// RKEntityByAttributeCache.m
// RestKit
//
// Created by Blake Watters on 5/1/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#if TARGET_OS_IPHONE
#import
#endif
#import “RKEntityByAttributeCache.h”
#import “RKLog.h”
#import “RKObjectPropertyInspector.h”
#import “RKObjectPropertyInspector+CoreData.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreDataCache
@interface RKEntityByAttributeCache ()
@property (nonatomic, retain) NSMutableDictionary *attributeValuesToObjectIDs;
@end
@implementation RKEntityByAttributeCache
@synthesize entity = _entity;
@synthesize attribute = _attribute;
@synthesize managedObjectContext = _managedObjectContext;
@synthesize attributeValuesToObjectIDs = _attributeValuesToObjectIDs;
@synthesize monitorsContextForChanges = _monitorsContextForChanges;
– (id)initWithEntity:(NSEntityDescription *)entity attribute:(NSString *)attributeName managedObjectContext:(NSManagedObjectContext *)context
{
self = [self init];
if (self) {
_entity = [entity retain];
_attribute = [attributeName retain];
_managedObjectContext = [context retain];
_monitorsContextForChanges = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:context];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:context];
#if TARGET_OS_IPHONE
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveMemoryWarning:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
#endif
}
return self;
}
– (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_entity release];
[_attribute release];
[_managedObjectContext release];
[_attributeValuesToObjectIDs release];
[super dealloc];
}
– (NSUInteger)count
{
return [[[self.attributeValuesToObjectIDs allValues] valueForKeyPath:@”@sum.@count”] integerValue];
}
– (NSUInteger)countOfAttributeValues
{
return [self.attributeValuesToObjectIDs count];
}
– (NSUInteger)countWithAttributeValue:(id)attributeValue
{
return [[self objectsWithAttributeValue:attributeValue] count];
}
– (BOOL)shouldCoerceAttributeToString:(NSString *)attributeValue
{
if ([attributeValue isKindOfClass:[NSString class]] || [attributeValue isEqual:[NSNull null]]) {
return NO;
}
Class attributeType = [[RKObjectPropertyInspector sharedInspector] typeForProperty:self.attribute ofEntity:self.entity];
return [attributeType instancesRespondToSelector:@selector(stringValue)];
}
– (void)load
{
RKLogDebug(@”Loading entity cache for Entity ‘%@’ by attribute ‘%@'”, self.entity.name, self.attribute);
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:self.entity];
[fetchRequest setResultType:NSManagedObjectIDResultType];
NSError *error = nil;
NSArray *objectIDs = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
if (error) {
RKLogError(@”Failed to load entity cache: %@”, error);
return;
}
self.attributeValuesToObjectIDs = [NSMutableDictionary dictionaryWithCapacity:[objectIDs count]];
for (NSManagedObjectID *objectID in objectIDs) {
NSError *error = nil;
NSManagedObject *object = [self.managedObjectContext existingObjectWithID:objectID error:&error];
if (! object && error) {
RKLogError(@”Failed to retrieve managed object with ID %@: %@”, objectID, error);
}
[self addObject:object];
}
}
– (void)flush
{
RKLogDebug(@”Flushing entity cache for Entity ‘%@’ by attribute ‘%@'”, self.entity.name, self.attribute);
self.attributeValuesToObjectIDs = nil;
}
– (void)reload
{
[self flush];
[self load];
}
– (BOOL)isLoaded
{
return (self.attributeValuesToObjectIDs != nil);
}
– (NSManagedObject *)objectWithAttributeValue:(id)attributeValue
{
NSArray *objects = [self objectsWithAttributeValue:attributeValue];
return ([objects count] > 0) ? [objects objectAtIndex:0] : nil;
}
– (NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID {
/*
NOTE:
We use existingObjectWithID: as opposed to objectWithID: as objectWithID: can return us a fault
that will raise an exception when fired. existingObjectWithID:error: will return nil if the ID has been
deleted. objectRegisteredForID: is also an acceptable approach.
*/
NSError *error = nil;
NSManagedObject *object = [self.managedObjectContext existingObjectWithID:objectID error:&error];
if (! object && error) {
RKLogError(@”Failed to retrieve managed object with ID %@. Error %@\n%@”, objectID, [error localizedDescription], [error userInfo]);
return nil;
}
return object;
}
– (NSArray *)objectsWithAttributeValue:(id)attributeValue
{
attributeValue = [self shouldCoerceAttributeToString:attributeValue] ? [attributeValue stringValue] : attributeValue;
NSMutableArray *objectIDs = [self.attributeValuesToObjectIDs objectForKey:attributeValue];
if (objectIDs) {
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:[objectIDs count]];
for (NSManagedObjectID *objectID in objectIDs) {
NSManagedObject *object = [self objectWithID:objectID];
if (object) [objects addObject:object];
}
return objects;
}
return [NSArray array];
}
– (void)addObject:(NSManagedObject *)object
{
NSAssert([object.entity isEqual:self.entity], @”Cannot add object with entity ‘%@’ to cache with entity of ‘%@'”, [[object entity] name], [self.entity name]);
id attributeValue = [object valueForKey:self.attribute];
// Coerce to a string if possible
attributeValue = [self shouldCoerceAttributeToString:attributeValue] ? [attributeValue stringValue] : attributeValue;
if (attributeValue) {
NSManagedObjectID *objectID = [object objectID];
NSMutableArray *objectIDs = [self.attributeValuesToObjectIDs objectForKey:attributeValue];
if (objectIDs) {
if (! [objectIDs containsObject:objectID]) {
[objectIDs addObject:objectID];
}
} else {
objectIDs = [NSMutableArray arrayWithObject:objectID];
}
if (nil == self.attributeValuesToObjectIDs) self.attributeValuesToObjectIDs = [NSMutableDictionary dictionary];
[self.attributeValuesToObjectIDs setValue:objectIDs forKey:attributeValue];
} else {
RKLogWarning(@”Unable to add object with nil value for attribute ‘%@’: %@”, self.attribute, object);
}
}
– (void)removeObject:(NSManagedObject *)object
{
NSAssert([object.entity isEqual:self.entity], @”Cannot remove object with entity ‘%@’ from cache with entity of ‘%@'”, [[object entity] name], [self.entity name]);
id attributeValue = [object valueForKey:self.attribute];
// Coerce to a string if possible
attributeValue = [self shouldCoerceAttributeToString:attributeValue] ? [attributeValue stringValue] : attributeValue;
if (attributeValue) {
NSManagedObjectID *objectID = [object objectID];
NSMutableArray *objectIDs = [self.attributeValuesToObjectIDs objectForKey:attributeValue];
if (objectIDs && [objectIDs containsObject:objectID]) {
[objectIDs removeObject:objectID];
}
} else {
RKLogWarning(@”Unable to remove object with nil value for attribute ‘%@’: %@”, self.attribute, object);
}
}
– (BOOL)containsObjectWithAttributeValue:(id)attributeValue
{
// Coerce to a string if possible
attributeValue = [self shouldCoerceAttributeToString:attributeValue] ? [attributeValue stringValue] : attributeValue;
return [[self objectsWithAttributeValue:attributeValue] count] > 0;
}
– (BOOL)containsObject:(NSManagedObject *)object
{
if (! [object.entity isEqual:self.entity]) return NO;
id attributeValue = [object valueForKey:self.attribute];
// Coerce to a string if possible
attributeValue = [self shouldCoerceAttributeToString:attributeValue] ? [attributeValue stringValue] : attributeValue;
return [[self objectsWithAttributeValue:attributeValue] containsObject:object];
}
– (void)managedObjectContextDidChange:(NSNotification *)notification
{
if (self.monitorsContextForChanges == NO) return;
NSDictionary *userInfo = notification.userInfo;
NSSet *insertedObjects = [userInfo objectForKey:NSInsertedObjectsKey];
NSSet *updatedObjects = [userInfo objectForKey:NSUpdatedObjectsKey];
NSSet *deletedObjects = [userInfo objectForKey:NSDeletedObjectsKey];
RKLogTrace(@”insertedObjects=%@, updatedObjects=%@, deletedObjects=%@”, insertedObjects, updatedObjects, deletedObjects);
NSMutableSet *objectsToAdd = [NSMutableSet setWithSet:insertedObjects];
[objectsToAdd unionSet:updatedObjects];
for (NSManagedObject *object in objectsToAdd) {
if ([object.entity isEqual:self.entity]) {
[self addObject:object];
}
}
for (NSManagedObject *object in deletedObjects) {
if ([object.entity isEqual:self.entity]) {
[self removeObject:object];
}
}
}
– (void)managedObjectContextDidSave:(NSNotification *)notification
{
// After the MOC has been saved, we flush to ensure any temporary
// objectID references are converted into permanent ID’s on the next load.
[self flush];
}
– (void)didReceiveMemoryWarning:(NSNotification *)notification
{
[self flush];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKEntityByAttributeCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKEntityCache.h
//
// RKEntityCache.h
// RestKit
//
// Created by Blake Watters on 5/2/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import
@class RKEntityByAttributeCache;
/**
Instances of RKInMemoryEntityCache provide an in-memory caching mechanism for
objects in a Core Data managed object context. Managed objects can be cached by
attribute for fast retrieval without repeatedly hitting the Core Data persistent store.
This can provide a substantial speed advantage over issuing fetch requests
in cases where repeated look-ups of the same data are performed using a small set
of attributes as the query key. Internally, the cache entries are maintained as
references to the NSManagedObjectID of corresponding cached objects.
*/
@interface RKEntityCache : NSObject
///—————————————————————————–
/// @name Initializing the Cache
///—————————————————————————–
/**
Initializes the receiver with a managed object context containing the entity instances to be cached.
@param context The managed object context containing objects to be cached.
@returns self, initialized with context.
*/
– (id)initWithManagedObjectContext:(NSManagedObjectContext *)context;
/**
The managed object context with which the receiver is associated.
*/
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
///—————————————————————————–
/// @name Caching Objects by Attribute
///—————————————————————————–
/**
Caches all instances of an entity using the value for an attribute as the cache key.
@param entity The entity to cache all instances of.
@param attributeName The attribute to cache the instances by.
*/
– (void)cacheObjectsForEntity:(NSEntityDescription *)entity byAttribute:(NSString *)attributeName;
/**
Returns a Boolean value indicating if all instances of an entity have been cached by a given attribute name.
@param entity The entity to check the cache status of.
@param attributeName The attribute to check the cache status with.
@return YES if the cache has been loaded with instances with the given attribute, else NO.
*/
– (BOOL)isEntity:(NSEntityDescription *)entity cachedByAttribute:(NSString *)attributeName;
/**
Retrieves the first cached instance of a given entity where the specified attribute matches the given value.
@param entity The entity to search the cache for instances of.
@param attributeName The attribute to search the cache for matches with.
@param attributeValue The value of the attribute to return a match for.
@return A matching managed object instance or nil.
@raise NSInvalidArgumentException Raised if instances of the entity and attribute have not been cached.
*/
– (NSManagedObject *)objectForEntity:(NSEntityDescription *)entity withAttribute:(NSString *)attributeName value:(id)attributeValue;
/**
Retrieves all cached instances of a given entity where the specified attribute matches the given value.
@param entity The entity to search the cache for instances of.
@param attributeName The attribute to search the cache for matches with.
@param attributeValue The value of the attribute to return a match for.
@return All matching managed object instances or nil.
@raise NSInvalidArgumentException Raised if instances of the entity and attribute have not been cached.
*/
– (NSArray *)objectsForEntity:(NSEntityDescription *)entity withAttribute:(NSString *)attributeName value:(id)attributeValue;
///—————————————————————————–
// @name Accessing Underlying Caches
///—————————————————————————–
/**
Retrieves the underlying entity attribute cache for a given entity and attribute.
@param entity The entity to retrieve the entity attribute cache object for.
@param attributeName The attribute to retrieve the entity attribute cache object for.
@return The entity attribute cache for the given entity and attribute, or nil if none was found.
*/
– (RKEntityByAttributeCache *)attributeCacheForEntity:(NSEntityDescription *)entity attribute:(NSString *)attributeName;
/**
Retrieves all entity attributes caches for a given entity.
@param entity The entity to retrieve the collection of entity attribute caches for.
@return An array of entity attribute cache objects for the given entity or an empty array if none were found.
*/
– (NSArray *)attributeCachesForEntity:(NSEntityDescription *)entity;
///—————————————————————————–
// @name Managing the Cache
///—————————————————————————–
/**
Flushes the entity cache by sending a flush message to each entity attribute cache
contained within the receiver.
@see [RKEntityByAttributeCache flush]
*/
– (void)flush;
/**
Adds a given object to all entity attribute caches for the object’s entity contained
within the receiver.
@param object The object to add to the appropriate entity attribute caches.
*/
– (void)addObject:(NSManagedObject *)object;
/**
Removed a given object from all entity attribute caches for the object’s entity contained
within the receiver.
@param object The object to remove from the appropriate entity attribute caches.
*/
– (void)removeObject:(NSManagedObject *)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKEntityCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKEntityCache.m
//
// RKEntityCache.m
// RestKit
//
// Created by Blake Watters on 5/2/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import “RKEntityCache.h”
#import “RKEntityByAttributeCache.h”
@interface RKEntityCache ()
@property (nonatomic, retain) NSMutableSet *attributeCaches;
@end
@implementation RKEntityCache
@synthesize managedObjectContext = _managedObjectContext;
@synthesize attributeCaches = _attributeCaches;
– (id)initWithManagedObjectContext:(NSManagedObjectContext *)context
{
NSAssert(context, @”Cannot initialize entity cache with a nil context”);
self = [super init];
if (self) {
_managedObjectContext = [context retain];
_attributeCaches = [[NSMutableSet alloc] init];
}
return self;
}
– (id)init
{
return [self initWithManagedObjectContext:nil];
}
– (void)dealloc
{
[_managedObjectContext release];
[_attributeCaches release];
[super dealloc];
}
– (void)cacheObjectsForEntity:(NSEntityDescription *)entity byAttribute:(NSString *)attributeName
{
NSAssert(entity, @”Cannot cache objects for a nil entity”);
NSAssert(attributeName, @”Cannot cache objects without an attribute”);
RKEntityByAttributeCache *attributeCache = [self attributeCacheForEntity:entity attribute:attributeName];
if (attributeCache && !attributeCache.isLoaded) {
[attributeCache load];
} else {
attributeCache = [[RKEntityByAttributeCache alloc] initWithEntity:entity attribute:attributeName managedObjectContext:self.managedObjectContext];
[attributeCache load];
[self.attributeCaches addObject:attributeCache];
[attributeCache release];
}
}
– (BOOL)isEntity:(NSEntityDescription *)entity cachedByAttribute:(NSString *)attributeName
{
NSAssert(entity, @”Cannot check cache status for a nil entity”);
NSAssert(attributeName, @”Cannot check cache status for a nil attribute”);
RKEntityByAttributeCache *attributeCache = [self attributeCacheForEntity:entity attribute:attributeName];
return (attributeCache && attributeCache.isLoaded);
}
– (NSManagedObject *)objectForEntity:(NSEntityDescription *)entity withAttribute:(NSString *)attributeName value:(id)attributeValue
{
NSAssert(entity, @”Cannot retrieve cached objects with a nil entity”);
NSAssert(attributeName, @”Cannot retrieve cached objects by a nil entity”);
RKEntityByAttributeCache *attributeCache = [self attributeCacheForEntity:entity attribute:attributeName];
if (attributeCache) {
return [attributeCache objectWithAttributeValue:attributeValue];
}
return nil;
}
– (NSArray *)objectsForEntity:(NSEntityDescription *)entity withAttribute:(NSString *)attributeName value:(id)attributeValue
{
NSAssert(entity, @”Cannot retrieve cached objects with a nil entity”);
NSAssert(attributeName, @”Cannot retrieve cached objects by a nil entity”);
RKEntityByAttributeCache *attributeCache = [self attributeCacheForEntity:entity attribute:attributeName];
if (attributeCache) {
return [attributeCache objectsWithAttributeValue:attributeValue];
}
return [NSSet set];
}
– (RKEntityByAttributeCache *)attributeCacheForEntity:(NSEntityDescription *)entity attribute:(NSString *)attributeName
{
NSAssert(entity, @”Cannot retrieve attribute cache for a nil entity”);
NSAssert(attributeName, @”Cannot retrieve attribute cache for a nil attribute”);
for (RKEntityByAttributeCache *cache in self.attributeCaches) {
if ([cache.entity isEqual:entity] && [cache.attribute isEqualToString:attributeName]) {
return cache;
}
}
return nil;
}
– (NSSet *)attributeCachesForEntity:(NSEntityDescription *)entity
{
NSAssert(entity, @”Cannot retrieve attribute caches for a nil entity”);
NSMutableSet *set = [NSMutableSet set];
for (RKEntityByAttributeCache *cache in self.attributeCaches) {
if ([cache.entity isEqual:entity]) {
[set addObject:cache];
}
}
return [NSSet setWithSet:set];
}
– (void)flush
{
[self.attributeCaches makeObjectsPerformSelector:@selector(flush)];
}
– (void)addObject:(NSManagedObject *)object
{
NSAssert(object, @”Cannot add a nil object to the cache”);
NSArray *attributeCaches = [self attributeCachesForEntity:object.entity];
for (RKEntityByAttributeCache *cache in attributeCaches) {
[cache addObject:object];
}
}
– (void)removeObject:(NSManagedObject *)object
{
NSAssert(object, @”Cannot remove a nil object from the cache”);
NSArray *attributeCaches = [self attributeCachesForEntity:object.entity];
for (RKEntityByAttributeCache *cache in attributeCaches) {
[cache removeObject:object];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKEntityCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKFetchRequestManagedObjectCache.h
//
// RKFetchRequestManagedObjectCache.h
// RestKit
//
// Created by Jeff Arena on 1/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKManagedObjectCaching.h”
/**
Provides a simple managed object cache strategy in which every request for an object
is satisfied by dispatching an NSFetchRequest against the Core Data persistent store.
Performance can be disappointing for data sets with a large amount of redundant data
being mapped and connected together, but the memory footprint stays flat.
*/
@interface RKFetchRequestManagedObjectCache : NSObject
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKFetchRequestManagedObjectCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKFetchRequestManagedObjectCache.m
//
// RKFetchRequestMappingCache.m
// RestKit
//
// Created by Jeff Arena on 1/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKFetchRequestManagedObjectCache.h”
#import “NSManagedObject+ActiveRecord.h”
#import “NSEntityDescription+RKAdditions.h”
#import “RKLog.h”
#import “RKObjectPropertyInspector.h”
#import “RKObjectPropertyInspector+CoreData.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKFetchRequestManagedObjectCache
– (NSManagedObject *)findInstanceOfEntity:(NSEntityDescription *)entity
withPrimaryKeyAttribute:(NSString *)primaryKeyAttribute
value:(id)primaryKeyValue
inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
{
NSAssert(entity, @”Cannot find existing managed object without a target class”);
NSAssert(primaryKeyAttribute, @”Cannot find existing managed object instance without mapping that defines a primaryKeyAttribute”);
NSAssert(primaryKeyValue, @”Cannot find existing managed object by primary key without a value”);
NSAssert(managedObjectContext, @”Cannot find existing managed object with a context”);
id searchValue = primaryKeyValue;
Class type = [[RKObjectPropertyInspector sharedInspector] typeForProperty:primaryKeyAttribute ofEntity:entity];
if (type && ([type isSubclassOfClass:[NSString class]] && NO == [primaryKeyValue isKindOfClass:[NSString class]])) {
searchValue = [NSString stringWithFormat:@”%@”, primaryKeyValue];
} else if (type && ([type isSubclassOfClass:[NSNumber class]] && NO == [primaryKeyValue isKindOfClass:[NSNumber class]])) {
if ([primaryKeyValue isKindOfClass:[NSString class]]) {
searchValue = [NSNumber numberWithDouble:[(NSString *)primaryKeyValue doubleValue]];
}
}
// Use cached predicate if primary key matches
NSPredicate *predicate = nil;
if ([entity.primaryKeyAttributeName isEqualToString:primaryKeyAttribute]) {
predicate = [entity predicateForPrimaryKeyAttributeWithValue:searchValue];
} else {
// Parse a predicate
predicate = [NSPredicate predicateWithFormat:@”%K = %@”, primaryKeyAttribute, searchValue];
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = entity;
fetchRequest.fetchLimit = 1;
fetchRequest.predicate = predicate;
NSArray *objects = [NSManagedObject executeFetchRequest:fetchRequest inContext:managedObjectContext];
RKLogDebug(@”Found objects ‘%@’ using fetchRequest ‘%@'”, objects, fetchRequest);
[fetchRequest release];
NSManagedObject *object = nil;
if ([objects count] > 0) {
object = [objects objectAtIndex:0];
}
return object;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKFetchRequestManagedObjectCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKInMemoryManagedObjectCache.h
//
// RKInMemoryManagedObjectCache.h
// RestKit
//
// Created by Jeff Arena on 1/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKManagedObjectCaching.h”
/**
Provides a fast managed object cache where-in object instances are retained in
memory to avoid hitting the Core Data persistent store. Performance is greatly
increased over fetch request based strategy at the expense of memory consumption.
*/
@interface RKInMemoryManagedObjectCache : NSObject
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKInMemoryManagedObjectCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKInMemoryManagedObjectCache.m
//
// RKInMemoryManagedObjectCache.m
// RestKit
//
// Created by Jeff Arena on 1/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKInMemoryManagedObjectCache.h”
#import “NSEntityDescription+RKAdditions.h”
#import “RKEntityCache.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
static NSString * const RKInMemoryObjectManagedObjectCacheThreadDictionaryKey = @”RKInMemoryObjectManagedObjectCacheThreadDictionaryKey”;
@implementation RKInMemoryManagedObjectCache
– (RKEntityCache *)cacheForEntity:(NSEntityDescription *)entity inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
{
NSAssert(entity, @”Cannot find existing managed object without a target class”);
NSAssert(managedObjectContext, @”Cannot find existing managed object with a context”);
NSMutableDictionary *contextDictionary = [[[NSThread currentThread] threadDictionary] objectForKey:RKInMemoryObjectManagedObjectCacheThreadDictionaryKey];
if (! contextDictionary) {
contextDictionary = [NSMutableDictionary dictionaryWithCapacity:1];
[[[NSThread currentThread] threadDictionary] setObject:contextDictionary forKey:RKInMemoryObjectManagedObjectCacheThreadDictionaryKey];
}
NSNumber *hashNumber = [NSNumber numberWithUnsignedInteger:[managedObjectContext hash]];
RKEntityCache *entityCache = [contextDictionary objectForKey:hashNumber];
if (! entityCache) {
RKLogInfo(@”Creating thread-local entity cache for managed object context: %@”, managedObjectContext);
entityCache = [[RKEntityCache alloc] initWithManagedObjectContext:managedObjectContext];
[contextDictionary setObject:entityCache forKey:hashNumber];
[entityCache release];
}
return entityCache;
}
– (NSManagedObject *)findInstanceOfEntity:(NSEntityDescription *)entity
withPrimaryKeyAttribute:(NSString *)primaryKeyAttribute
value:(id)primaryKeyValue
inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
{
RKEntityCache *entityCache = [self cacheForEntity:entity inManagedObjectContext:managedObjectContext];
if (! [entityCache isEntity:entity cachedByAttribute:primaryKeyAttribute]) {
RKLogInfo(@”Caching instances of Entity ‘%@’ by primary key attribute ‘%@'”, entity.name, primaryKeyAttribute);
[entityCache cacheObjectsForEntity:entity byAttribute:primaryKeyAttribute];
RKEntityByAttributeCache *attributeCache = [entityCache attributeCacheForEntity:entity attribute:primaryKeyAttribute];
RKLogTrace(@”Cached %ld objects”, (long) [attributeCache count]);
}
return [entityCache objectForEntity:entity withAttribute:primaryKeyAttribute value:primaryKeyValue];
}
– (void)didFetchObject:(NSManagedObject *)object
{
RKEntityCache *entityCache = [self cacheForEntity:object.entity inManagedObjectContext:object.managedObjectContext];
[entityCache addObject:object];
}
– (void)didCreateObject:(NSManagedObject *)object
{
RKEntityCache *entityCache = [self cacheForEntity:object.entity inManagedObjectContext:object.managedObjectContext];
[entityCache addObject:object];
}
– (void)didDeleteObject:(NSManagedObject *)object
{
RKEntityCache *entityCache = [self cacheForEntity:object.entity inManagedObjectContext:object.managedObjectContext];
[entityCache removeObject:object];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKInMemoryManagedObjectCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectCaching.h
//
// RKManagedObjectCaching.h
// RestKit
//
// Created by Jeff Arena on 1/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
Objects implementing the RKManagedObjectCaching protocol can act as the cache
strategy for RestKit managed object stores. The managed object cache is consulted
when objects are retrieved from Core Data during object mapping operations and provide
an opportunity to accelerate the mapping process by trading memory for speed.
*/
@protocol RKManagedObjectCaching
@required
/**
Retrieves a model object from the object store given a Core Data entity and
the primary key attribute and value for the desired object.
@param entity The Core Data entity for the type of object to be retrieved from the cache.
@param primaryKeyAttribute The name of the attribute that acts as the primary key for the entity.
@param primaryKeyValue The value for the primary key attribute of the object to be retrieved from the cache.
@param mmanagedObjectContext The managed object context to be searched for a matching instance.
@return A managed object that is an instance of the given entity with a primary key and value matching
the specified parameters, or nil if no object was found.
*/
– (NSManagedObject *)findInstanceOfEntity:(NSEntityDescription *)entity
withPrimaryKeyAttribute:(NSString *)primaryKeyAttribute
value:(id)primaryKeyValue
inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;
@optional
/**
Tells the receiver that an object was fetched and should be added to the cache.
@param object The object that was fetched from a managed object context.
*/
– (void)didFetchObject:(NSManagedObject *)object;
/**
Tells the receiver that an object was created and should be added to the cache.
@param object The object that was created in a managed object context.
*/
– (void)didCreateObject:(NSManagedObject *)object;
/**
Tells the receiver that an object was deleted and should be removed to the cache.
@param object The object that was deleted from a managed object context.
*/
– (void)didDeleteObject:(NSManagedObject *)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectCaching.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectLoader.h
//
// RKManagedObjectLoader.h
// RestKit
//
// Created by Blake Watters on 2/13/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectLoader.h”
#import “RKManagedObjectStore.h”
/**
A subclass of the object loader that is dispatched when you
are loading Core Data managed objects. This differs from the
transient object loader only by handling the special threading
concerns imposed by Core Data.
*/
@interface RKManagedObjectLoader : RKObjectLoader {
RKManagedObjectStore *_objectStore;
NSManagedObjectID* _targetObjectID;
NSMutableSet* _managedObjectKeyPaths;
BOOL _deleteObjectOnFailure;
}
/**
A reference to a RestKit managed object store for interacting with Core Data
@see RKManagedObjectStore
*/
@property (nonatomic, retain) RKManagedObjectStore* objectStore;
+ (id)loaderWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore;
– (id)initWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectLoader.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectLoader.m
//
// RKManagedObjectLoader.m
// RestKit
//
// Created by Blake Watters on 2/13/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectManager.h”
#import “RKManagedObjectLoader.h”
#import “RKURL.h”
#import “RKObjectMapper.h”
#import “RKManagedObjectThreadSafeInvocation.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKObjectLoader_Internals.h”
#import “RKRequest_Internals.h”
#import “RKObjectMappingProvider+CoreData.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKManagedObjectLoader
@synthesize objectStore = _objectStore;
+ (id)loaderWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore {
return [[[self alloc] initWithURL:URL mappingProvider:mappingProvider objectStore:objectStore] autorelease];
}
– (id)initWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider objectStore:(RKManagedObjectStore *)objectStore {
self = [self initWithURL:URL mappingProvider:mappingProvider];
if (self) {
_objectStore = [objectStore retain];
}
return self;
}
– (id)initWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider {
self = [super initWithURL:URL mappingProvider:mappingProvider];
if (self) {
_managedObjectKeyPaths = [[NSMutableSet alloc] init];
}
return self;
}
– (void)dealloc {
[_targetObjectID release];
_targetObjectID = nil;
_deleteObjectOnFailure = NO;
[_managedObjectKeyPaths release];
[_objectStore release];
[super dealloc];
}
– (void)reset {
[super reset];
[_targetObjectID release];
_targetObjectID = nil;
}
#pragma mark – RKObjectMapperDelegate methods
– (void)objectMapper:(RKObjectMapper*)objectMapper didMapFromObject:(id)sourceObject toObject:(id)destinationObject atKeyPath:(NSString*)keyPath usingMapping:(RKObjectMapping*)objectMapping {
if ([destinationObject isKindOfClass:[NSManagedObject class]]) {
[_managedObjectKeyPaths addObject:keyPath];
}
}
#pragma mark – RKObjectLoader overrides
// Overload the target object reader to return a thread-local copy of the target object
– (id)targetObject {
if ([NSThread isMainThread] == NO && _targetObjectID) {
return [self.objectStore objectWithID:_targetObjectID];
}
return _targetObject;
}
– (void)setTargetObject:(NSObject*)targetObject {
[_targetObject release];
_targetObject = nil;
_targetObject = [targetObject retain];
[_targetObjectID release];
_targetObjectID = nil;
}
– (BOOL)prepareURLRequest {
// TODO: Can we just do this if the object hasn’t been saved already???
// NOTE: There is an important sequencing issue here. You MUST save the
// managed object context before retaining the objectID or you will run
// into an error where the object context cannot be saved. We do this
// right before send to avoid sequencing issues where the target object is
// set before the managed object store.
if (self.targetObject && [self.targetObject isKindOfClass:[NSManagedObject class]]) {
_deleteObjectOnFailure = [(NSManagedObject*)self.targetObject isNew];
[self.objectStore save:nil];
_targetObjectID = [[(NSManagedObject*)self.targetObject objectID] retain];
}
return [super prepareURLRequest];
}
– (NSArray *)cachedObjects {
NSFetchRequest *fetchRequest = [self.mappingProvider fetchRequestForResourcePath:self.resourcePath];
if (fetchRequest) {
return [NSManagedObject objectsWithFetchRequest:fetchRequest];
}
return nil;
}
– (void)deleteCachedObjectsMissingFromResult:(RKObjectMappingResult*)result {
if (! [self isGET]) {
RKLogDebug(@”Skipping cleanup of objects via managed object cache: only used for GET requests.”);
return;
}
if ([self.URL isKindOfClass:[RKURL class]]) {
NSArray *results = [result asCollection];
NSArray *cachedObjects = [self cachedObjects];
for (id object in cachedObjects) {
if (NO == [results containsObject:object]) {
RKLogTrace(@”Deleting orphaned object %@: not found in result set and expected at this resource path”, object);
[[self.objectStore managedObjectContextForCurrentThread] deleteObject:object];
}
}
} else {
RKLogWarning(@”Unable to perform cleanup of server-side object deletions: unable to determine resource path.”);
}
}
// NOTE: We are on the background thread here, be mindful of Core Data’s threading needs
– (void)processMappingResult:(RKObjectMappingResult*)result {
NSAssert(_sentSynchronously || ![NSThread isMainThread], @”Mapping result processing should occur on a background thread”);
if (_targetObjectID && self.targetObject && self.method == RKRequestMethodDELETE) {
NSManagedObject* backgroundThreadObject = [self.objectStore objectWithID:_targetObjectID];
RKLogInfo(@”Deleting local object %@ due to DELETE request”, backgroundThreadObject);
[[self.objectStore managedObjectContextForCurrentThread] deleteObject:backgroundThreadObject];
}
// If the response was successful, save the store…
if ([self.response isSuccessful]) {
[self deleteCachedObjectsMissingFromResult:result];
NSError *error = nil;
BOOL success = [self.objectStore save:&error];
if (! success) {
RKLogError(@”Failed to save managed object context after mapping completed: %@”, [error localizedDescription]);
NSMethodSignature* signature = [(NSObject *)self methodSignatureForSelector:@selector(informDelegateOfError:)];
RKManagedObjectThreadSafeInvocation* invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:@selector(informDelegateOfError:)];
[invocation setArgument:&error atIndex:2];
[invocation invokeOnMainThread];
dispatch_async(dispatch_get_main_queue(), ^{
[self finalizeLoad:success];
});
return;
}
}
NSDictionary* dictionary = [result asDictionary];
NSMethodSignature* signature = [self methodSignatureForSelector:@selector(informDelegateOfObjectLoadWithResultDictionary:)];
RKManagedObjectThreadSafeInvocation* invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation setObjectStore:self.objectStore];
[invocation setTarget:self];
[invocation setSelector:@selector(informDelegateOfObjectLoadWithResultDictionary:)];
[invocation setArgument:&dictionary atIndex:2];
[invocation setManagedObjectKeyPaths:_managedObjectKeyPaths forArgument:2];
[invocation invokeOnMainThread];
}
// Overloaded to handle deleting an object orphaned by a failed postObject:
– (void)handleResponseError {
[super handleResponseError];
if (_targetObjectID) {
if (_deleteObjectOnFailure) {
RKLogInfo(@”Error response encountered: Deleting existing managed object with ID: %@”, _targetObjectID);
NSManagedObject* objectToDelete = [self.objectStore objectWithID:_targetObjectID];
if (objectToDelete) {
[[self.objectStore managedObjectContextForCurrentThread] deleteObject:objectToDelete];
[self.objectStore save:nil];
} else {
RKLogWarning(@”Unable to delete existing managed object with ID: %@. Object not found in the store.”, _targetObjectID);
}
} else {
RKLogDebug(@”Skipping deletion of existing managed object”);
}
}
}
– (BOOL)isResponseMappable {
if ([self.response wasLoadedFromCache]) {
NSArray* cachedObjects = [self cachedObjects];
if (! cachedObjects) {
RKLogDebug(@”Skipping managed object mapping optimization -> Managed object cache returned nil cachedObjects for resourcePath: %@”, self.resourcePath);
return [super isResponseMappable];
}
[self informDelegateOfObjectLoadWithResultDictionary:[NSDictionary dictionaryWithObject:cachedObjects forKey:@””]];
return NO;
}
return [super isResponseMappable];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectLoader.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectMapping.h
//
// RKManagedObjectMapping.h
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMapping.h”
//#import “RKManagedObjectStore.h”
@class RKManagedObjectStore;
/**
An RKManagedObjectMapping defines an object mapping with a Core Data destination
entity.
*/
@interface RKManagedObjectMapping : RKObjectMapping {
NSEntityDescription *_entity;
NSString *_primaryKeyAttribute;
NSMutableDictionary *_relationshipToPrimaryKeyMappings;
}
/**
Creates a new object mapping targetting the Core Data entity represented by objectClass
*/
+ (id)mappingForClass:(Class)objectClass inManagedObjectStore:(RKManagedObjectStore *)objectStore;
/**
Creates a new object mapping targetting the specified Core Data entity
*/
+ (RKManagedObjectMapping *)mappingForEntity:(NSEntityDescription *)entity inManagedObjectStore:(RKManagedObjectStore *)objectStore;
/**
Creates a new object mapping targetting the Core Data entity with the specified name.
The entity description is fetched from the managed object context associated with objectStore
*/
+ (RKManagedObjectMapping *)mappingForEntityWithName:(NSString *)entityName inManagedObjectStore:(RKManagedObjectStore *)objectStore;
/**
The Core Data entity description used for this object mapping
*/
@property (nonatomic, readonly) NSEntityDescription *entity;
/**
The name of the attribute on the destination entity that acts as the primary key for instances
of the entity in the remote backend system. Used to uniquely identify objects within the store
so that existing objects are updated rather than creating new ones.
@warning Note that primaryKeyAttribute defaults to the primaryKeyAttribute configured
on the NSEntityDescription for the entity targetted by the receiving mapping. This provides
flexibility in cases where a single entity is the target of many mappings with differing
primary key definitions.
If the primaryKeyAttribute is set on an RKManagedObjectMapping that targets an entity with a
nil primaryKeyAttribute, then the primaryKeyAttribute will be set on the entity as well for
convenience and backwards compatibility. This may change in the future.
@see [NSEntityDescription primaryKeyAttribute]
*/
@property (nonatomic, retain) NSString *primaryKeyAttribute;
/**
Returns a dictionary containing Core Data relationships and attribute pairs containing
the primary key for
*/
@property (nonatomic, readonly) NSDictionary *relationshipsAndPrimaryKeyAttributes;
/**
The RKManagedObjectStore containing the Core Data entity being mapped
*/
@property (nonatomic, readonly) RKManagedObjectStore *objectStore;
/**
Instructs RestKit to automatically connect a relationship of the object being mapped by looking up
the related object by primary key.
For example, given a Project object associated with a User, where the ‘user’ relationship is
specified by a userID property on the managed object:
[mapping connectRelationship:@”user” withObjectForPrimaryKeyAttribute:@”userID”];
Will hydrate the ‘user’ association on the managed object with the object
in the local object graph having the primary key specified in the managed object’s
userID property.
In effect, this approach allows foreign key relationships between managed objects
to be automatically maintained from the server to the underlying Core Data object graph.
*/
– (void)connectRelationship:(NSString *)relationshipName withObjectForPrimaryKeyAttribute:(NSString *)primaryKeyAttribute;
/**
Connects relationships using the primary key values contained in the specified attribute. This method is
a short-cut for repeated invocation of `connectRelationship:withObjectForPrimaryKeyAttribute:`.
@see connectRelationship:withObjectForPrimaryKeyAttribute:
*/
– (void)connectRelationshipsWithObjectsForPrimaryKeyAttributes:(NSString *)firstRelationshipName, … NS_REQUIRES_NIL_TERMINATION;
/**
Conditionally connect a relationship of the object being mapped when the object being mapped has
keyPath equal to a specified value.
For example, given a Project object associated with a User, where the ‘admin’ relationship is
specified by a adminID property on the managed object:
[mapping connectRelationship:@”admin” withObjectForPrimaryKeyAttribute:@”adminID” whenValueOfKeyPath:@”userType” isEqualTo:@”Admin”];
Will hydrate the ‘admin’ association on the managed object with the object
in the local object graph having the primary key specified in the managed object’s
userID property. Note that this connection will only occur when the Product’s ‘userType’
property equals ‘Admin’. In cases where no match occurs, the relationship connection is skipped.
@see connectRelationship:withObjectForPrimaryKeyAttribute:
*/
– (void)connectRelationship:(NSString *)relationshipName withObjectForPrimaryKeyAttribute:(NSString *)primaryKeyAttribute whenValueOfKeyPath:(NSString *)keyPath isEqualTo:(id)value;
/**
Conditionally connect a relationship of the object being mapped when the object being mapped has
block evaluate to YES. This variant is useful in cases where you want to execute an arbitrary
block to determine whether or not to connect a relationship.
For example, given a Project object associated with a User, where the ‘admin’ relationship is
specified by a adminID property on the managed object:
[mapping connectRelationship:@”admin” withObjectForPrimaryKeyAttribute:@”adminID” usingEvaluationBlock:^(id data) {
return [User isAuthenticated];
}];
Will hydrate the ‘admin’ association on the managed object with the object
in the local object graph having the primary key specified in the managed object’s
userID property. Note that this connection will only occur when the provided block evalutes to YES.
In cases where no match occurs, the relationship connection is skipped.
@see connectRelationship:withObjectForPrimaryKeyAttribute:
*/
– (void)connectRelationship:(NSString *)relationshipName withObjectForPrimaryKeyAttribute:(NSString *)primaryKeyAttribute usingEvaluationBlock:(BOOL (^)(id data))block;
/**
Initialize a managed object mapping with a Core Data entity description and a RestKit managed object store
*/
– (id)initWithEntity:(NSEntityDescription *)entity inManagedObjectStore:(RKManagedObjectStore *)objectStore;
/**
Returns the default value for the specified attribute as expressed in the Core Data entity definition. This value will
be assigned if the object mapping is applied and a value for a missing attribute is not present in the payload.
*/
– (id)defaultValueForMissingAttribute:(NSString *)attributeName;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectMapping.m
//
// RKManagedObjectMapping.m
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectMapping.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKManagedObjectStore.h”
#import “RKDynamicObjectMappingMatcher.h”
#import “RKObjectPropertyInspector+CoreData.h”
#import “NSEntityDescription+RKAdditions.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKManagedObjectMapping
@synthesize entity = _entity;
@synthesize primaryKeyAttribute = _primaryKeyAttribute;
@synthesize objectStore = _objectStore;
+ (id)mappingForClass:(Class)objectClass {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must provide a managedObjectStore. Invoke mappingForClass:inManagedObjectStore: instead.”]
userInfo:nil];
}
+ (id)mappingForClass:(Class)objectClass inManagedObjectStore:(RKManagedObjectStore *)objectStore {
return [self mappingForEntityWithName:NSStringFromClass(objectClass) inManagedObjectStore:objectStore];
}
+ (RKManagedObjectMapping *)mappingForEntity:(NSEntityDescription*)entity inManagedObjectStore:(RKManagedObjectStore *)objectStore {
return [[[self alloc] initWithEntity:entity inManagedObjectStore:objectStore] autorelease];
}
+ (RKManagedObjectMapping *)mappingForEntityWithName:(NSString*)entityName inManagedObjectStore:(RKManagedObjectStore *)objectStore {
return [self mappingForEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:objectStore.primaryManagedObjectContext]
inManagedObjectStore:objectStore];
}
– (id)initWithEntity:(NSEntityDescription*)entity inManagedObjectStore:(RKManagedObjectStore*)objectStore {
NSAssert(entity, @”Cannot initialize an RKManagedObjectMapping without an entity. Maybe you want RKObjectMapping instead?”);
NSAssert(objectStore, @”Object store cannot be nil”);
Class objectClass = NSClassFromString([entity managedObjectClassName]);
NSAssert(objectClass, @”The managedObjectClass for an object mapped entity cannot be nil.”);
self = [self init];
if (self) {
_objectClass = [objectClass retain];
_entity = [entity retain];
_objectStore = objectStore;
[self addObserver:self forKeyPath:@”entity” options:NSKeyValueObservingOptionInitial context:nil];
[self addObserver:self forKeyPath:@”primaryKeyAttribute” options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
}
return self;
}
– (id)init {
self = [super init];
if (self) {
_relationshipToPrimaryKeyMappings = [[NSMutableDictionary alloc] init];
}
return self;
}
– (void)dealloc {
[self removeObserver:self forKeyPath:@”entity”];
[self removeObserver:self forKeyPath:@”primaryKeyAttribute”];
[_entity release];
[_relationshipToPrimaryKeyMappings release];
[super dealloc];
}
– (NSDictionary*)relationshipsAndPrimaryKeyAttributes {
return _relationshipToPrimaryKeyMappings;
}
– (void)connectRelationship:(NSString*)relationshipName withObjectForPrimaryKeyAttribute:(NSString*)primaryKeyAttribute {
NSAssert([_relationshipToPrimaryKeyMappings objectForKey:relationshipName] == nil, @”Cannot add connect relationship %@ by primary key, a mapping already exists.”, relationshipName);
[_relationshipToPrimaryKeyMappings setObject:primaryKeyAttribute forKey:relationshipName];
}
– (void)connectRelationshipsWithObjectsForPrimaryKeyAttributes:(NSString*)firstRelationshipName, … {
va_list args;
va_start(args, firstRelationshipName);
for (NSString* relationshipName = firstRelationshipName; relationshipName != nil; relationshipName = va_arg(args, NSString*)) {
NSString* primaryKeyAttribute = va_arg(args, NSString*);
NSAssert(primaryKeyAttribute != nil, @”Cannot connect a relationship without an attribute containing the primary key”);
[self connectRelationship:relationshipName withObjectForPrimaryKeyAttribute:primaryKeyAttribute];
// TODO: Raise proper exception here, argument error…
}
va_end(args);
}
– (void)connectRelationship:(NSString*)relationshipName withObjectForPrimaryKeyAttribute:(NSString*)primaryKeyAttribute whenValueOfKeyPath:(NSString*)keyPath isEqualTo:(id)value {
NSAssert([_relationshipToPrimaryKeyMappings objectForKey:relationshipName] == nil, @”Cannot add connect relationship %@ by primary key, a mapping already exists.”, relationshipName);
RKDynamicObjectMappingMatcher* matcher = [[RKDynamicObjectMappingMatcher alloc] initWithKey:keyPath value:value primaryKeyAttribute:primaryKeyAttribute];
[_relationshipToPrimaryKeyMappings setObject:matcher forKey:relationshipName];
[matcher release];
}
– (void)connectRelationship:(NSString*)relationshipName withObjectForPrimaryKeyAttribute:(NSString*)primaryKeyAttribute usingEvaluationBlock:(BOOL (^)(id data))block {
NSAssert([_relationshipToPrimaryKeyMappings objectForKey:relationshipName] == nil, @”Cannot add connect relationship %@ by primary key, a mapping already exists.”, relationshipName);
RKDynamicObjectMappingMatcher* matcher = [[RKDynamicObjectMappingMatcher alloc] initWithPrimaryKeyAttribute:primaryKeyAttribute evaluationBlock:block];
[_relationshipToPrimaryKeyMappings setObject:matcher forKey:relationshipName];
[matcher release];
}
– (id)defaultValueForMissingAttribute:(NSString*)attributeName {
NSAttributeDescription *desc = [[self.entity attributesByName] valueForKey:attributeName];
return [desc defaultValue];
}
– (id)mappableObjectForData:(id)mappableData {
NSAssert(mappableData, @”Mappable data cannot be nil”);
id object = nil;
id primaryKeyValue = nil;
NSString* primaryKeyAttribute;
NSEntityDescription* entity = [self entity];
RKObjectAttributeMapping* primaryKeyAttributeMapping = nil;
primaryKeyAttribute = [self primaryKeyAttribute];
if (primaryKeyAttribute) {
// If a primary key has been set on the object mapping, find the attribute mapping
// so that we can extract any existing primary key from the mappable data
for (RKObjectAttributeMapping* attributeMapping in self.attributeMappings) {
if ([attributeMapping.destinationKeyPath isEqualToString:primaryKeyAttribute]) {
primaryKeyAttributeMapping = attributeMapping;
break;
}
}
// Get the primary key value out of the mappable data (if any)
if ([primaryKeyAttributeMapping isMappingForKeyOfNestedDictionary]) {
RKLogDebug(@”Detected use of nested dictionary key as primaryKey attribute…”);
primaryKeyValue = [[mappableData allKeys] lastObject];
} else {
NSString* keyPathForPrimaryKeyElement = primaryKeyAttributeMapping.sourceKeyPath;
if (keyPathForPrimaryKeyElement) {
primaryKeyValue = [mappableData valueForKeyPath:keyPathForPrimaryKeyElement];
} else {
RKLogWarning(@”Unable to find source attribute for primaryKeyAttribute ‘%@’: unable to find existing object instances by primary key.”, primaryKeyAttribute);
}
}
}
// If we have found the primary key attribute & value, try to find an existing instance to update
if (primaryKeyAttribute && primaryKeyValue && NO == [primaryKeyValue isEqual:[NSNull null]]) {
object = [self.objectStore.cacheStrategy findInstanceOfEntity:entity
withPrimaryKeyAttribute:primaryKeyAttribute
value:primaryKeyValue
inManagedObjectContext:[self.objectStore managedObjectContextForCurrentThread]];
if (object && [self.objectStore.cacheStrategy respondsToSelector:@selector(didFetchObject:)]) {
[self.objectStore.cacheStrategy didFetchObject:object];
}
}
if (object == nil) {
object = [[[NSManagedObject alloc] initWithEntity:entity
insertIntoManagedObjectContext:[_objectStore managedObjectContextForCurrentThread]] autorelease];
if (primaryKeyAttribute && primaryKeyValue && ![primaryKeyValue isEqual:[NSNull null]]) {
id coercedPrimaryKeyValue = [entity coerceValueForPrimaryKey:primaryKeyValue];
[object setValue:coercedPrimaryKeyValue forKey:primaryKeyAttribute];
}
if ([self.objectStore.cacheStrategy respondsToSelector:@selector(didCreateObject:)]) {
[self.objectStore.cacheStrategy didCreateObject:object];
}
}
return object;
}
– (Class)classForProperty:(NSString*)propertyName {
Class propertyClass = [super classForProperty:propertyName];
if (! propertyClass) {
propertyClass = [[RKObjectPropertyInspector sharedInspector] typeForProperty:propertyName ofEntity:self.entity];
}
return propertyClass;
}
/*
Allows the primaryKeyAttributeName property on the NSEntityDescription to configure the mapping and vice-versa
*/
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@”entity”]) {
if (! self.primaryKeyAttribute) {
self.primaryKeyAttribute = [self.entity primaryKeyAttributeName];
}
} else if ([keyPath isEqualToString:@”primaryKeyAttribute”]) {
if (! self.entity.primaryKeyAttribute) {
self.entity.primaryKeyAttributeName = self.primaryKeyAttribute;
}
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectMappingOperation.h
//
// RKManagedObjectMappingOperation.h
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingOperation.h”
/**
Enhances the object mapping operation process with Core Data specific logic
*/
@interface RKManagedObjectMappingOperation : RKObjectMappingOperation {
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectMappingOperation.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectMappingOperation.m
//
// RKManagedObjectMappingOperation.m
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectMappingOperation.h”
#import “RKManagedObjectMapping.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKDynamicObjectMappingMatcher.h”
#import “RKManagedObjectCaching.h”
#import “RKManagedObjectStore.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKManagedObjectMappingOperation
– (void)connectRelationship:(NSString *)relationshipName {
NSDictionary* relationshipsAndPrimaryKeyAttributes = [(RKManagedObjectMapping*)self.objectMapping relationshipsAndPrimaryKeyAttributes];
id primaryKeyObject = [relationshipsAndPrimaryKeyAttributes objectForKey:relationshipName];
NSString* primaryKeyAttribute = nil;
if ([primaryKeyObject isKindOfClass:[RKDynamicObjectMappingMatcher class]]) {
RKLogTrace(@”Found a dynamic matcher attempting to connect relationshipName: %@”, relationshipName);
RKDynamicObjectMappingMatcher* matcher = (RKDynamicObjectMappingMatcher*)primaryKeyObject;
if ([matcher isMatchForData:self.destinationObject]) {
primaryKeyAttribute = matcher.primaryKeyAttribute;
RKLogTrace(@”Dynamic matched succeeded. Proceeding to connect relationshipName ‘%@’ using primaryKeyAttribute ‘%@'”, relationshipName, primaryKeyAttribute);
} else {
RKLogTrace(@”Dynamic matcher match failed. Skipping connection of relationshipName: %@”, relationshipName);
return;
}
} else if ([primaryKeyObject isKindOfClass:[NSString class]]) {
primaryKeyAttribute = (NSString*)primaryKeyObject;
}
NSAssert(primaryKeyAttribute, @”Cannot connect relationship without primaryKeyAttribute”);
RKObjectRelationshipMapping* relationshipMapping = [self.objectMapping mappingForRelationship:relationshipName];
RKObjectMappingDefinition *mapping = relationshipMapping.mapping;
NSAssert(mapping, @”Attempted to connect relationship for keyPath ‘%@’ without a relationship mapping defined.”);
if (! [mapping isKindOfClass:[RKObjectMapping class]]) {
RKLogWarning(@”Can only connect relationships for RKObjectMapping relationships. Found %@: Skipping…”, NSStringFromClass([mapping class]));
return;
}
RKManagedObjectMapping *objectMapping = (RKManagedObjectMapping *) mapping;
NSAssert(relationshipMapping, @”Unable to find relationship mapping ‘%@’ to connect by primaryKey”, relationshipName);
NSAssert([relationshipMapping isKindOfClass:[RKObjectRelationshipMapping class]], @”Expected mapping for %@ to be a relationship mapping”, relationshipName);
NSAssert([relationshipMapping.mapping isKindOfClass:[RKManagedObjectMapping class]], @”Can only connect RKManagedObjectMapping relationships”);
NSString* primaryKeyAttributeOfRelatedObject = [(RKManagedObjectMapping*)objectMapping primaryKeyAttribute];
NSAssert(primaryKeyAttributeOfRelatedObject, @”Cannot connect relationship: mapping for %@ has no primary key attribute specified”, NSStringFromClass(objectMapping.objectClass));
id valueOfLocalPrimaryKeyAttribute = [self.destinationObject valueForKey:primaryKeyAttribute];
if (valueOfLocalPrimaryKeyAttribute) {
id relatedObject = nil;
if ([valueOfLocalPrimaryKeyAttribute conformsToProtocol:@protocol(NSFastEnumeration)]) {
RKLogTrace(@”Connecting has-many relationship at keyPath ‘%@’ to object with primaryKey attribute ‘%@'”, relationshipName, primaryKeyAttributeOfRelatedObject);
// Implemented for issue 284 – https://github.com/RestKit/RestKit/issues/284
relatedObject = [NSMutableSet set];
NSObject
for (id foreignKey in valueOfLocalPrimaryKeyAttribute) {
id searchResult = [cache findInstanceOfEntity:objectMapping.entity withPrimaryKeyAttribute:primaryKeyAttributeOfRelatedObject value:foreignKey inManagedObjectContext:[[(RKManagedObjectMapping*)[self objectMapping] objectStore] managedObjectContextForCurrentThread]];
if (searchResult) {
[relatedObject addObject:searchResult];
}
}
} else {
RKLogTrace(@”Connecting has-one relationship at keyPath ‘%@’ to object with primaryKey attribute ‘%@'”, relationshipName, primaryKeyAttributeOfRelatedObject);
// Normal foreign key
NSObject
relatedObject = [cache findInstanceOfEntity:objectMapping.entity withPrimaryKeyAttribute:primaryKeyAttributeOfRelatedObject value:valueOfLocalPrimaryKeyAttribute inManagedObjectContext:[self.destinationObject managedObjectContext]];
}
if (relatedObject) {
RKLogDebug(@”Connected relationship ‘%@’ to object with primary key value ‘%@’: %@”, relationshipName, valueOfLocalPrimaryKeyAttribute, relatedObject);
} else {
RKLogDebug(@”Failed to find instance of ‘%@’ to connect relationship ‘%@’ with primary key value ‘%@'”, [[objectMapping entity] name], relationshipName, valueOfLocalPrimaryKeyAttribute);
}
if ([relatedObject isKindOfClass:[NSManagedObject class]]) {
// Sanity check the managed object contexts
NSAssert([[(NSManagedObject *)self.destinationObject managedObjectContext] isEqual:[(NSManagedObject *)relatedObject managedObjectContext]], nil);
}
RKLogTrace(@”setValue of %@ forKeyPath %@”, relatedObject, relationshipName);
[self.destinationObject setValue:relatedObject forKeyPath:relationshipName];
} else {
RKLogTrace(@”Failed to find primary key value for attribute ‘%@'”, primaryKeyAttribute);
}
}
– (void)connectRelationships {
NSDictionary* relationshipsAndPrimaryKeyAttributes = [(RKManagedObjectMapping *)self.objectMapping relationshipsAndPrimaryKeyAttributes];
RKLogTrace(@”relationshipsAndPrimaryKeyAttributes: %@”, relationshipsAndPrimaryKeyAttributes);
for (NSString* relationshipName in relationshipsAndPrimaryKeyAttributes) {
if (self.queue) {
RKLogTrace(@”Enqueueing relationship connection using operation queue”);
__block RKManagedObjectMappingOperation *selfRef = self;
[self.queue addOperationWithBlock:^{
[selfRef connectRelationship:relationshipName];
}];
} else {
[self connectRelationship:relationshipName];
}
}
}
– (BOOL)performMapping:(NSError **)error {
BOOL success = [super performMapping:error];
if ([self.objectMapping isKindOfClass:[RKManagedObjectMapping class]]) {
/**
NOTE: Processing the pending changes here ensures that the managed object context generates observable
callbacks that are important for maintaining any sort of cache that is consistent within a single
object mapping operation. As the MOC is only saved when the aggregate operation is processed, we must
manually invoke processPendingChanges to prevent recreating objects with the same primary key.
See https://github.com/RestKit/RestKit/issues/661
*/
[self connectRelationships];
}
return success;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectMappingOperation.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectSearchEngine.h
//
// RKManagedObjectSearchEngine.h
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKSearchEngine.h”
@interface RKManagedObjectSearchEngine : NSObject {
RKSearchMode _mode;
}
/**
* The type of searching to perform. Can be either RKSearchModeAnd or RKSearchModeOr.
*
* Defaults to RKSearchModeOr
*/
@property (nonatomic, assign) RKSearchMode mode;
/**
* Construct a new search engine
*/
+ (id)searchEngine;
/**
* Normalize and tokenize the provided string into an NSArray.
* Note that returned value may contain entries of empty strings.
*/
+ (NSArray*)tokenizedNormalizedString:(NSString*)string;
/**
* Generate a predicate for the supplied search term against
* searchableAttributes (defined for an RKSearchableManagedObject)
*/
– (NSPredicate*)predicateForSearch:(NSString*)searchText;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectSearchEngine.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectSearchEngine.m
//
// RKManagedObjectSearchEngine.m
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectSearchEngine.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKManagedObjectSearchEngine
static NSMutableCharacterSet* __removeSet;
@synthesize mode = _mode;
+ (id)searchEngine {
RKManagedObjectSearchEngine* searchEngine = [[[RKManagedObjectSearchEngine alloc] init] autorelease];
return searchEngine;
}
– (id)init {
if (self = [super init]) {
_mode = RKSearchModeOr;
}
return self;
}
#pragma mark –
#pragma mark Private
– (NSPredicate*)predicateForSearch:(NSArray*)searchTerms compoundSelector:(SEL)selector {
NSMutableArray* termPredicates = [NSMutableArray array];
for (NSString* searchTerm in searchTerms) {
[termPredicates addObject:
[NSPredicate predicateWithFormat:@”(ANY searchWords.word beginswith %@)”, searchTerm]];
}
return [NSCompoundPredicate performSelector:selector withObject:termPredicates];
}
#pragma mark –
#pragma mark Public
+ (NSArray*)tokenizedNormalizedString:(NSString*)string {
if (__removeSet == nil) {
NSMutableCharacterSet* removeSet = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[removeSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
[removeSet invert];
__removeSet = removeSet;
}
NSString* scannerString = [[[[string lowercaseString] decomposedStringWithCanonicalMapping]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
stringByReplacingOccurrencesOfString:@”-” withString:@” “];
NSArray* tokens = [[[scannerString componentsSeparatedByCharactersInSet:__removeSet]
componentsJoinedByString:@””] componentsSeparatedByString:@” “];
return tokens;
}
– (NSPredicate*)predicateForSearch:(NSString*)searchText {
NSString* searchQuery = [searchText copy];
NSArray* searchTerms = [RKManagedObjectSearchEngine tokenizedNormalizedString:searchQuery];
[searchQuery release];
if ([searchTerms count] == 0) {
return nil;
}
if (_mode == RKSearchModeOr) {
return [self predicateForSearch:searchTerms
compoundSelector:@selector(orPredicateWithSubpredicates:)];
} else if (_mode == RKSearchModeAnd) {
return [self predicateForSearch:searchTerms
compoundSelector:@selector(andPredicateWithSubpredicates:)];
} else {
return nil;
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectSearchEngine.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectSeeder.h
//
// RKManagedObjectSeeder.h
// RestKit
//
// Created by Blake Watters on 3/4/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “ObjectMapping.h”
// The default seed database filename. Used when the object store has not been initialized
extern NSString* const RKDefaultSeedDatabaseFileName;
@protocol RKManagedObjectSeederDelegate
@required
// Invoked when the seeder creates a new object
– (void)didSeedObject:(NSManagedObject*)object fromFile:(NSString*)fileName;
@end
/**
* Provides an interface for generating a seed database suitable for initializing
* a Core Data backed RestKit application. The object seeder loads files from the
* application’s main bundle and processes them with the Object Mapper to produce
* a database on disk. This file can then be copied into the main bundle of an application
* and provided to RKManagedObjectStore at initialization to start the app with a set of
* data immediately available for use within Core Data.
*/
@interface RKManagedObjectSeeder : NSObject {
RKObjectManager* _manager;
NSObject
}
// Delegate for seeding operations
@property (nonatomic, assign) NSObject
// Path to the generated seed database on disk
@property (nonatomic, readonly) NSString* pathToSeedDatabase;
/**
* Generates a seed database using an object manager and a null terminated list of files. Exits
* the seeding process and outputs an informational message
*/
+ (void)generateSeedDatabaseWithObjectManager:(RKObjectManager*)objectManager fromFiles:(NSString*)fileName, …;
/**
* Returns an object seeder ready to begin seeding. Requires a fully configured instance of an object manager.
*/
+ (RKManagedObjectSeeder*)objectSeederWithObjectManager:(RKObjectManager*)objectManager;
/**
* Seed the database with objects from the specified file(s). The list must be terminated by nil
*/
– (void)seedObjectsFromFiles:(NSString*)fileName, …;
/**
* Seed the database with objects from the specified file using the supplied object mapping.
*/
– (void)seedObjectsFromFile:(NSString*)fileName withObjectMapping:(RKObjectMapping*)nilOrObjectMapping;
/**
* Seed the database with objects from the specified file, from the specified bundle, using the supplied object mapping.
*/
– (void)seedObjectsFromFile:(NSString *)fileName withObjectMapping:(RKObjectMapping *)nilOrObjectMapping bundle:(NSBundle *)nilOrBundle;
/**
* Completes a seeding session by persisting the store, outputing an informational message
* and exiting the process
*/
– (void)finalizeSeedingAndExit;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectSeeder.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectSeeder.m
//
// RKObjectSeeder.m
// RestKit
//
// Created by Blake Watters on 3/4/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#endif
#import “RKManagedObjectSeeder.h”
#import “RKManagedObjectStore.h”
#import “RKParserRegistry.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@interface RKManagedObjectSeeder (Private)
– (id)initWithObjectManager:(RKObjectManager*)manager;
– (void)seedObjectsFromFileNames:(NSArray*)fileNames;
@end
NSString* const RKDefaultSeedDatabaseFileName = @”RKSeedDatabase.sqlite”;
@implementation RKManagedObjectSeeder
@synthesize delegate = _delegate;
+ (void)generateSeedDatabaseWithObjectManager:(RKObjectManager*)objectManager fromFiles:(NSString*)firstFileName, … {
RKManagedObjectSeeder* seeder = [RKManagedObjectSeeder objectSeederWithObjectManager:objectManager];
va_list args;
va_start(args, firstFileName);
NSMutableArray* fileNames = [NSMutableArray array];
for (NSString* fileName = firstFileName; fileName != nil; fileName = va_arg(args, id)) {
[fileNames addObject:fileName];
}
va_end(args);
// Seed the files
for (NSString* fileName in fileNames) {
[seeder seedObjectsFromFile:fileName withObjectMapping:nil];
}
[seeder finalizeSeedingAndExit];
}
+ (RKManagedObjectSeeder*)objectSeederWithObjectManager:(RKObjectManager*)objectManager {
return [[[RKManagedObjectSeeder alloc] initWithObjectManager:objectManager] autorelease];
}
– (id)initWithObjectManager:(RKObjectManager*)manager {
self = [self init];
if (self) {
_manager = [manager retain];
// If the user hasn’t configured an object store, set one up for them
if (nil == _manager.objectStore) {
_manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:RKDefaultSeedDatabaseFileName];
}
// Delete any existing persistent store
[_manager.objectStore deletePersistentStore];
}
return self;
}
– (void)dealloc {
[_manager release];
[super dealloc];
}
– (NSString*)pathToSeedDatabase {
return _manager.objectStore.pathToStoreFile;
}
– (void)seedObjectsFromFiles:(NSString*)firstFileName, … {
va_list args;
va_start(args, firstFileName);
NSMutableArray* fileNames = [NSMutableArray array];
for (NSString* fileName = firstFileName; fileName != nil; fileName = va_arg(args, id)) {
[fileNames addObject:fileName];
}
va_end(args);
for (NSString* fileName in fileNames) {
[self seedObjectsFromFile:fileName withObjectMapping:nil];
}
}
– (void)seedObjectsFromFile:(NSString*)fileName withObjectMapping:(RKObjectMapping *)nilOrObjectMapping {
[self seedObjectsFromFile:fileName withObjectMapping:nilOrObjectMapping bundle:nil];
}
– (void)seedObjectsFromFile:(NSString *)fileName withObjectMapping:(RKObjectMapping *)nilOrObjectMapping bundle:(NSBundle *)nilOrBundle
{
NSError* error = nil;
if (nilOrBundle == nil) {
nilOrBundle = [NSBundle mainBundle];
}
NSString* filePath = [nilOrBundle pathForResource:fileName ofType:nil];
NSString* payload = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
if (payload) {
NSString* MIMEType = [fileName MIMETypeForPathExtension];
if (MIMEType == nil) {
// Default the MIME type to the value of the Accept header if we couldn’t detect it…
MIMEType = _manager.acceptMIMEType;
}
id
NSAssert1(parser, @”Could not find a parser for the MIME Type ‘%@'”, MIMEType);
id parsedData = [parser objectFromString:payload error:&error];
NSAssert(parsedData, @”Cannot perform object load without data for mapping”);
RKObjectMappingProvider* mappingProvider = nil;
if (nilOrObjectMapping) {
mappingProvider = [[RKObjectMappingProvider new] autorelease];
[mappingProvider setMapping:nilOrObjectMapping forKeyPath:@””];
} else {
mappingProvider = _manager.mappingProvider;
}
RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider];
RKObjectMappingResult* result = [mapper performMapping];
if (result == nil) {
RKLogError(@”Database seeding from file ‘%@’ failed due to object mapping errors: %@”, fileName, mapper.errors);
return;
}
NSArray* mappedObjects = [result asCollection];
NSAssert1([mappedObjects isKindOfClass:[NSArray class]], @”Expected an NSArray of objects, got %@”, mappedObjects);
// Inform the delegate
if (self.delegate) {
for (NSManagedObject* object in mappedObjects) {
[self.delegate didSeedObject:object fromFile:fileName];
}
}
RKLogInfo(@”Seeded %lu objects from %@…”, (unsigned long) [mappedObjects count], [NSString stringWithFormat:@”%@”, fileName]);
} else {
RKLogError(@”Unable to read file %@: %@”, fileName, [error localizedDescription]);
}
}
– (void)finalizeSeedingAndExit {
NSError *error = nil;
BOOL success = [[_manager objectStore] save:&error];
if (! success) {
RKLogError(@”[RestKit] RKManagedObjectSeeder: Error saving object context: %@”, [error localizedDescription]);
}
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString* storeFileName = [[_manager objectStore] storeFilename];
NSString* destinationPath = [basePath stringByAppendingPathComponent:storeFileName];
RKLogInfo(@”A seeded database has been generated at ‘%@’. ”
@”Please execute `open \”%@\”` in your Terminal and copy %@ to your app. Be sure to add the seed database to your \”Copy Resources\” build phase.”,
destinationPath, basePath, storeFileName);
exit(1);
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectSeeder.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectStore.h
//
// RKManagedObjectStore.h
// RestKit
//
// Created by Blake Watters on 9/22/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKManagedObjectMapping.h”
#import “RKManagedObjectCaching.h”
@class RKManagedObjectStore;
/**
* Notifications
*/
extern NSString* const RKManagedObjectStoreDidFailSaveNotification;
///////////////////////////////////////////////////////////////////
@protocol RKManagedObjectStoreDelegate
@optional
– (void)managedObjectStore:(RKManagedObjectStore *)objectStore didFailToCreatePersistentStoreCoordinatorWithError:(NSError *)error;
– (void)managedObjectStore:(RKManagedObjectStore *)objectStore didFailToDeletePersistentStore:(NSString *)pathToStoreFile error:(NSError *)error;
– (void)managedObjectStore:(RKManagedObjectStore *)objectStore didFailToCopySeedDatabase:(NSString *)seedDatabase error:(NSError *)error;
– (void)managedObjectStore:(RKManagedObjectStore *)objectStore didFailToSaveContext:(NSManagedObjectContext *)context error:(NSError *)error exception:(NSException *)exception;
@end
///////////////////////////////////////////////////////////////////
@interface RKManagedObjectStore : NSObject {
NSObject
NSString* _storeFilename;
NSString* _pathToStoreFile;
NSManagedObjectModel* _managedObjectModel;
NSPersistentStoreCoordinator* _persistentStoreCoordinator;
}
// The delegate for this object store
@property (nonatomic, assign) NSObject
// The filename of the database backing this object store
@property (nonatomic, readonly) NSString* storeFilename;
// The full path to the database backing this object store
@property (nonatomic, readonly) NSString* pathToStoreFile;
// Core Data
@property (nonatomic, readonly) NSManagedObjectModel* managedObjectModel;
@property (nonatomic, readonly) NSPersistentStoreCoordinator* persistentStoreCoordinator;
///—————————————————————————–
/// @name Accessing the Default Object Store
///—————————————————————————–
+ (RKManagedObjectStore *)defaultObjectStore;
+ (void)setDefaultObjectStore:(RKManagedObjectStore *)objectStore;
///—————————————————————————–
/// @name Deleting Store Files
///—————————————————————————–
/**
Deletes the SQLite file backing an RKManagedObjectStore instance at a given path.
@param path The complete path to the store file to delete.
*/
+ (void)deleteStoreAtPath:(NSString *)path;
/**
Deletes the SQLite file backing an RKManagedObjectStore instance with a given
filename within the application data directory.
@param filename The name of the file within the application data directory backing a managed object store.
*/
+ (void)deleteStoreInApplicationDataDirectoryWithFilename:(NSString *)filename;
///—————————————————————————–
/// @name Initializing an Object Store
///—————————————————————————–
/**
*/
@property (nonatomic, retain) NSObject
/**
* Initialize a new managed object store with a SQLite database with the filename specified
*/
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString*)storeFilename;
/**
* Initialize a new managed object store backed by a SQLite database with the specified filename.
* If a seed database name is provided and no existing database is found, initialize the store by
* copying the seed database from the main bundle. If the managed object model provided is nil,
* all models will be merged from the main bundle for you.
*/
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString *)storeFilename usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate;
/**
* Initialize a new managed object store backed by a SQLite database with the specified filename,
* in the specified directory. If no directory is specified, will use the app’s Documents
* directory. If a seed database name is provided and no existing database is found, initialize
* the store by copying the seed database from the main bundle. If the managed object model
* provided is nil, all models will be merged from the main bundle for you.
*/
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString *)storeFilename inDirectory:(NSString *)directory usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate;
/**
* Initialize a new managed object store with a SQLite database with the filename specified
* @deprecated
*/
– (id)initWithStoreFilename:(NSString*)storeFilename DEPRECATED_ATTRIBUTE;
/**
* Save the current contents of the managed object store
*/
– (BOOL)save:(NSError **)error;
/**
* This deletes and recreates the managed object context and
* persistent store, effectively clearing all data
*/
– (void)deletePersistentStoreUsingSeedDatabaseName:(NSString *)seedFile;
– (void)deletePersistentStore;
/**
* Retrieves a model object from the appropriate context using the objectId
*/
– (NSManagedObject*)objectWithID:(NSManagedObjectID*)objectID;
/**
* Retrieves a array of model objects from the appropriate context using
* an array of NSManagedObjectIDs
*/
– (NSArray*)objectsWithIDs:(NSArray*)objectIDs;
///—————————————————————————–
/// @name Retrieving Managed Object Contexts
///—————————————————————————–
/**
Retrieves the Managed Object Context for the main thread that was initialized when
the object store was created.
*/
@property (nonatomic, retain, readonly) NSManagedObjectContext *primaryManagedObjectContext;
/**
Instantiates a new managed object context
*/
– (NSManagedObjectContext *)newManagedObjectContext;
/*
* This returns an appropriate managed object context for this object store.
* Because of the intrecacies of how Core Data works across threads it returns
* a different NSManagedObjectContext for each thread.
*/
– (NSManagedObjectContext *)managedObjectContextForCurrentThread;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectStore.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectStore.m
//
// RKManagedObjectStore.m
// RestKit
//
// Created by Blake Watters on 9/22/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectStore.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKLog.h”
#import “RKSearchWordObserver.h”
#import “RKObjectPropertyInspector.h”
#import “RKObjectPropertyInspector+CoreData.h”
#import “RKAlert.h”
#import “RKDirectory.h”
#import “RKInMemoryManagedObjectCache.h”
#import “RKFetchRequestManagedObjectCache.h”
#import “NSBundle+RKAdditions.h”
#import “NSManagedObjectContext+RKAdditions.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
NSString* const RKManagedObjectStoreDidFailSaveNotification = @”RKManagedObjectStoreDidFailSaveNotification”;
static NSString* const RKManagedObjectStoreThreadDictionaryContextKey = @”RKManagedObjectStoreThreadDictionaryContextKey”;
static NSString* const RKManagedObjectStoreThreadDictionaryEntityCacheKey = @”RKManagedObjectStoreThreadDictionaryEntityCacheKey”;
static RKManagedObjectStore *defaultObjectStore = nil;
@interface RKManagedObjectStore ()
@property (nonatomic, retain, readwrite) NSManagedObjectContext *primaryManagedObjectContext;
– (id)initWithStoreFilename:(NSString *)storeFilename inDirectory:(NSString *)nilOrDirectoryPath usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate;
– (void)createPersistentStoreCoordinator;
– (void)createStoreIfNecessaryUsingSeedDatabase:(NSString*)seedDatabase;
– (NSManagedObjectContext*)newManagedObjectContext;
@end
@implementation RKManagedObjectStore
@synthesize delegate = _delegate;
@synthesize storeFilename = _storeFilename;
@synthesize pathToStoreFile = _pathToStoreFile;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
@synthesize cacheStrategy = _cacheStrategy;
@synthesize primaryManagedObjectContext;
+ (RKManagedObjectStore *)defaultObjectStore {
return defaultObjectStore;
}
+ (void)setDefaultObjectStore:(RKManagedObjectStore *)objectStore {
[objectStore retain];
[defaultObjectStore release];
defaultObjectStore = objectStore;
[NSManagedObjectContext setDefaultContext:objectStore.primaryManagedObjectContext];
}
+ (void)deleteStoreAtPath:(NSString *)path
{
NSURL* storeURL = [NSURL fileURLWithPath:path];
NSError* error = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:storeURL.path]) {
if (! [[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error]) {
NSAssert(NO, @”Managed object store failed to delete persistent store : %@”, error);
}
} else {
RKLogWarning(@”Asked to delete persistent store but no store file exists at path: %@”, storeURL.path);
}
}
+ (void)deleteStoreInApplicationDataDirectoryWithFilename:(NSString *)filename
{
NSString *path = [[RKDirectory applicationDataDirectory] stringByAppendingPathComponent:filename];
[self deleteStoreAtPath:path];
}
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString*)storeFilename {
return [self objectStoreWithStoreFilename:storeFilename usingSeedDatabaseName:nil managedObjectModel:nil delegate:nil];
}
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString *)storeFilename usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate {
return [[[self alloc] initWithStoreFilename:storeFilename inDirectory:nil usingSeedDatabaseName:nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:nilOrManagedObjectModel delegate:delegate] autorelease];
}
+ (RKManagedObjectStore*)objectStoreWithStoreFilename:(NSString *)storeFilename inDirectory:(NSString *)directory usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate {
return [[[self alloc] initWithStoreFilename:storeFilename inDirectory:directory usingSeedDatabaseName:nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:nilOrManagedObjectModel delegate:delegate] autorelease];
}
– (id)initWithStoreFilename:(NSString*)storeFilename {
return [self initWithStoreFilename:storeFilename inDirectory:nil usingSeedDatabaseName:nil managedObjectModel:nil delegate:nil];
}
– (id)initWithStoreFilename:(NSString *)storeFilename inDirectory:(NSString *)nilOrDirectoryPath usingSeedDatabaseName:(NSString *)nilOrNameOfSeedDatabaseInMainBundle managedObjectModel:(NSManagedObjectModel*)nilOrManagedObjectModel delegate:(id)delegate {
self = [self init];
if (self) {
_storeFilename = [storeFilename retain];
if (nilOrDirectoryPath == nil) {
// If initializing into Application Data directory, ensure the directory exists
nilOrDirectoryPath = [RKDirectory applicationDataDirectory];
[RKDirectory ensureDirectoryExistsAtPath:nilOrDirectoryPath error:nil];
} else {
// If path given, caller is responsible for directory’s existence
BOOL isDir;
NSAssert1([[NSFileManager defaultManager] fileExistsAtPath:nilOrDirectoryPath isDirectory:&isDir] && isDir == YES, @”Specified storage directory exists”, nilOrDirectoryPath);
}
_pathToStoreFile = [[nilOrDirectoryPath stringByAppendingPathComponent:_storeFilename] retain];
if (nilOrManagedObjectModel == nil) {
// NOTE: allBundles permits Core Data setup in unit tests
nilOrManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
}
NSMutableArray* allManagedObjectModels = [NSMutableArray arrayWithObject:nilOrManagedObjectModel];
_managedObjectModel = [[NSManagedObjectModel modelByMergingModels:allManagedObjectModels] retain];
_delegate = delegate;
if (nilOrNameOfSeedDatabaseInMainBundle) {
[self createStoreIfNecessaryUsingSeedDatabase:nilOrNameOfSeedDatabaseInMainBundle];
}
[self createPersistentStoreCoordinator];
self.primaryManagedObjectContext = [[self newManagedObjectContext] autorelease];
_cacheStrategy = [RKInMemoryManagedObjectCache new];
// Ensure there is a search word observer
[RKSearchWordObserver sharedObserver];
// Hydrate the defaultObjectStore
if (! defaultObjectStore) {
[RKManagedObjectStore setDefaultObjectStore:self];
}
}
return self;
}
– (void)setThreadLocalObject:(id)value forKey:(id)key {
NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
NSString *objectStoreKey = [NSString stringWithFormat:@”RKManagedObjectStore_%p”, self];
if (! [threadDictionary valueForKey:objectStoreKey]) {
[threadDictionary setValue:[NSMutableDictionary dictionary] forKey:objectStoreKey];
}
[[threadDictionary objectForKey:objectStoreKey] setObject:value forKey:key];
}
– (id)threadLocalObjectForKey:(id)key {
NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
NSString *objectStoreKey = [NSString stringWithFormat:@”RKManagedObjectStore_%p”, self];
if (! [threadDictionary valueForKey:objectStoreKey]) {
[threadDictionary setObject:[NSMutableDictionary dictionary] forKey:objectStoreKey];
}
return [[threadDictionary objectForKey:objectStoreKey] objectForKey:key];
}
– (void)removeThreadLocalObjectForKey:(id)key {
NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary];
NSString *objectStoreKey = [NSString stringWithFormat:@”RKManagedObjectStore_%p”, self];
if (! [threadDictionary valueForKey:objectStoreKey]) {
[threadDictionary setObject:[NSMutableDictionary dictionary] forKey:objectStoreKey];
}
[[threadDictionary objectForKey:objectStoreKey] removeObjectForKey:key];
}
– (void)clearThreadLocalStorage {
// Clear out our Thread local information
NSManagedObjectContext *managedObjectContext = [self threadLocalObjectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
if (managedObjectContext) {
[self removeThreadLocalObjectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
}
if ([self threadLocalObjectForKey:RKManagedObjectStoreThreadDictionaryEntityCacheKey]) {
[self removeThreadLocalObjectForKey:RKManagedObjectStoreThreadDictionaryEntityCacheKey];
}
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self clearThreadLocalStorage];
[_storeFilename release];
_storeFilename = nil;
[_pathToStoreFile release];
_pathToStoreFile = nil;
[_managedObjectModel release];
_managedObjectModel = nil;
[_persistentStoreCoordinator release];
_persistentStoreCoordinator = nil;
[_cacheStrategy release];
_cacheStrategy = nil;
[primaryManagedObjectContext release];
primaryManagedObjectContext = nil;
[super dealloc];
}
/**
Performs the save action for the application, which is to send the save:
message to the application’s managed object context.
*/
– (BOOL)save:(NSError **)error {
NSManagedObjectContext* moc = [self managedObjectContextForCurrentThread];
NSError *localError = nil;
@try {
if (![moc save:&localError]) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToSaveContext:error:exception:)]) {
[self.delegate managedObjectStore:self didFailToSaveContext:moc error:localError exception:nil];
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:localError forKey:@”error”];
[[NSNotificationCenter defaultCenter] postNotificationName:RKManagedObjectStoreDidFailSaveNotification object:self userInfo:userInfo];
if ([[localError domain] isEqualToString:@”NSCocoaErrorDomain”]) {
NSDictionary *userInfo = [localError userInfo];
NSArray *errors = [userInfo valueForKey:@”NSDetailedErrors”];
if (errors) {
for (NSError *detailedError in errors) {
NSDictionary *subUserInfo = [detailedError userInfo];
RKLogError(@”Core Data Save Error\n \
NSLocalizedDescription:\t\t%@\n \
NSValidationErrorKey:\t\t\t%@\n \
NSValidationErrorPredicate:\t%@\n \
NSValidationErrorObject:\n%@\n”,
[subUserInfo valueForKey:@”NSLocalizedDescription”],
[subUserInfo valueForKey:@”NSValidationErrorKey”],
[subUserInfo valueForKey:@”NSValidationErrorPredicate”],
[subUserInfo valueForKey:@”NSValidationErrorObject”]);
}
}
else {
RKLogError(@”Core Data Save Error\n \
NSLocalizedDescription:\t\t%@\n \
NSValidationErrorKey:\t\t\t%@\n \
NSValidationErrorPredicate:\t%@\n \
NSValidationErrorObject:\n%@\n”,
[userInfo valueForKey:@”NSLocalizedDescription”],
[userInfo valueForKey:@”NSValidationErrorKey”],
[userInfo valueForKey:@”NSValidationErrorPredicate”],
[userInfo valueForKey:@”NSValidationErrorObject”]);
}
}
if (error) {
*error = localError;
}
return NO;
}
}
@catch (NSException* e) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToSaveContext:error:exception:)]) {
[self.delegate managedObjectStore:self didFailToSaveContext:moc error:nil exception:e];
}
else {
@throw;
}
}
return YES;
}
– (NSManagedObjectContext *)newManagedObjectContext {
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
[managedObjectContext setUndoManager:nil];
[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
managedObjectContext.managedObjectStore = self;
return managedObjectContext;
}
– (void)createStoreIfNecessaryUsingSeedDatabase:(NSString*)seedDatabase {
if (NO == [[NSFileManager defaultManager] fileExistsAtPath:self.pathToStoreFile]) {
NSString* seedDatabasePath = [[NSBundle mainBundle] pathForResource:seedDatabase ofType:nil];
NSAssert1(seedDatabasePath, @”Unable to find seed database file ‘%@’ in the Main Bundle, aborting…”, seedDatabase);
RKLogInfo(@”No existing database found, copying from seed path ‘%@'”, seedDatabasePath);
NSError* error;
if (![[NSFileManager defaultManager] copyItemAtPath:seedDatabasePath toPath:self.pathToStoreFile error:&error]) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToCopySeedDatabase:error:)]) {
[self.delegate managedObjectStore:self didFailToCopySeedDatabase:seedDatabase error:error];
} else {
RKLogError(@”Encountered an error during seed database copy: %@”, [error localizedDescription]);
}
}
NSAssert1([[NSFileManager defaultManager] fileExistsAtPath:seedDatabasePath], @”Seed database not found at path ‘%@’!”, seedDatabasePath);
}
}
– (void)createPersistentStoreCoordinator {
NSAssert(_managedObjectModel, @”Cannot create persistent store coordinator without a managed object model”);
NSAssert(!_persistentStoreCoordinator, @”Cannot create persistent store coordinator: one already exists.”);
NSURL *storeURL = [NSURL fileURLWithPath:self.pathToStoreFile];
NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToCreatePersistentStoreCoordinatorWithError:)]) {
[self.delegate managedObjectStore:self didFailToCreatePersistentStoreCoordinatorWithError:error];
} else {
NSAssert(NO, @”Managed object store failed to create persistent store coordinator: %@”, error);
}
}
}
– (void)deletePersistentStoreUsingSeedDatabaseName:(NSString *)seedFile {
NSURL* storeURL = [NSURL fileURLWithPath:self.pathToStoreFile];
NSError* error = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:storeURL.path]) {
if (![[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error]) {
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToDeletePersistentStore:error:)]) {
[self.delegate managedObjectStore:self didFailToDeletePersistentStore:self.pathToStoreFile error:error];
}
else {
NSAssert(NO, @”Managed object store failed to delete persistent store : %@”, error);
}
}
} else {
RKLogWarning(@”Asked to delete persistent store but no store file exists at path: %@”, storeURL.path);
}
[_persistentStoreCoordinator release];
_persistentStoreCoordinator = nil;
if (seedFile) {
[self createStoreIfNecessaryUsingSeedDatabase:seedFile];
}
[self createPersistentStoreCoordinator];
// Recreate the MOC
self.primaryManagedObjectContext = [[self newManagedObjectContext] autorelease];
}
– (void)deletePersistentStore {
[self deletePersistentStoreUsingSeedDatabaseName:nil];
}
– (NSManagedObjectContext *)managedObjectContextForCurrentThread {
if ([NSThread isMainThread]) {
return self.primaryManagedObjectContext;
}
// Background threads leverage thread-local storage
NSManagedObjectContext* managedObjectContext = [self threadLocalObjectForKey:RKManagedObjectStoreThreadDictionaryContextKey];
if (!managedObjectContext) {
managedObjectContext = [self newManagedObjectContext];
// Store into thread local storage dictionary
[self setThreadLocalObject:managedObjectContext forKey:RKManagedObjectStoreThreadDictionaryContextKey];
[managedObjectContext release];
// If we are a background Thread MOC, we need to inform the main thread on save
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:managedObjectContext];
}
return managedObjectContext;
}
– (void)mergeChangesOnMainThreadWithNotification:(NSNotification*)notification {
assert([NSThread isMainThread]);
[self.primaryManagedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
}
– (void)mergeChanges:(NSNotification *)notification {
// Merge changes into the main context on the main thread
[self performSelectorOnMainThread:@selector(mergeChangesOnMainThreadWithNotification:) withObject:notification waitUntilDone:YES];
}
#pragma mark –
#pragma mark Helpers
– (NSManagedObject*)objectWithID:(NSManagedObjectID *)objectID {
NSAssert(objectID, @”Cannot fetch a managedObject with a nil objectID”);
return [[self managedObjectContextForCurrentThread] objectWithID:objectID];
}
– (NSArray*)objectsWithIDs:(NSArray*)objectIDs {
NSMutableArray* objects = [[NSMutableArray alloc] init];
for (NSManagedObjectID* objectID in objectIDs) {
[objects addObject:[self objectWithID:objectID]];
}
NSArray* objectArray = [NSArray arrayWithArray:objects];
[objects release];
return objectArray;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectStore.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectThreadSafeInvocation.h
//
// RKManagedObjectThreadSafeInvocation.h
// RestKit
//
// Created by Blake Watters on 5/12/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectStore.h”
@interface RKManagedObjectThreadSafeInvocation : NSInvocation {
NSMutableDictionary* _argumentKeyPaths;
RKManagedObjectStore* _objectStore;
}
@property (nonatomic, retain) RKManagedObjectStore* objectStore;
+ (RKManagedObjectThreadSafeInvocation*)invocationWithMethodSignature:(NSMethodSignature*)methodSignature;
– (void)setManagedObjectKeyPaths:(NSSet*)keyPaths forArgument:(NSInteger)index;
– (void)invokeOnMainThread;
// Private
– (void)serializeManagedObjectsForArgument:(id)argument withKeyPaths:(NSSet*)keyPaths;
– (void)deserializeManagedObjectIDsForArgument:(id)argument withKeyPaths:(NSSet*)keyPaths;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectThreadSafeInvocation.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKManagedObjectThreadSafeInvocation.m
//
// RKManagedObjectThreadSafeInvocation.m
// RestKit
//
// Created by Blake Watters on 5/12/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKManagedObjectThreadSafeInvocation.h”
@implementation RKManagedObjectThreadSafeInvocation
@synthesize objectStore = _objectStore;
+ (RKManagedObjectThreadSafeInvocation*)invocationWithMethodSignature:(NSMethodSignature*)methodSignature {
return (RKManagedObjectThreadSafeInvocation*) [super invocationWithMethodSignature:methodSignature];
}
– (void)setManagedObjectKeyPaths:(NSSet*)keyPaths forArgument:(NSInteger)index {
if (nil == _argumentKeyPaths) {
_argumentKeyPaths = [[NSMutableDictionary alloc] init];
}
NSNumber* argumentIndex = [NSNumber numberWithInteger:index];
[_argumentKeyPaths setObject:keyPaths forKey:argumentIndex];
}
– (void)setValue:(id)value forKeyPathOrKey:(NSString *)keyPath object:(id)object {
[object setValue:value forKeyPath:keyPath];
id testValue = [object valueForKeyPath:keyPath];
if (![value isEqual:testValue]) {
[object setValue:value forKey:keyPath];
testValue = [object valueForKeyPath:keyPath];
NSAssert([value isEqual:testValue], @”Could not set value”);
}
}
– (void)serializeManagedObjectsForArgument:(id)argument withKeyPaths:(NSSet*)keyPaths {
for (NSString* keyPath in keyPaths) {
id value = [argument valueForKeyPath:keyPath];
if ([value isKindOfClass:[NSManagedObject class]]) {
NSManagedObjectID *objectID = [(NSManagedObject*)value objectID];
[self setValue:objectID forKeyPathOrKey:keyPath object:argument];
} else if ([value respondsToSelector:@selector(allObjects)]) {
id collection = [[[[[value class] alloc] init] autorelease] mutableCopy];
for (id subObject in value) {
if ([subObject isKindOfClass:[NSManagedObject class]]) {
[collection addObject:[(NSManagedObject*)subObject objectID]];
} else {
[collection addObject:subObject];
}
}
[self setValue:collection forKeyPathOrKey:keyPath object:argument];
[collection release];
}
}
}
– (void)deserializeManagedObjectIDsForArgument:(id)argument withKeyPaths:(NSSet*)keyPaths {
for (NSString* keyPath in keyPaths) {
id value = [argument valueForKeyPath:keyPath];
if ([value isKindOfClass:[NSManagedObjectID class]]) {
NSAssert(self.objectStore, @”Object store cannot be nil”);
NSManagedObject* managedObject = [self.objectStore objectWithID:(NSManagedObjectID*)value];
NSAssert(managedObject, @”Expected managed object for ID %@, got nil”, value);
[self setValue:managedObject forKeyPathOrKey:keyPath object:argument];
} else if ([value respondsToSelector:@selector(allObjects)]) {
id collection = [[[[[value class] alloc] init] autorelease] mutableCopy];
for (id subObject in value) {
if ([subObject isKindOfClass:[NSManagedObjectID class]]) {
NSAssert(self.objectStore, @”Object store cannot be nil”);
NSManagedObject* managedObject = [self.objectStore objectWithID:(NSManagedObjectID*)subObject];
[collection addObject:managedObject];
} else {
[collection addObject:subObject];
}
}
[self setValue:collection forKeyPathOrKey:keyPath object:argument];
[collection release];
}
}
}
– (void)serializeManagedObjects {
for (NSNumber* argumentIndex in _argumentKeyPaths) {
NSSet* managedKeyPaths = [_argumentKeyPaths objectForKey:argumentIndex];
id argument = nil;
[self getArgument:&argument atIndex:[argumentIndex intValue]];
if (argument) {
[self serializeManagedObjectsForArgument:argument withKeyPaths:managedKeyPaths];
}
}
}
– (void)deserializeManagedObjects {
for (NSNumber* argumentIndex in _argumentKeyPaths) {
NSSet* managedKeyPaths = [_argumentKeyPaths objectForKey:argumentIndex];
id argument = nil;
[self getArgument:&argument atIndex:[argumentIndex intValue]];
if (argument) {
[self deserializeManagedObjectIDsForArgument:argument withKeyPaths:managedKeyPaths];
}
}
}
– (void)performInvocationOnMainThread {
[self deserializeManagedObjects];
[self invoke];
}
– (void)invokeOnMainThread {
[self retain];
[self serializeManagedObjects];
[self performSelectorOnMainThread:@selector(performInvocationOnMainThread) withObject:nil waitUntilDone:YES];
[self release];
}
– (void)dealloc {
[_argumentKeyPaths release];
[_objectStore release];
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKManagedObjectThreadSafeInvocation.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKObjectMappingProvider+CoreData.h
//
// RKObjectMappingProvider+CoreData.h
// RestKit
//
// Created by Jeff Arena on 1/26/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectMappingProvider.h”
#import
typedef NSFetchRequest *(^RKObjectMappingProviderFetchRequestBlock)(NSString *resourcePath);
/**
Provides extensions to RKObjectMappingProvider to support Core Data specific
functionality.
*/
@interface RKObjectMappingProvider (CoreData)
/**
Configures an object mapping to be used when during a load event where the resourcePath of
the RKObjectLoader instance matches resourcePathPattern.
The resourcePathPattern is a SOCKit pattern matching property names preceded by colons within
a path. For example, if a collection of reviews for a product were loaded from a remote system
at the resourcePath @”/products/1234/reviews”, object mapping could be configured to handle
this request with a resourcePathPattern of @”/products/:productID/reviews”.
**NOTE** that care must be taken when configuring patterns within the provider. The patterns
will be evaluated in the order they are added to the provider, so more specific patterns must
precede more general patterns where either would generate a match.
@param objectMapping The object mapping to use when the resourcePath matches the specified
resourcePathPattern.
@param resourcePathPattern A pattern to be evaluated using an RKPathMatcher against a resourcePath
to determine if objectMapping is the appropriate mapping.
@param fetchRequestBlock A block that accepts an individual resourcePath and returns an NSFetchRequest
that should be used to fetch the local objects associated with resourcePath from CoreData, for use in
properly processing local deletes
@see RKPathMatcher
@see RKURL
@see RKObjectLoader
*/
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectMapping forResourcePathPattern:(NSString *)resourcePathPattern withFetchRequestBlock:(RKObjectMappingProviderFetchRequestBlock)fetchRequestBlock;
/**
Retrieves the NSFetchRequest object that will retrieve cached objects for a given resourcePath.
@param resourcePath A resourcePath to retrieve the fetch request for.
@return An NSFetchRequest object for fetching objects for the given resource path or nil.
*/
– (NSFetchRequest *)fetchRequestForResourcePath:(NSString *)resourcePath;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKObjectMappingProvider+CoreData.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKObjectMappingProvider+CoreData.m
//
// RKObjectMappingProvider+CoreData.m
// RestKit
//
// Created by Jeff Arena on 1/26/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectMappingProvider+CoreData.h”
#import “RKOrderedDictionary.h”
#import “RKFixCategoryBug.h”
RK_FIX_CATEGORY_BUG(RKObjectMappingProvider_CoreData)
@implementation RKObjectMappingProvider (CoreData)
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectMapping forResourcePathPattern:(NSString *)resourcePath withFetchRequestBlock:(RKObjectMappingProviderFetchRequestBlock)fetchRequestBlock {
[self setEntry:[RKObjectMappingProviderContextEntry contextEntryWithMapping:objectMapping
userData:Block_copy(fetchRequestBlock)] forResourcePathPattern:resourcePath];
}
– (NSFetchRequest *)fetchRequestForResourcePath:(NSString *)resourcePath {
RKObjectMappingProviderContextEntry *entry = [self entryForResourcePath:resourcePath];
if (entry.userData) {
NSFetchRequest *(^fetchRequestBlock)(NSString *) = entry.userData;
return fetchRequestBlock(resourcePath);
}
return nil;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKObjectMappingProvider+CoreData.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKObjectPropertyInspector+CoreData.h
//
// RKObjectPropertyInspector+CoreData.h
// RestKit
//
// Created by Blake Watters on 8/14/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectPropertyInspector.h”
@interface RKObjectPropertyInspector (CoreData)
– (NSDictionary *)propertyNamesAndTypesForEntity:(NSEntityDescription*)entity;
/**
Returns the Class type of the specified property on the object class
*/
– (Class)typeForProperty:(NSString*)propertyName ofEntity:(NSEntityDescription*)entity;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKObjectPropertyInspector+CoreData.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKObjectPropertyInspector+CoreData.m
//
// RKObjectPropertyInspector+CoreData.m
// RestKit
//
// Created by Blake Watters on 8/14/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectPropertyInspector+CoreData.h”
#import “RKLog.h”
#import “RKFixCategoryBug.h”
#import
RK_FIX_CATEGORY_BUG(RKObjectPropertyInspector_CoreData)
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
@implementation RKObjectPropertyInspector (CoreData)
– (NSDictionary *)propertyNamesAndTypesForEntity:(NSEntityDescription*)entity {
NSMutableDictionary* propertyNamesAndTypes = [_cachedPropertyNamesAndTypes objectForKey:[entity name]];
if (propertyNamesAndTypes) {
return propertyNamesAndTypes;
}
propertyNamesAndTypes = [NSMutableDictionary dictionary];
for (NSString* name in [entity attributesByName]) {
NSAttributeDescription* attributeDescription = [[entity attributesByName] valueForKey:name];
if ([attributeDescription attributeValueClassName]) {
[propertyNamesAndTypes setValue:NSClassFromString([attributeDescription attributeValueClassName]) forKey:name];
} else if ([attributeDescription attributeType] == NSTransformableAttributeType &&
![name isEqualToString:@”_mapkit_hasPanoramaID”]) {
const char* className = [[entity managedObjectClassName] cStringUsingEncoding:NSUTF8StringEncoding];
const char* propertyName = [name cStringUsingEncoding:NSUTF8StringEncoding];
Class managedObjectClass = objc_getClass(className);
// property_getAttributes() returns everything we need to implement this…
// See: http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW5
objc_property_t prop = class_getProperty(managedObjectClass, propertyName);
NSString* attributeString = [NSString stringWithCString:property_getAttributes(prop) encoding:NSUTF8StringEncoding];
const char* destinationClassName = [[RKObjectPropertyInspector propertyTypeFromAttributeString:attributeString] cStringUsingEncoding:NSUTF8StringEncoding];
Class destinationClass = objc_getClass(destinationClassName);
if (destinationClass) {
[propertyNamesAndTypes setObject:destinationClass forKey:name];
}
}
}
for (NSString* name in [entity relationshipsByName]) {
NSRelationshipDescription* relationshipDescription = [[entity relationshipsByName] valueForKey:name];
if ([relationshipDescription isToMany]) {
[propertyNamesAndTypes setValue:[NSSet class] forKey:name];
} else {
NSEntityDescription* destinationEntity = [relationshipDescription destinationEntity];
Class destinationClass = NSClassFromString([destinationEntity managedObjectClassName]);
[propertyNamesAndTypes setValue:destinationClass forKey:name];
}
}
[_cachedPropertyNamesAndTypes setObject:propertyNamesAndTypes forKey:[entity name]];
RKLogDebug(@”Cached property names and types for Entity ‘%@’: %@”, entity, propertyNamesAndTypes);
return propertyNamesAndTypes;
}
– (Class)typeForProperty:(NSString*)propertyName ofEntity:(NSEntityDescription*)entity {
return [[self propertyNamesAndTypesForEntity:entity] valueForKey:propertyName];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKObjectPropertyInspector+CoreData.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchableManagedObject.h
//
// RKSearchableManagedObject.h
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSManagedObject+ActiveRecord.h”
#import “RKManagedObjectSearchEngine.h”
@class RKSearchWord;
/**
RKSearchableManagedObject provides an abstract base class for Core Data entities
that are searchable using the RKManagedObjectSearchEngine interface. The collection of
search words is maintained by the RKSearchWordObserver singleton at managed object context
save time.
@see RKSearchWord
@see RKSearchWordObserver
@see RKManagedObjectSearchEngine
*/
@interface RKSearchableManagedObject : NSManagedObject
///—————————————————————————–
/// @name Configuring Searchable Attributes
///—————————————————————————–
/**
Returns an array of attributes which should be processed by the search word observer to
build the set of search words for entities with the type of the receiver. Subclasses must
provide an implementation for indexing to occur as the base implementation returns an empty
array.
@warning *NOTE*: May only include attributes property names, not key paths.
@return An array of attribute names containing searchable textual content for entities with the type of the receiver.
@see RKSearchWordObserver
@see searchWords
*/
+ (NSArray *)searchableAttributes;
///—————————————————————————–
/// @name Obtaining a Search Predicate
///—————————————————————————–
/**
A predicate that will search for the specified text with the specified mode. Mode can be
configured to be RKSearchModeAnd or RKSearchModeOr.
@return A predicate that will search for the specified text with the specified mode.
@see RKSearchMode
*/
+ (NSPredicate *)predicateForSearchWithText:(NSString *)searchText searchMode:(RKSearchMode)mode;
///—————————————————————————–
/// @name Managing the Search Words
///—————————————————————————–
/**
The set of tokenized search words contained in the receiver.
*/
@property (nonatomic, retain) NSSet *searchWords;
/**
Rebuilds the set of tokenized search words associated with the receiver by processing the
searchable attributes and tokenizing the contents into RKSearchWord instances.
@see [RKSearchableManagedObject searchableAttributes]
*/
– (void)refreshSearchWords;
@end
@interface RKSearchableManagedObject (SearchWordsAccessors)
/**
Adds a search word object to the receiver’s set of search words.
@param searchWord The search word to be added to the set of search words.
*/
– (void)addSearchWordsObject:(RKSearchWord *)searchWord;
/**
Removes a search word object from the receiver’s set of search words.
@param searchWord The search word to be removed from the receiver’s set of search words.
*/
– (void)removeSearchWordsObject:(RKSearchWord *)searchWord;
/**
Adds a set of search word objects to the receiver’s set of search words.
@param searchWords The set of search words to be added to receiver’s the set of search words.
*/
– (void)addSearchWords:(NSSet *)searchWords;
/**
Removes a set of search word objects from the receiver’s set of search words.
@param searchWords The set of search words to be removed from receiver’s the set of search words.
*/
– (void)removeSearchWords:(NSSet *)searchWords;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchableManagedObject.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchableManagedObject.m
//
// RKSearchableManagedObject.m
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKSearchableManagedObject.h”
#import “CoreData.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreDataSearchEngine
@implementation RKSearchableManagedObject
@dynamic searchWords;
+ (NSArray *)searchableAttributes
{
return [NSArray array];
}
+ (NSPredicate *)predicateForSearchWithText:(NSString *)searchText searchMode:(RKSearchMode)mode
{
if (searchText == nil) {
return nil;
} else {
RKManagedObjectSearchEngine *searchEngine = [RKManagedObjectSearchEngine searchEngine];
searchEngine.mode = mode;
return [searchEngine predicateForSearch:searchText];
}
}
– (void)refreshSearchWords
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
RKLogDebug(@”Refreshing search words for %@ %@”, NSStringFromClass([self class]), [self objectID]);
NSMutableSet *searchWords = [NSMutableSet set];
for (NSString *searchableAttribute in [[self class] searchableAttributes]) {
NSString *attributeValue = [self valueForKey:searchableAttribute];
if (attributeValue) {
RKLogTrace(@”Generating search words for searchable attribute: %@”, searchableAttribute);
NSArray *attributeValueWords = [RKManagedObjectSearchEngine tokenizedNormalizedString:attributeValue];
for (NSString *word in attributeValueWords) {
if (word && [word length] > 0) {
RKSearchWord *searchWord = [RKSearchWord findFirstByAttribute:RKSearchWordPrimaryKeyAttribute
withValue:word
inContext:self.managedObjectContext];
if (! searchWord) {
searchWord = [RKSearchWord createInContext:self.managedObjectContext];
}
searchWord.word = word;
[searchWords addObject:searchWord];
}
}
}
}
self.searchWords = searchWords;
RKLogTrace(@”Generating searchWords: %@”, [searchWords valueForKey:RKSearchWordPrimaryKeyAttribute]);
[pool drain];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchableManagedObject.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchWord.h
//
// RKSearchWord.m
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSManagedObject+ActiveRecord.h”
#import “RKSearchableManagedObject.h”
extern NSString * const RKSearchWordPrimaryKeyAttribute;
@interface RKSearchWord : NSManagedObject
@property (nonatomic, retain) NSString* word;
@property (nonatomic, retain) NSSet* searchableManagedObjects;
@end
@interface RKSearchWord (SearchableManagedObjectsAccessors)
– (void)addSearchableManagedObjectsObject:(RKSearchableManagedObject*)searchableManagedObject;
– (void)removeSearchableManagedObjectsObject:(RKSearchableManagedObject*)searchableManagedObject;
– (void)addSearchableManagedObjects:(NSSet*)searchableManagedObjects;
– (void)removeSearchableManagedObjects:(NSSet*)searchableManagedObjects;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchWord.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchWord.m
//
// RKSearchWord.m
// RestKit
//
// Created by Jeff Arena on 3/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKSearchWord.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreData
NSString * const RKSearchWordPrimaryKeyAttribute = @”word”;
@implementation RKSearchWord
@dynamic word;
@dynamic searchableManagedObjects;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchWord.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchWordObserver.h
//
// RKSearchWordObserver.h
// RestKit
//
// Created by Blake Watters on 7/25/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
Provides an observer responsible for initiating refresh of searchable
Core Data attributes at managed object context save time.
*/
@interface RKSearchWordObserver : NSObject
/**
Returns the shared observer
*/
+ (RKSearchWordObserver *)sharedObserver;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchWordObserver.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/RKSearchWordObserver.m
//
// RKSearchWordObserver.m
// RestKit
//
// Created by Blake Watters on 7/25/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import “RKSearchWordObserver.h”
#import “RKSearchableManagedObject.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitCoreDataSearchEngine
static RKSearchWordObserver *sharedSearchWordObserver = nil;
@implementation RKSearchWordObserver
+ (RKSearchWordObserver *)sharedObserver {
if (! sharedSearchWordObserver) {
sharedSearchWordObserver = [[RKSearchWordObserver alloc] init];
}
return sharedSearchWordObserver;
}
– (id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextWillSaveNotification:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
}
return self;
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
– (void)managedObjectContextWillSaveNotification:(NSNotification *)notification {
NSManagedObjectContext *context = [notification object];
NSSet *candidateObjects = [[NSSet setWithSet:context.insertedObjects] setByAddingObjectsFromSet:context.updatedObjects];
RKLogDebug(@”Managed object context will save notification received. Checking changed and inserted objects for searchable entities…”);
for (NSManagedObject *object in candidateObjects) {
if (! [object isKindOfClass:[RKSearchableManagedObject class]]) {
RKLogTrace(@”Skipping search words refresh for entity of type ‘%@’: not searchable.”, NSStringFromClass([object class]));
continue;
}
NSArray *searchableAttributes = [[object class] searchableAttributes];
for (NSString *attribute in searchableAttributes) {
if ([[object changedValues] objectForKey:attribute]) {
RKLogDebug(@”Detected change to searchable attribute ‘%@’ for %@ entity: refreshing search words.”, attribute, NSStringFromClass([object class]));
[(RKSearchableManagedObject *)object refreshSearchWords];
break;
}
}
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/CoreData/._RKSearchWordObserver.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._CoreData
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/Network.h
//
// Network.h
// RestKit
//
// Created by Blake Watters on 9/30/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKClient.h”
#import “RKURL.h”
#import “RKRequest.h”
#import “RKResponse.h”
#import “RKRequestSerializable.h”
#import “RKReachabilityObserver.h”
#import “RKRequestQueue.h”
#import “RKNotifications.h”
#import “RKOAuthClient.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._Network.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSData+RKAdditions.h
//
// NSData+RKAdditions.h
// RestKit
//
// Created by Jeff Arena on 4/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
Provides extensions to NSData for various common tasks.
*/
@interface NSData (RKAdditions)
/**
Returns a string of the MD5 sum of the receiver.
@return A new string containing the MD5 sum of the receiver.
*/
– (NSString *)MD5;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSData+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSData+RKAdditions.m
//
// NSData+MD5.m
// RestKit
//
// Created by Jeff Arena on 4/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “NSData+RKAdditions.h”
#import “RKFixCategoryBug.h”
RK_FIX_CATEGORY_BUG(NSData_RKAdditions)
@implementation NSData (RKAdditions)
– (NSString *)MD5 {
// Create byte array of unsigned chars
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
// Create 16 byte MD5 hash value, store in buffer
CC_MD5(self.bytes, (CC_LONG) self.length, md5Buffer);
// Convert unsigned char buffer to NSString of hex values
NSMutableString* output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x",md5Buffer[i]];
}
return output;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSData+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSDictionary+RKRequestSerialization.h
//
// NSDictionary+RKRequestSerialization.h
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKRequestSerializable.h”
/*
Extends NSDictionary to enable usage as the params of an RKRequest.
This category provides for the serialization of the receiving NSDictionary into a URL
encoded string representation (MIME Type application/x-www-form-urlencoded). This
enables NSDictionary objects to act as the params for an RKRequest.
@see RKRequestSerializable
@see [RKRequest params]
@class NSDictionary (RKRequestSerialization)
*/
@interface NSDictionary (RKRequestSerialization)
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSDictionary+RKRequestSerialization.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSDictionary+RKRequestSerialization.m
//
// NSDictionary+RKRequestSerialization.m
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSDictionary+RKRequestSerialization.h”
#import “NSDictionary+RKAdditions.h”
#import “RKFixCategoryBug.h”
#import “RKMIMETypes.h”
RK_FIX_CATEGORY_BUG(NSDictionary_RKRequestSerialization)
@implementation NSDictionary (RKRequestSerialization)
– (NSString *)HTTPHeaderValueForContentType
{
return RKMIMETypeFormURLEncoded;
}
– (NSData *)HTTPBody
{
return [[self URLEncodedString] dataUsingEncoding:NSUTF8StringEncoding];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSDictionary+RKRequestSerialization.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSObject+URLEncoding.h
//
// NSObject+URLEncoding.h
// RestKit
//
// Created by Jeff Arena on 7/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
@interface NSObject (URLEncoding)
/**
* Returns a representation of the object as a URLEncoded string
*
* @returns A UTF-8 encoded string representation of the object
*/
– (NSString*)URLEncodedString;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSObject+URLEncoding.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/NSObject+URLEncoding.m
//
// NSObject+URLEncoding.m
// RestKit
//
// Created by Jeff Arena on 7/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “NSObject+URLEncoding.h”
@implementation NSObject (URLEncoding)
– (NSString*)URLEncodedString {
NSString *string = [NSString stringWithFormat:@”%@”, self];
NSString *encodedString = (NSString*)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)string,
NULL,
(CFStringRef)@”!*'();:@&=+$,/?%#[]”,
kCFStringEncodingUTF8);
return [encodedString autorelease];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._NSObject+URLEncoding.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKClient.h
//
// RKClient.h
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKURL.h”
#import “RKRequest.h”
#import “RKParams.h”
#import “RKResponse.h”
#import “NSDictionary+RKRequestSerialization.h”
#import “RKReachabilityObserver.h”
#import “RKRequestCache.h”
#import “RKRequestQueue.h”
#import “RKConfigurationDelegate.h”
/**
RKClient exposes the low level client interface for working with HTTP servers
and RESTful services. It wraps the request/response cycle with a clean, simple
interface.
RKClient can be thought of as analogous to a web browser or other HTTP user
agent. The client’s primary purpose is to configure and dispatch requests to a
remote service for processing in a global way. When working with the Network
layer, a user will generally construct and dispatch all RKRequest objects via
the interfaces exposed by RKClient.
### Base URL and Resource Paths
Core to an effective utilization of RKClient is an understanding of the Base
URL and Resource Path concepts. The Base URL forms the common beginning part of
a complete URL string that is used to access a remote web service. RKClient
instances are configured with a Base URL and all requests dispatched through
the client will be sent to a URL consisting of the base URL plus the resource
path specified. The resource path is simply the remaining part of the URL once
all common text is removed.
For example, given a remote web service at `http://restkit.org` and RESTful
services at `http://restkit.org/services` and `http://restkit.org/objects`, our
base URL would be `http://restkit.org` and we would have resource paths of
`/services` and `/objects`.
Base URLs simplify interaction with remote services by freeing us from having
to interpolate strings and construct NSURL objects to get work done. We are
also able to quickly retarget an entire application to a different server or
API version by changing the base URL. This is commonly done via conditional
compilation to create builds against a staging and production server, for
example.
### Memory Management
Note that memory management of requests sent via RKClient instances are
automatically managed for you. When sent, the request is retained by the
requestQueue and is released when all request processing has completed.
Generally speaking this means that you can dispatch requests and work with the
response in the delegate methods without regard for memory management.
### Request Serialization
RKClient and RKRequest support the serialization of objects into payloads to be
sent as the body of a request. This functionality is commonly used to provide a
dictionary of simple values to be encoded and sent as a form encoding with POST
and PUT operations. It is worth noting however that this functionality is
provided via the RKRequestSerializable protocol and is not specific to
NSDictionary objects.
### Sending Asynchronous Requests
A handful of methods are provided as a convenience to cover the common
asynchronous request tasks. All other request needs should instantiate a
request via [RKClient requestWithResourcePath:] and work with the RKRequest
object directly.
@see RKRequest
@see RKResponse
@see RKRequestQueue
@see RKRequestSerializable
*/
@interface RKClient : NSObject
RKURL *_baseURL;
RKRequestAuthenticationType _authenticationType;
NSString *_username;
NSString *_password;
NSString *_OAuth1ConsumerKey;
NSString *_OAuth1ConsumerSecret;
NSString *_OAuth1AccessToken;
NSString *_OAuth1AccessTokenSecret;
NSString *_OAuth2AccessToken;
NSString *_OAuth2RefreshToken;
NSMutableDictionary *_HTTPHeaders;
RKReachabilityObserver *_reachabilityObserver;
NSString *_serviceUnavailableAlertTitle;
NSString *_serviceUnavailableAlertMessage;
BOOL _serviceUnavailableAlertEnabled;
RKRequestQueue *_requestQueue;
RKRequestCache *_requestCache;
RKRequestCachePolicy _cachePolicy;
NSMutableSet *_additionalRootCertificates;
BOOL _disableCertificateValidation;
NSStringEncoding _defaultHTTPEncoding;
NSString *_runLoopMode;
// Queue suspension flags
BOOL _awaitingReachabilityDetermination;
}
///—————————————————————————–
/// @name Initializing a Client
///—————————————————————————–
/**
Returns a client scoped to a particular base URL.
If the singleton client is nil, the return client is set as the singleton.
@see baseURL
@param baseURL The baseURL to set for the client. All requests will be relative
to this base URL.
@return A configured RKClient instance ready to send requests
*/
+ (RKClient *)clientWithBaseURL:(NSURL *)baseURL;
/**
Returns a client scoped to a particular base URL.
If the singleton client is nil, the return client is set as the singleton.
@see baseURL
@param baseURLString The string to use to construct the NSURL to set the
baseURL. All requests will be relative to this base URL.
@return A configured RKClient instance ready to send requests
*/
+ (RKClient *)clientWithBaseURLString:(NSString *)baseURLString;
/**
Returns a Rest client scoped to a particular base URL with a set of HTTP AUTH
credentials.
If the singleton client is nil, the return client is set as the singleton.
@bug **DEPRECATED** in version 0.9.4: Use [RKClient clientWithBaseURLString:]
and set username and password afterwards.
@param baseURL The baseURL to set for the client. All requests will be relative
to this base URL.
@param username The username to use for HTTP Authentication challenges
@param password The password to use for HTTP Authentication challenges
@return A configured RKClient instance ready to send requests
*/
+ (RKClient *)clientWithBaseURL:(NSString *)baseURL username:(NSString *)username password:(NSString *)password DEPRECATED_ATTRIBUTE;
/**
Returns a client scoped to a particular base URL. If the singleton client is
nil, the return client is set as the singleton.
@see baseURL
@param baseURL The baseURL to set for the client. All requests will be relative
to this base URL.
@return A configured RKClient instance ready to send requests
*/
– (id)initWithBaseURL:(NSURL *)baseURL;
/**
Returns a client scoped to a particular base URL. If the singleton client is
nil, the return client is set as the singleton.
@see baseURL
@param baseURLString The string to use to construct the NSURL to set the
baseURL. All requests will be relative to this base URL.
@return A configured RKClient instance ready to send requests
*/
– (id)initWithBaseURLString:(NSString *)baseURLString;
///—————————————————————————–
/// @name Configuring the Client
///—————————————————————————–
/**
The base URL all resources are nested underneath. All requests created through
the client will their URL built by appending a resourcePath to the baseURL to
form a complete URL.
Changing the baseURL has the side-effect of causing the requestCache instance
to be rebuilt. Caches are maintained a per-host basis.
@see requestCache
*/
@property (nonatomic, retain) RKURL *baseURL;
/**
A dictionary of headers to be sent with each request
*/
@property (nonatomic, retain, readonly) NSMutableDictionary *HTTPHeaders;
/**
An optional timeout interval within which the request should be cancelled.
This is passed along to RKRequest if set. If it isn’t set, it will default
to RKRequest’s default timeoutInterval.
*Default*: Falls through to RKRequest’s timeoutInterval
*/
@property (nonatomic, assign) NSTimeInterval timeoutInterval;
/**
The request queue to push asynchronous requests onto.
*Default*: A new request queue is instantiated for you during init.
*/
@property (nonatomic, retain) RKRequestQueue *requestQueue;
/**
The run loop mode under which the underlying NSURLConnection is performed
*Default*: NSRunLoopCommonModes
*/
@property (nonatomic, copy) NSString *runLoopMode;
/**
The default value used to decode HTTP body content when HTTP headers received do not provide information on the content.
This encoding will be used by the RKResponse when creating the body content
*/
@property (nonatomic, assign) NSStringEncoding defaultHTTPEncoding;
/**
Adds an HTTP header to each request dispatched through the client
@param value The string value to set for the HTTP header
@param header The HTTP header to add
@see HTTPHeaders
*/
– (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)header;
///—————————————————————————–
/// @name Handling SSL Validation
///—————————————————————————–
/**
Flag for disabling SSL certificate validation.
*Default*: NO
@warning **WARNING**: This is a potential security exposure and should be used
**ONLY while debugging** in a controlled environment.
*/
@property (nonatomic, assign) BOOL disableCertificateValidation;
/**
A set of additional certificates to be used in evaluating server SSL
certificates.
*/
@property (nonatomic, retain, readonly) NSSet *additionalRootCertificates;
/**
Adds an additional certificate that will be used to evaluate server SSL certs.
@param cert The SecCertificateRef to add to the list of additional SSL certs.
@see additionalRootCertificates
*/
– (void)addRootCertificate:(SecCertificateRef)cert;
///—————————————————————————–
/// @name Authentication
///—————————————————————————–
/**
The type of authentication to use for this request.
This must be assigned one of the following:
– `RKRequestAuthenticationTypeNone`: Disable the use of authentication
– `RKRequestAuthenticationTypeHTTP`: Use NSURLConnection’s HTTP AUTH
auto-negotiation
– `RKRequestAuthenticationTypeHTTPBasic`: Force the use of HTTP Basic
authentication. This will supress AUTH challenges as RestKit will add an
Authorization header establishing login via HTTP basic. This is an
optimization that skips the challenge portion of the request.
– `RKRequestAuthenticationTypeOAuth1`: Enable the use of OAuth 1.0
authentication. OAuth1ConsumerKey, OAuth1ConsumerSecret, OAuth1AccessToken,
and OAuth1AccessTokenSecret must be set.
– `RKRequestAuthenticationTypeOAuth2`: Enable the use of OAuth 2.0
authentication. OAuth2AccessToken must be set.
**Default**: RKRequestAuthenticationTypeNone
*/
@property (nonatomic, assign) RKRequestAuthenticationType authenticationType;
/**
The username to use for authentication via HTTP AUTH.
Used to respond to an authentication challenge when authenticationType is
RKRequestAuthenticationTypeHTTP or RKRequestAuthenticationTypeHTTPBasic.
@see authenticationType
*/
@property (nonatomic, retain) NSString *username;
/**
The password to use for authentication via HTTP AUTH.
Used to respond to an authentication challenge when authenticationType is
RKRequestAuthenticationTypeHTTP or RKRequestAuthenticationTypeHTTPBasic.
@see authenticationType
*/
@property (nonatomic, retain) NSString *password;
///—————————————————————————–
/// @name OAuth1 Secrets
///—————————————————————————–
/**
The OAuth 1.0 consumer key
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1ConsumerKey;
/**
The OAuth 1.0 consumer secret
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1ConsumerSecret;
/**
The OAuth 1.0 access token
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1AccessToken;
/**
The OAuth 1.0 access token secret
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1AccessTokenSecret;
///—————————————————————————–
/// @name OAuth2 Secrets
///—————————————————————————–
/**
The OAuth 2.0 access token
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth2
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth2AccessToken;
/**
The OAuth 2.0 refresh token
Used to retrieve a new access token before expiration and to build an
Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth2
@bug **NOT IMPLEMENTED**: This functionality is not yet implemented.
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth2RefreshToken;
///—————————————————————————–
/// @name Reachability & Service Availability Alerting
///—————————————————————————–
/**
An instance of RKReachabilityObserver used for determining the availability of
network access.
Initialized using [RKReachabilityObserver reachabilityObserverForInternet] to
monitor connectivity to the Internet. Can be changed to directly monitor a
remote hostname/IP address or the local WiFi interface instead.
@warning **WARNING**: Changing the reachability observer has the side-effect of
temporarily suspending the requestQueue until reachability to the new host can
be established.
@see RKReachabilityObserver
*/
@property (nonatomic, retain) RKReachabilityObserver *reachabilityObserver;
/**
The title to use in the alert shown when a request encounters a
ServiceUnavailable (503) response.
*Default*: _”Service Unavailable”_
*/
@property (nonatomic, retain) NSString *serviceUnavailableAlertTitle;
/**
The message to use in the alert shown when a request encounters a
ServiceUnavailable (503) response.
*Default*: _”The remote resource is unavailable. Please try again later.”_
*/
@property (nonatomic, retain) NSString *serviceUnavailableAlertMessage;
/**
Flag that determines whether the Service Unavailable alert is shown in response
to a ServiceUnavailable (503) response.
*Default*: _NO_
*/
@property (nonatomic, assign) BOOL serviceUnavailableAlertEnabled;
///—————————————————————————–
/// @name Reachability helpers
///—————————————————————————–
/**
Convenience method for returning the current reachability status from the
reachabilityObserver.
Equivalent to executing `[RKClient isNetworkReachable]` on the sharedClient
@see RKReachabilityObserver
@return YES if the remote host is accessible
*/
– (BOOL)isNetworkReachable;
/**
Convenience method for returning the current reachability status from the
reachabilityObserver.
@bug **DEPRECATED** in v0.10.0: Use [RKClient isNetworkReachable]
@see RKReachabilityObserver
@return YES if the remote host is accessible
*/
– (BOOL)isNetworkAvailable DEPRECATED_ATTRIBUTE;
///—————————————————————————–
/// @name Caching
///—————————————————————————–
/**
An instance of the request cache used to store/load cacheable responses for
requests sent through this client
@bug **DEPRECATED** in v0.10.0: Use requestCache instead.
*/
@property (nonatomic, retain) RKRequestCache *cache DEPRECATED_ATTRIBUTE;
/**
An instance of the request cache used to store/load cacheable responses for
requests sent through this client
*/
@property (nonatomic, retain) RKRequestCache *requestCache;
/**
The timeout interval within which the requests should not be sent and the
cached response should be used.
This is only used if the cache policy includes RKRequestCachePolicyTimeout.
*/
@property (nonatomic, assign) NSTimeInterval cacheTimeoutInterval;
/**
The default cache policy to apply for all requests sent through this client
This must be assigned one of the following:
– `RKRequestCachePolicyNone`: Never use the cache.
– `RKRequestCachePolicyLoadIfOffline`: Load from the cache when offline.
– `RKRequestCachePolicyLoadOnError`: Load from the cache if an error is
encountered.
– `RKRequestCachePolicyEtag`: Load from the cache if there is data stored and
the server returns a 304 (Not Modified) response.
– `RKRequestCachePolicyEnabled`: Load from the cache whenever data has been
stored.
– `RKRequestCachePolicyTimeout`: Load from the cache if the
cacheTimeoutInterval is reached before the server responds.
@see RKRequest
*/
@property (nonatomic, assign) RKRequestCachePolicy cachePolicy;
/**
The path used to store response data for this client’s request cache.
The path that is used is the device’s cache directory with
`RKClientRequestCache-host` appended.
*/
@property (nonatomic, readonly) NSString *cachePath;
///—————————————————————————–
/// @name Shared Client Instance
///—————————————————————————–
/**
Returns the shared instance of the client
*/
+ (RKClient *)sharedClient;
/**
Sets the shared instance of the client, releasing the current instance (if any)
@param client An RKClient instance to configure as the new shared instance
*/
+ (void)setSharedClient:(RKClient *)client;
///—————————————————————————–
/// @name Building Requests
///—————————————————————————–
/**
Return a request object targetted at a resource path relative to the base URL.
By default the method is set to GET. All headers set on the client will
automatically be applied to the request as well.
@bug **DEPRECATED** in v0.10.0: Use [RKClient requestWithResourcePath:] instead.
@param resourcePath The resource path to configure the request for.
@param delegate A delegate to inform of events in the request lifecycle.
@return A fully configured RKRequest instance ready for sending.
@see RKRequestDelegate
*/
– (RKRequest *)requestWithResourcePath:(NSString *)resourcePath delegate:(NSObject
/**
Return a request object targeted at a resource path relative to the base URL.
By default the method is set to GET. All headers set on the client will
automatically be applied to the request as well.
@param resourcePath The resource path to configure the request for.
@return A fully configured RKRequest instance ready for sending.
@see RKRequestDelegate
*/
– (RKRequest *)requestWithResourcePath:(NSString *)resourcePath;
///—————————————————————————–
/// @name Sending Asynchronous Requests
///—————————————————————————–
/**
Perform an asynchronous GET request for a resource and inform a delegate of the
results.
@param resourcePath The resourcePath to target the request at
@param delegate A delegate object to inform of the results
@return The RKRequest object built and sent to the remote system
*/
– (RKRequest *)get:(NSString *)resourcePath delegate:(NSObject
/**
Fetch a resource via an HTTP GET with a dictionary of params.
This request _only_ allows NSDictionary objects as the params. The dictionary
will be coerced into a URL encoded string and then appended to the resourcePath
as the query string of the request.
@param resourcePath The resourcePath to target the request at
@param queryParameters A dictionary of query parameters to append to the
resourcePath. Assumes that resourcePath does not contain a query string.
@param delegate A delegate object to inform of the results
@return The RKRequest object built and sent to the remote system
*/
– (RKRequest *)get:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters delegate:(NSObject
/**
Fetches a resource via an HTTP GET after executing a given a block using the configured request object.
@param resourcePath The resourcePath to target the request at
@param block The block to execute with the request before sending it for processing.
*/
– (void)get:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block;
/**
Create a resource via an HTTP POST with a set of form parameters.
The form parameters passed here must conform to RKRequestSerializable, such as
an instance of RKParams.
@see RKParams
@param resourcePath The resourcePath to target the request at
@param params A RKRequestSerializable object to use as the body of the request
@param delegate A delegate object to inform of the results
@return The RKRequest object built and sent to the remote system
@see RKRequestSerializable
*/
– (RKRequest *)post:(NSString *)resourcePath params:(NSObject
/**
Creates a resource via an HTTP POST after executing a given a block using the configured request object.
@param resourcePath The resourcePath to target the request at
@param block The block to execute with the request before sending it for processing.
*/
– (void)post:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block;
/**
Update a resource via an HTTP PUT.
The form parameters passed here must conform to RKRequestSerializable, such as
an instance of RKParams.
@see RKParams
@param resourcePath The resourcePath to target the request at
@param params A RKRequestSerializable object to use as the body of the request
@param delegate A delegate object to inform of the results
@return The RKRequest object built and sent to the remote system
@see RKRequestSerializable
*/
– (RKRequest *)put:(NSString *)resourcePath params:(NSObject
/**
Updates a resource via an HTTP PUT after executing a given a block using the configured request object.
@param resourcePath The resourcePath to target the request at
@param block The block to execute with the request before sending it for processing.
*/
– (void)put:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block;
/**
Destroy a resource via an HTTP DELETE.
@param resourcePath The resourcePath to target the request at
@param delegate A delegate object to inform of the results
@return The RKRequest object built and sent to the remote system
*/
– (RKRequest *)delete:(NSString *)resourcePath delegate:(NSObject
/**
Destroys a resource via an HTTP DELETE after executing a given a block using the configured request object.
@param resourcePath The resourcePath to target the request at
@param block The block to execute with the request before sending it for processing.
*/
– (void)delete:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block;
///—————————————————————————–
/// @name Constructing Resource Paths and URLs
///—————————————————————————–
/**
Returns a NSURL by adding a resource path to the base URL
@bug **DEPRECATED** in v0.10.0: Use [RKURL URLByAppendingResourcePath:]
@param resourcePath The resource path to build a URL against
@return An NSURL constructed by concatenating the baseURL and the resourcePath
*/
– (NSURL *)URLForResourcePath:(NSString *)resourcePath DEPRECATED_ATTRIBUTE;
/**
Returns an NSString by adding a resource path to the base URL
@bug **DEPRECATED**: Use `[RKURL URLByAppendingResourcePath:] absoluteString`
@param resourcePath The resource path to build a URL against
@return A string URL constructed by concatenating the baseURL and the
resourcePath.
*/
– (NSString *)URLPathForResourcePath:(NSString *)resourcePath DEPRECATED_ATTRIBUTE;
/**
Returns a resource path with a dictionary of query parameters URL encoded and
appended
This is a convenience method for constructing a new resource path that includes
a query. For example, when given a resourcePath of /contacts and a dictionary
of parameters containing foo=bar and color=red, will return
/contacts?foo=bar&color=red
@warning **NOTE**: This assumes that the resource path does not already contain
any query parameters.
@bug **DEPRECATED**: Use [RKURL URLByAppendingQueryParameters:]
@param resourcePath The resource path to append the query parameters onto
@param queryParams A dictionary of query parameters to be URL encoded and
appended to the resource path.
@return A new resource path with the query parameters appended
*/
– (NSString *)resourcePath:(NSString *)resourcePath withQueryParams:(NSDictionary *)queryParams DEPRECATED_ATTRIBUTE;
/**
Returns a NSURL by adding a resource path to the base URL and appending a URL
encoded set of query parameters
This is a convenience method for constructing a new resource path that includes
a query. For example, when given a resourcePath of /contacts and a dictionary
of parameters containing foo=bar and color=red, will return
/contacts?foo=bar&color=red
@warning **NOTE**: Assumes that the resource path does not already contain any
query parameters.
@bug **DEPRECATED**: Use [RKURL URLByAppendingResourcePath:queryParameters:]
@param resourcePath The resource path to append the query parameters onto
@param queryParams A dictionary of query parameters to be URL encoded and
appended to the resource path.
@return A URL constructed by concatenating the baseURL and the resourcePath
with the query parameters appended.
*/
– (NSURL *)URLForResourcePath:(NSString *)resourcePath queryParams:(NSDictionary *)queryParams DEPRECATED_ATTRIBUTE;
@end
///—————————————————————————–
/// @name URL & URL Path Convenience methods
///—————————————————————————–
/**
Returns an NSURL with the specified resource path appended to the base URL that
the shared RKClient instance is configured with.
Shortcut for calling `[[RKClient sharedClient] URLForResourcePath:@”/some/path”]`
@bug **DEPRECATED** in v0.10.0: Use [[RKClient sharedClient].baseURL
URLByAppendingResourcePath:]
@param resourcePath The resource path to append to the baseURL of the
`[RKClient sharedClient]`
@return A fully constructed NSURL consisting of baseURL of the shared client
singleton and the supplied resource path
*/
NSURL *RKMakeURL(NSString *resourcePath) DEPRECATED_ATTRIBUTE;
/**
Returns an NSString with the specified resource path appended to the base URL
that the shared RKClient instance is configured with
Shortcut for calling
`[[RKClient sharedClient] URLPathForResourcePath:@”/some/path”]`
@bug **DEPRECATED** in v0.10.0: Use
[[[RKClient sharedClient].baseURL URLByAppendingResourcePath:] absoluteString]
@param resourcePath The resource path to append to the baseURL of the
`[RKClient sharedClient]`
@return A fully constructed NSURL consisting of baseURL of the shared client
singleton and the supplied resource path
*/
NSString *RKMakeURLPath(NSString *resourcePath) DEPRECATED_ATTRIBUTE;
/**
Convenience method for generating a path against the properties of an object.
Takes a string with property names encoded with colons and interpolates the
values of the properties specified and returns the generated path. Defaults to
adding escapes. If desired, turn them off with
RKMakePathWithObjectAddingEscapes.
For example, given an ‘article’ object with an ‘articleID’ property of 12345
and a ‘name’ of Blake, RKMakePathWithObject(@”articles/:articleID/:name”, article)
would generate @”articles/12345/Blake”
This functionality is the basis for resource path generation in the Router.
@bug **DEPRECATED** in v0.10.0: Use [NSString interpolateWithObject:]
@param path The colon encoded path pattern string to use for interpolation.
@param object The object containing the properties needed for interpolation.
@return A new path string, replacing the pattern’s parameters with the object’s
actual property values.
@see RKMakePathWithObjectAddingEscapes
*/
NSString *RKMakePathWithObject(NSString *path, id object) DEPRECATED_ATTRIBUTE;
/**
Convenience method for generating a path against the properties of an object. Takes
a string with property names encoded with colons and interpolates the values of
the properties specified and returns the generated path.
For example, given an ‘article’ object with an ‘articleID’ property of 12345
and a ‘code’ of “This/That”, `RKMakePathWithObjectAddingEscapes(@”articles/:articleID/:code”, article, YES)`
would generate @”articles/12345/This%2FThat”
This functionality is the basis for resource path generation in the Router.
@bug **DEPRECATED** in v0.10.0: Use [NSString interpolateWithObject:addingEscapes:]
@param path The colon encoded path pattern string to use for interpolation.
@param object The object containing the properties needed for interpolation.
@param addEscapes Conditionally add percent escapes to the interpolated
property values.
@return A new path string, replacing the pattern’s parameters with the object’s
actual property values.
*/
NSString *RKMakePathWithObjectAddingEscapes(NSString *pattern, id object, BOOL addEscapes) DEPRECATED_ATTRIBUTE;
/**
Returns a resource path with a dictionary of query parameters URL encoded and
appended.
This is a convenience method for constructing a new resource path that includes
a query. For example, when given a resourcePath of /contacts and a dictionary
of parameters containing `foo=bar` and `color=red`, will return
`/contacts?foo=bar&color=red`.
@warning This assumes that the resource path does not already contain any query
parameters.
@bug **DEPRECATED** in v0.10.0: Use [NSString stringByAppendingQueryParameters:]
instead
@param resourcePath The resource path to append the query parameters onto
@param queryParams A dictionary of query parameters to be URL encoded and
appended to the resource path.
@return A new resource path with the query parameters appended.
*/
NSString *RKPathAppendQueryParams(NSString *resourcePath, NSDictionary *queryParams) DEPRECATED_ATTRIBUTE;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKClient.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKClient.m
//
// RKClient.m
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKClient.h”
#import “RKURL.h”
#import “RKNotifications.h”
#import “RKAlert.h”
#import “RKLog.h”
#import “RKPathMatcher.h”
#import “NSString+RKAdditions.h”
#import “RKDirectory.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
///////////////////////////////////////////////////////////////////////////////////////////////////
// Global
static RKClient *sharedClient = nil;
///////////////////////////////////////////////////////////////////////////////////////////////////
// URL Conveniences functions
NSURL *RKMakeURL(NSString *resourcePath) {
return [[RKClient sharedClient].baseURL URLByAppendingResourcePath:resourcePath];
}
NSString *RKMakeURLPath(NSString *resourcePath) {
return [[[RKClient sharedClient].baseURL URLByAppendingResourcePath:resourcePath] absoluteString];
}
NSString *RKMakePathWithObjectAddingEscapes(NSString* pattern, id object, BOOL addEscapes) {
NSCAssert(pattern != NULL, @”Pattern string must not be empty in order to create a path from an interpolated object.”);
NSCAssert(object != NULL, @”Object provided is invalid; cannot create a path from a NULL object”);
RKPathMatcher *matcher = [RKPathMatcher matcherWithPattern:pattern];
NSString *interpolatedPath = [matcher pathFromObject:object addingEscapes:addEscapes];
return interpolatedPath;
}
NSString *RKMakePathWithObject(NSString *pattern, id object) {
return RKMakePathWithObjectAddingEscapes(pattern, object, YES);
}
NSString *RKPathAppendQueryParams(NSString *resourcePath, NSDictionary *queryParams) {
return [resourcePath stringByAppendingQueryParameters:queryParams];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@interface RKClient ()
@property (nonatomic, retain, readwrite) NSMutableDictionary *HTTPHeaders;
@property (nonatomic, retain, readwrite) NSSet *additionalRootCertificates;
@end
@implementation RKClient
@synthesize baseURL = _baseURL;
@synthesize authenticationType = _authenticationType;
@synthesize username = _username;
@synthesize password = _password;
@synthesize OAuth1ConsumerKey = _OAuth1ConsumerKey;
@synthesize OAuth1ConsumerSecret = _OAuth1ConsumerSecret;
@synthesize OAuth1AccessToken = _OAuth1AccessToken;
@synthesize OAuth1AccessTokenSecret = _OAuth1AccessTokenSecret;
@synthesize OAuth2AccessToken = _OAuth2AccessToken;
@synthesize OAuth2RefreshToken = _OAuth2RefreshToken;
@synthesize HTTPHeaders = _HTTPHeaders;
@synthesize additionalRootCertificates = _additionalRootCertificates;
@synthesize disableCertificateValidation = _disableCertificateValidation;
@synthesize reachabilityObserver = _reachabilityObserver;
@synthesize serviceUnavailableAlertTitle = _serviceUnavailableAlertTitle;
@synthesize serviceUnavailableAlertMessage = _serviceUnavailableAlertMessage;
@synthesize serviceUnavailableAlertEnabled = _serviceUnavailableAlertEnabled;
@synthesize requestCache = _requestCache;
@synthesize cachePolicy = _cachePolicy;
@synthesize requestQueue = _requestQueue;
@synthesize timeoutInterval = _timeoutInterval;
@synthesize defaultHTTPEncoding = _defaultHTTPEncoding;
@synthesize cacheTimeoutInterval = _cacheTimeoutInterval;
@synthesize runLoopMode = _runLoopMode;
+ (RKClient *)sharedClient {
return sharedClient;
}
+ (void)setSharedClient:(RKClient *)client {
[sharedClient release];
sharedClient = [client retain];
}
+ (RKClient *)clientWithBaseURLString:(NSString *)baseURLString {
return [self clientWithBaseURL:[RKURL URLWithString:baseURLString]];
}
+ (RKClient *)clientWithBaseURL:(NSURL *)baseURL {
RKClient *client = [[[self alloc] initWithBaseURL:baseURL] autorelease];
return client;
}
+ (RKClient *)clientWithBaseURL:(NSString *)baseURL username:(NSString *)username password:(NSString *)password {
RKClient *client = [RKClient clientWithBaseURLString:baseURL];
client.authenticationType = RKRequestAuthenticationTypeHTTPBasic;
client.username = username;
client.password = password;
return client;
}
– (id)init {
self = [super init];
if (self) {
self.HTTPHeaders = [NSMutableDictionary dictionary];
self.additionalRootCertificates = [NSMutableSet set];
self.defaultHTTPEncoding = NSUTF8StringEncoding;
self.cacheTimeoutInterval = 0;
self.runLoopMode = NSRunLoopCommonModes;
self.requestQueue = [RKRequestQueue requestQueue];
self.serviceUnavailableAlertEnabled = NO;
self.serviceUnavailableAlertTitle = NSLocalizedString(@”Service Unavailable”, nil);
self.serviceUnavailableAlertMessage = NSLocalizedString(@”The remote resource is unavailable. Please try again later.”, nil);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(serviceDidBecomeUnavailableNotification:)
name:RKServiceDidBecomeUnavailableNotification
object:nil];
// Configure observers
[self addObserver:self forKeyPath:@”reachabilityObserver” options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
[self addObserver:self forKeyPath:@”baseURL” options:NSKeyValueObservingOptionNew context:nil];
[self addObserver:self forKeyPath:@”requestQueue” options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionInitial context:nil];
}
return self;
}
– (id)initWithBaseURL:(NSURL *)baseURL {
self = [self init];
if (self) {
self.cachePolicy = RKRequestCachePolicyDefault;
self.baseURL = [RKURL URLWithBaseURL:baseURL];
if (sharedClient == nil) {
[RKClient setSharedClient:self];
// Initialize Logging as soon as a client is created
RKLogInitialize();
}
}
return self;
}
– (id)initWithBaseURLString:(NSString *)baseURLString {
return [self initWithBaseURL:[RKURL URLWithString:baseURLString]];
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Allow KVO to fire
self.reachabilityObserver = nil;
self.baseURL = nil;
self.requestQueue = nil;
[self removeObserver:self forKeyPath:@”reachabilityObserver”];
[self removeObserver:self forKeyPath:@”baseURL”];
[self removeObserver:self forKeyPath:@”requestQueue”];
self.username = nil;
self.password = nil;
self.serviceUnavailableAlertTitle = nil;
self.serviceUnavailableAlertMessage = nil;
self.requestCache = nil;
self.runLoopMode = nil;
[_HTTPHeaders release];
[_additionalRootCertificates release];
if (sharedClient == self) sharedClient = nil;
[super dealloc];
}
– (NSString *)cachePath {
NSString *cacheDirForClient = [NSString stringWithFormat:@”RKClientRequestCache-%@”, [self.baseURL host]];
NSString *cachePath = [[RKDirectory cachesDirectory]
stringByAppendingPathComponent:cacheDirForClient];
return cachePath;
}
– (BOOL)isNetworkReachable {
BOOL isNetworkReachable = YES;
if (self.reachabilityObserver) {
isNetworkReachable = [self.reachabilityObserver isNetworkReachable];
}
return isNetworkReachable;
}
– (void)configureRequest:(RKRequest *)request {
request.additionalHTTPHeaders = _HTTPHeaders;
request.authenticationType = self.authenticationType;
request.username = self.username;
request.password = self.password;
request.cachePolicy = self.cachePolicy;
request.cache = self.requestCache;
request.queue = self.requestQueue;
request.reachabilityObserver = self.reachabilityObserver;
request.defaultHTTPEncoding = self.defaultHTTPEncoding;
request.additionalRootCertificates = self.additionalRootCertificates;
request.disableCertificateValidation = self.disableCertificateValidation;
request.runLoopMode = self.runLoopMode;
// If a timeoutInterval was set on the client, we’ll pass it on to the request.
// Otherwise, we’ll let the request default to its own timeout interval.
if (self.timeoutInterval) {
request.timeoutInterval = self.timeoutInterval;
}
if (self.cacheTimeoutInterval) {
request.cacheTimeoutInterval = self.cacheTimeoutInterval;
}
// OAuth 1 Parameters
request.OAuth1AccessToken = self.OAuth1AccessToken;
request.OAuth1AccessTokenSecret = self.OAuth1AccessTokenSecret;
request.OAuth1ConsumerKey = self.OAuth1ConsumerKey;
request.OAuth1ConsumerSecret = self.OAuth1ConsumerSecret;
// OAuth2 Parameters
request.OAuth2AccessToken = self.OAuth2AccessToken;
request.OAuth2RefreshToken = self.OAuth2RefreshToken;
}
– (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)header {
[_HTTPHeaders setValue:value forKey:header];
}
– (void)addRootCertificate:(SecCertificateRef)cert {
[_additionalRootCertificates addObject:(id)cert];
}
– (void)reachabilityObserverDidChange:(NSDictionary *)change {
RKReachabilityObserver *oldReachabilityObserver = [change objectForKey:NSKeyValueChangeOldKey];
RKReachabilityObserver *newReachabilityObserver = [change objectForKey:NSKeyValueChangeNewKey];
if (! [oldReachabilityObserver isEqual:[NSNull null]]) {
RKLogDebug(@”Reachability observer changed for RKClient %@, disposing of previous instance: %@”, self, oldReachabilityObserver);
// Cleanup if changed immediately after client init
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKReachabilityWasDeterminedNotification object:oldReachabilityObserver];
}
if (! [newReachabilityObserver isEqual:[NSNull null]]) {
// Suspend the queue until reachability to our new hostname is established
if (! [newReachabilityObserver isReachabilityDetermined]) {
self.requestQueue.suspended = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityWasDetermined:)
name:RKReachabilityWasDeterminedNotification
object:newReachabilityObserver];
RKLogDebug(@”Reachability observer changed for client %@, suspending queue %@ until reachability to host ‘%@’ can be determined”,
self, self.requestQueue, newReachabilityObserver.host);
// Maintain a flag for Reachability determination status. This ensures that we can do the right thing in the
// event that the requestQueue is changed while we are in an inderminate suspension state
_awaitingReachabilityDetermination = YES;
} else {
self.requestQueue.suspended = NO;
RKLogDebug(@”Reachability observer changed for client %@, unsuspending queue %@ as new observer already has determined reachability to %@”,
self, self.requestQueue, newReachabilityObserver.host);
_awaitingReachabilityDetermination = NO;
}
}
}
– (void)baseURLDidChange:(NSDictionary *)change {
RKURL *newBaseURL = [change objectForKey:NSKeyValueChangeNewKey];
// Don’t crash if baseURL is nil’d out (i.e. dealloc)
if (! [newBaseURL isEqual:[NSNull null]]) {
// Configure a cache for the new base URL
[_requestCache release];
_requestCache = [[RKRequestCache alloc] initWithPath:[self cachePath]
storagePolicy:RKRequestCacheStoragePolicyPermanently];
// Determine reachability strategy (if user has not already done so)
if (self.reachabilityObserver == nil) {
NSString *hostName = [newBaseURL host];
if ([hostName isEqualToString:@”localhost”] || [hostName isIPAddress]) {
self.reachabilityObserver = [RKReachabilityObserver reachabilityObserverForHost:hostName];
} else {
self.reachabilityObserver = [RKReachabilityObserver reachabilityObserverForInternet];
}
}
}
}
– (void)requestQueueDidChange:(NSDictionary *)change {
if (! _awaitingReachabilityDetermination) {
return;
}
// If we are awaiting reachability determination, suspend the new queue
RKRequestQueue *newQueue = [change objectForKey:NSKeyValueChangeNewKey];
if (! [newQueue isEqual:[NSNull null]]) {
// The request queue has changed while we were awaiting reachability.
// Suspend the queue until reachability is determined
newQueue.suspended = !self.reachabilityObserver.reachabilityDetermined;
}
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@”baseURL”]) {
[self baseURLDidChange:change];
} else if ([keyPath isEqualToString:@”requestQueue”]) {
[self requestQueueDidChange:change];
} else if ([keyPath isEqualToString:@”reachabilityObserver”]) {
[self reachabilityObserverDidChange:change];
}
}
– (RKRequest *)requestWithResourcePath:(NSString *)resourcePath {
RKRequest *request = [[RKRequest alloc] initWithURL:[self.baseURL URLByAppendingResourcePath:resourcePath]];
[self configureRequest:request];
[request autorelease];
return request;
}
– (RKRequest *)requestWithResourcePath:(NSString *)resourcePath delegate:(NSObject
RKRequest *request = [self requestWithResourcePath:resourcePath];
request.delegate = delegate;
return request;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Asynchronous Requests
///////////////////////////////////////////////////////////////////////////////////////////////////////////
– (RKRequest *)load:(NSString *)resourcePath method:(RKRequestMethod)method params:(NSObject
RKURL* resourcePathURL = nil;
if (method == RKRequestMethodGET) {
resourcePathURL = [self.baseURL URLByAppendingResourcePath:resourcePath queryParameters:(NSDictionary *)params];
} else {
resourcePathURL = [self.baseURL URLByAppendingResourcePath:resourcePath];
}
RKRequest *request = [RKRequest requestWithURL:resourcePathURL];
request.delegate = delegate;
[self configureRequest:request];
request.method = method;
if (method != RKRequestMethodGET) {
request.params = params;
}
[request send];
return request;
}
– (RKRequest *)get:(NSString *)resourcePath delegate:(id)delegate {
return [self load:resourcePath method:RKRequestMethodGET params:nil delegate:delegate];
}
– (RKRequest *)get:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters delegate:(id)delegate {
return [self load:resourcePath method:RKRequestMethodGET params:queryParameters delegate:delegate];
}
– (RKRequest *)post:(NSString *)resourcePath params:(NSObject
return [self load:resourcePath method:RKRequestMethodPOST params:params delegate:delegate];
}
– (RKRequest *)put:(NSString *)resourcePath params:(NSObject
return [self load:resourcePath method:RKRequestMethodPUT params:params delegate:delegate];
}
– (RKRequest *)delete:(NSString *)resourcePath delegate:(id)delegate {
return [self load:resourcePath method:RKRequestMethodDELETE params:nil delegate:delegate];
}
– (void)serviceDidBecomeUnavailableNotification:(NSNotification *)notification {
if (self.serviceUnavailableAlertEnabled) {
RKAlertWithTitle(self.serviceUnavailableAlertMessage, self.serviceUnavailableAlertTitle);
}
}
– (void)reachabilityWasDetermined:(NSNotification *)notification {
RKReachabilityObserver *observer = (RKReachabilityObserver *) [notification object];
NSAssert(observer == self.reachabilityObserver, @”Received unexpected reachability notification from inappropriate reachability observer”);
RKLogDebug(@”Reachability to host ‘%@’ determined for client %@, unsuspending queue %@”, observer.host, self, self.requestQueue);
_awaitingReachabilityDetermination = NO;
self.requestQueue.suspended = NO;
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKReachabilityWasDeterminedNotification object:observer];
}
#pragma mark – Deprecations
// deprecated
– (RKRequestCache *)cache {
return _requestCache;
}
// deprecated
– (void)setCache:(RKRequestCache *)requestCache {
self.requestCache = requestCache;
}
#pragma mark – Block Request Dispatching
– (RKRequest *)sendRequestToResourcePath:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block {
RKRequest *request = [self requestWithResourcePath:resourcePath];
if (block) block(request);
[request send];
return request;
}
– (void)get:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block {
[self sendRequestToResourcePath:resourcePath usingBlock:^(RKRequest *request) {
request.method = RKRequestMethodGET;
block(request);
}];
}
– (void)post:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block {
[self sendRequestToResourcePath:resourcePath usingBlock:^(RKRequest *request) {
request.method = RKRequestMethodPOST;
block(request);
}];
}
– (void)put:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block {
[self sendRequestToResourcePath:resourcePath usingBlock:^(RKRequest *request) {
request.method = RKRequestMethodPUT;
block(request);
}];
}
– (void)delete:(NSString *)resourcePath usingBlock:(void (^)(RKRequest *request))block {
[self sendRequestToResourcePath:resourcePath usingBlock:^(RKRequest *request) {
request.method = RKRequestMethodDELETE;
block(request);
}];
}
// deprecated
– (BOOL)isNetworkAvailable {
return [self isNetworkReachable];
}
– (NSString *)resourcePath:(NSString *)resourcePath withQueryParams:(NSDictionary *)queryParams {
return RKPathAppendQueryParams(resourcePath, queryParams);
}
– (NSURL *)URLForResourcePath:(NSString *)resourcePath {
return [self.baseURL URLByAppendingResourcePath:resourcePath];
}
– (NSString *)URLPathForResourcePath:(NSString *)resourcePath {
return [[self URLForResourcePath:resourcePath] absoluteString];
}
– (NSURL *)URLForResourcePath:(NSString *)resourcePath queryParams:(NSDictionary *)queryParams {
return [self.baseURL URLByAppendingResourcePath:resourcePath queryParameters:queryParams];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKClient.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKNotifications.h
//
// RKNotifications.h
// RestKit
//
// Created by Blake Watters on 9/24/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
Request Auditing
RKClient exposes a set of NSNotifications that can be used to audit the
request/response cycle of your application. This is useful for doing things
like generating automatic logging for all your requests or sending the response
times.
*/
extern NSString * const RKRequestSentNotification;
extern NSString * const RKRequestDidLoadResponseNotification;
extern NSString * const RKRequestDidLoadResponseNotificationUserInfoResponseKey;
extern NSString * const RKRequestDidFailWithErrorNotification;
extern NSString * const RKRequestDidFailWithErrorNotificationUserInfoErrorKey;
extern NSString * const RKRequestDidFinishLoadingNotification;
extern NSString * const RKServiceDidBecomeUnavailableNotification;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKNotifications.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKNotifications.m
//
// RKNotifications.m
// RestKit
//
// Created by Blake Watters on 9/24/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKNotifications.h”
NSString * const RKRequestSentNotification = @”RKRequestSentNotification”;
NSString * const RKRequestDidFailWithErrorNotification = @”RKRequestDidFailWithErrorNotification”;
NSString * const RKRequestDidFailWithErrorNotificationUserInfoErrorKey = @”error”;
NSString * const RKRequestDidLoadResponseNotification = @”RKRequestDidLoadResponseNotification”;
NSString * const RKRequestDidLoadResponseNotificationUserInfoResponseKey = @”response”;
NSString * const RKServiceDidBecomeUnavailableNotification = @”RKServiceDidBecomeUnavailableNotification”;
NSString * const RKRequestDidFinishLoadingNotification = @”RKRequestDidFinishLoadingNotification”;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKNotifications.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKOAuthClient.h
//
// RKOAuthClient.h
// RestKit
//
// Created by Rodrigo Garcia on 7/20/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKClient.h”
#import “RKRequest.h”
/**
Defines error codes for OAuth client errors that are returned via a callback
to RKOAuthClient’s delegate
*/
typedef enum RKOAuthClientErrors {
/**
An invalid authorization code was encountered
*/
RKOAuthClientErrorInvalidGrant = 3001,
/**
The client is not authorized to perform the action
*/
RKOAuthClientErrorUnauthorizedClient = 3002,
/**
Client authentication failed (e.g. unknown client, no client
authentication included, or unsupported authentication method).
*/
RKOAuthClientErrorInvalidClient = 3003,
/**
The request is missing a required parameter, includes an unsupported
parameter value, repeats a parameter, includes multiple credentials,
utilizes more than one mechanism for authenticating the client, or is
otherwise malformed.
*/
RKOAuthClientErrorInvalidRequest = 3004,
/**
The authorization grant type is not supported by the authorization server.
*/
RKOAuthClientErrorUnsupportedGrantType = 3005,
/**
The requested scope is invalid, unknown, malformed, or exceeds the scope
granted by the resource owner.
*/
RKOAuthClientErrorInvalidScope = 3006,
/**
An underlying RKRequest failed due to an error. The userInfo dictionary
will contain an NSUnderlyingErrorKey with the details of the failure
*/
RKOAuthClientErrorRequestFailure = 3007,
/**
Error was encountered and error_description unknown
*/
RKOAuthClientErrorUnknown = 0
} RKOAuthClientErrorCode;
@protocol RKOAuthClientDelegate;
/**
An OAuth client implementation that conforms to RKRequestDelegate to handle the
authentication involved with the OAuth 2 authorization code flow.
RKOAuthClient sets up a pre-configured RKRequest and RKResponse handler to give
easy access to retrieving an access token and handling errors through
RKOAuthClientDelegate.
**Example**:
RKOAuthClient *oauthClient;
oauthClient = [RKClientOAuth clientWithClientID:@”YOUR_CLIENT_ID”
secret:@”YOUR_CLIENT_SECRET”
delegate:yourDelegate];
oauthClient.authorizationCode = @”AUTHORIZATION_CODE”;
oauthClient.authorizationURL = @”https://foursquare.com/oauth2/authenticate”;
oauthClient.callbackURL = @”https://example.com/callback”;
[oauthClient validateAuthorizationCode];
From here, errors and the access token are returned through the
implementation of RKOAuthClientDelegate specified.
For more information on the OAuth 2 implementation, see
http://tools.ietf.org/html/draft-ietf-oauth-v2-22
@see RKOAuthClientDelegate
*/
@interface RKOAuthClient : NSObject {
NSString *_clientID;
NSString *_clientSecret;
NSString *_authorizationCode;
NSString *_authorizationURL;
NSString *_callbackURL;
NSString *_accessToken;
id
}
///—————————————————————————–
/// @name Creating an RKOAuthClient
///—————————————————————————–
/**
Initialize a new RKOAuthClient with OAuth client credentials.
@param clientID The ID of your application obtained from the OAuth provider.
@param secret Confidential key obtained from the OAuth provider that is used to
sign requests sent to the authentication server.
@return An RKOAuthClient initialized with a client ID and secret key.
*/
– (id)initWithClientID:(NSString *)clientID secret:(NSString *)secret;
/**
Creates and returns an RKOAuthClient initialized with OAuth client credentials.
@param clientID The ID of your application obtained from the OAuth provider.
@param secret Confidential key obtained from the OAuth provider that is used to
sign requests sent to the authentication server.
@return An RKOAuthClient initialized with a client ID and secret key.
*/
+ (RKOAuthClient *)clientWithClientID:(NSString *)clientID secret:(NSString *)secret;
///—————————————————————————–
/// @name General properties
///—————————————————————————–
/**
A delegate that must conform to the RKOAuthClientDelegate protocol.
The delegate will get callbacks such as successful access token acquisitions as
well as any errors that are encountered. Reference the RKOAuthClientDelegate
for more information.
@see RKOAuthClientDelegate.
*/
@property (nonatomic, assign) id
///—————————————————————————–
/// @name Client credentials
///—————————————————————————–
/**
The ID of your application obtained from the OAuth provider
*/
@property (nonatomic, retain) NSString *clientID;
/**
Confidential key obtained from the OAuth provider that is used to sign requests
sent to the authentication server.
*/
@property (nonatomic, retain) NSString *clientSecret;
///—————————————————————————–
/// @name Endpoints
///—————————————————————————–
/**
A string of the URL where the authorization server can be accessed
*/
@property (nonatomic, retain) NSString *authorizationURL;
/**
A string of the URL where authorization attempts will be redirected to
*/
@property (nonatomic, retain) NSString *callbackURL;
///—————————————————————————–
/// @name Working with the authorization flow
///—————————————————————————–
/**
The authorization code is used in conjunction with your client secret to obtain
an access token.
*/
@property (nonatomic, retain) NSString *authorizationCode;
/**
Returns the access token retrieved from the authentication server
*/
@property (nonatomic, readonly) NSString *accessToken;
/**
Fire a request to the authentication server to validate the authorization code
that has been set on the authorizationCode property. All responses are handled
by the delegate.
@see RKOAuthClientDelegate
*/
– (void)validateAuthorizationCode;
@end
/**
The delegate of an RKOAuthClient object must adopt the RKOAuthClientDelegate
protocol. The protocol defines all methods relating to obtaining an
accessToken and handling any errors along the way. It optionally provides
callbacks for many different OAuth2 exceptions that may occur during the
authorization code flow.
*/
@protocol RKOAuthClientDelegate
@required
///—————————————————————————–
/// @name Successful responses
///—————————————————————————–
/**
Sent when a new access token has been acquired
@param client A reference to the RKOAuthClient that triggered the callback
@param token A string of the access token acquired from the authentication
server.
*/
– (void)OAuthClient:(RKOAuthClient *)client didAcquireAccessToken:(NSString *)token;
///—————————————————————————–
/// @name Handling errors
///—————————————————————————–
/**
Sent when an access token request has failed due an invalid authorization code
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithInvalidGrantError:(NSError *)error;
@optional
/**
Sent to the delegate when the OAuth client encounters any error.
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithError:(NSError *)error;
/**
Sent when the client isn’t authorized to perform the requested action
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithUnauthorizedClientError:(NSError *)error;
/**
Sent when an error is encountered with the OAuth client such as an unknown
client, there is no client authentication included, or an unsupported
authentication method was used.
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithInvalidClientError:(NSError *)error;
/**
Sent when the request sent to the authentication server is invalid
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithInvalidRequestError:(NSError *)error;
/**
Sent when the grant type specified isn’t supported by the authentication server
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithUnsupportedGrantTypeError:(NSError *)error;
/**
Sent when the requested scope is invalid, unknown, malformed, or exceeds the
scope granted by the resource owner.
@param client A reference to the RKOAuthClient that triggered the callback
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailWithInvalidScopeError:(NSError *)error;
/**
Sent to the delegate when an authorization code flow request failed due to a
loading error somewhere within the RKRequest call
@param client A reference to the RKOAuthClient that triggered the callback
@param request A reference to the RKRequest that failed
@param error An NSError object containing the RKOAuthClientError that triggered
the callback
*/
– (void)OAuthClient:(RKOAuthClient *)client didFailLoadingRequest:(RKRequest *)request withError:(NSError *)error;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKOAuthClient.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKOAuthClient.m
//
// RKOAuthClient.m
// RestKit
//
// Created by Rodrigo Garcia on 7/20/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKOAuthClient.h”
#import “RKErrors.h”
@interface RKOAuthClient ()
@end
@implementation RKOAuthClient
@synthesize clientID = _clientID;
@synthesize clientSecret = _clientSecret;
@synthesize authorizationCode = _authorizationCode;
@synthesize authorizationURL = _authorizationURL;
@synthesize callbackURL = _callbackURL;
@synthesize delegate = _delegate;
@synthesize accessToken = _accessToken;
+ (RKOAuthClient *)clientWithClientID:(NSString *)clientID secret:(NSString *)secret {
RKOAuthClient *client = [[[self alloc] initWithClientID:clientID secret:secret] autorelease];
return client;
}
– (id)initWithClientID:(NSString *)clientID secret:(NSString *)secret {
self = [super init];
if (self) {
_clientID = [clientID copy];
_clientSecret = [secret copy];
}
return self;
}
– (void)dealloc {
[_clientID release];
[_clientSecret release];
[_accessToken release];
[super dealloc];
}
– (void)validateAuthorizationCode {
NSString *httpBody = [NSString stringWithFormat:@”client_id=%@&client_secret=%@&code=%@&redirect_uri=%@&grant_type=authorization_code”,
_clientID, _clientSecret, _authorizationCode, _callbackURL];
NSURL *URL = [NSURL URLWithString:_authorizationURL];
RKRequest *theRequest = [RKRequest requestWithURL:URL];
theRequest.delegate = self;
[theRequest setHTTPBodyString:httpBody];
[theRequest setMethod:RKRequestMethodPOST];
[theRequest send];
}
– (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
NSError *error = nil;
NSString *errorResponse = nil;
//Use the parsedBody answer in NSDictionary
NSDictionary* oauthResponse = (NSDictionary *) [response parsedBody:&error];
if ([oauthResponse isKindOfClass:[NSDictionary class]]) {
//Check the if an access token comes in the response
_accessToken = [[oauthResponse objectForKey:@”access_token”] copy];
errorResponse = [oauthResponse objectForKey:@”error”];
if (_accessToken) {
// W00T We got an accessToken
[self.delegate OAuthClient:self didAcquireAccessToken:_accessToken];
return;
} else if (errorResponse) {
// Heads-up! There is an error in the response
// The possible errors are defined in the OAuth2 Protocol
RKOAuthClientErrorCode errorCode = RKOAuthClientErrorUnknown;
NSString *errorDescription = [oauthResponse objectForKey:@”error_description”];
if ([errorResponse isEqualToString:@”invalid_grant”]) {
errorCode = RKOAuthClientErrorInvalidGrant;
}
else if([errorResponse isEqualToString:@”unauthorized_client”]){
errorCode = RKOAuthClientErrorUnauthorizedClient;
}
else if([errorResponse isEqualToString:@”invalid_client”]){
errorCode = RKOAuthClientErrorInvalidClient;
}
else if([errorResponse isEqualToString:@”invalid_request”]){
errorCode = RKOAuthClientErrorInvalidRequest;
}
else if([errorResponse isEqualToString:@”unsupported_grant_type”]){
errorCode = RKOAuthClientErrorUnsupportedGrantType;
}
else if([errorResponse isEqualToString:@”invalid_scope”]){
errorCode = RKOAuthClientErrorInvalidScope;
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorDescription, NSLocalizedDescriptionKey, nil];
NSError *error = [NSError errorWithDomain:RKErrorDomain code:errorCode userInfo:userInfo];
// Inform the delegate of what happened
if ([self.delegate respondsToSelector:@selector(OAuthClient:didFailWithError:)]) {
[self.delegate OAuthClient:self didFailWithError:error];
}
// Invalid grant
if (errorCode == RKOAuthClientErrorInvalidGrant && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithInvalidGrantError:)]) {
[self.delegate OAuthClient:self didFailWithInvalidGrantError:error];
}
// Unauthorized client
if (errorCode == RKOAuthClientErrorUnauthorizedClient && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithUnauthorizedClientError:)]) {
[self.delegate OAuthClient:self didFailWithUnauthorizedClientError:error];
}
// Invalid client
if (errorCode == RKOAuthClientErrorInvalidClient && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithInvalidClientError:)]) {
[self.delegate OAuthClient:self didFailWithInvalidClientError:error];
}
// Invalid request
if (errorCode == RKOAuthClientErrorInvalidRequest && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithInvalidRequestError:)]) {
[self.delegate OAuthClient:self didFailWithInvalidRequestError:error];
}
// Unsupported grant type
if (errorCode == RKOAuthClientErrorUnsupportedGrantType && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithUnsupportedGrantTypeError:)]) {
[self.delegate OAuthClient:self didFailWithUnsupportedGrantTypeError:error];
}
// Invalid scope
if (errorCode == RKOAuthClientErrorInvalidScope && [self.delegate respondsToSelector:@selector(OAuthClient:didFailWithInvalidScopeError:)]) {
[self.delegate OAuthClient:self didFailWithInvalidScopeError:error];
}
}
} else if (error) {
if ([self.delegate respondsToSelector:@selector(OAuthClient:didFailWithError:)]) {
[self.delegate OAuthClient:self didFailWithError:error];
}
} else {
// TODO: Logging…
}
}
– (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
error, NSUnderlyingErrorKey, nil];
NSError *clientError = [NSError errorWithDomain:RKErrorDomain code:RKOAuthClientErrorRequestFailure userInfo:userInfo];
if ([self.delegate respondsToSelector:@selector(OAuthClient:didFailLoadingRequest:withError:)]) {
[self.delegate OAuthClient:self didFailLoadingRequest:request withError:clientError];
}
if ([self.delegate respondsToSelector:@selector(OAuthClient:didFailWithError:)]) {
[self.delegate OAuthClient:self didFailWithError:clientError];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKOAuthClient.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKParams.h
//
// RKParams.h
// RestKit
//
// Created by Blake Watters on 8/3/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKRequestSerializable.h”
#import “RKParamsAttachment.h”
/**
This helper class implements the RKRequestSerializable protocol to provide
support for creating the multi-part request body for RKRequest objects.
RKParams enables simple support for file uploading from NSData objects and
files stored locally. RKParams will serialize these objects into a multi-part
form representation that is suitable for submission to a remote web server for
processing. After creating the RKParams object, use
[RKClient post:params:delegate:] as the example below does.
**Example**:
RKParams *params = [RKParams params];
NSData *imageData = UIImagePNGRepresentation([_imageView image]);
[params setData:imageData MIMEType:@”image/png” forParam:@”image1″];
UIImage *image = [UIImage imageNamed:@”RestKit “];
imageData = UIImagePNGRepresentation(image);
[params setData:imageData MIMEType:@”image/png” forParam:@”image2″];
[_client post:@”/RKParamsExample” params:params delegate:self];
It is also used internally by RKRequest for its OAuth1 implementation.
*/
@interface RKParams : NSInputStream
@private
NSMutableArray *_attachments;
NSStreamStatus _streamStatus;
NSData *_footer;
NSUInteger _bytesDelivered;
NSUInteger _length;
NSUInteger _footerLength;
NSUInteger _currentPart;
}
///—————————————————————————–
/// @name Creating an RKParams object
///—————————————————————————–
/**
Creates and returns an RKParams object that is ready for population.
@return An RKParams object to be populated.
*/
+ (RKParams *)params;
/**
Creates and returns an RKParams object created from a dictionary of key/value
pairs.
@param dictionary NSDictionary of key/value pairs to add as RKParamsAttachment
objects.
@return An RKParams object with the key/value pairs of the dictionary.
*/
+ (RKParams *)paramsWithDictionary:(NSDictionary *)dictionary;
/**
Initalize an RKParams object from a dictionary of key/value pairs
@param dictionary NSDictionary of key/value pairs to add as RKParamsAttachment
objects.
@return An RKParams object with the key/value pairs of the dictionary.
*/
– (RKParams *)initWithDictionary:(NSDictionary *)dictionary;
///—————————————————————————–
/// @name Working with attachments
///—————————————————————————–
/**
Array of all RKParamsAttachment attachments
*/
@property (nonatomic, readonly) NSMutableArray *attachments;
/**
Creates a new RKParamsAttachment from the key/value pair passed in and adds it
to the attachments array.
@param value Value of the attachment to add
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setValue:(id
/**
Creates a new RKParamsAttachment for a named parameter with the data contained
in the file at the given path and adds it to the attachments array.
@param filePath String of the path to the file to be attached
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setFile:(NSString *)filePath forParam:(NSString *)param;
/**
Creates a new RKParamsAttachment for a named parameter with the data given and
adds it to the attachments array.
A default MIME type of application/octet-stream will be used.
@param data NSData object of the data to be attached
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setData:(NSData *)data forParam:(NSString *)param;
/**
Creates a new RKParamsAttachment for a named parameter with the data given and
the MIME type specified and adds it to the attachments array.
@param data NSData object of the data to be attached
@param MIMEType String of the MIME type of the data
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setData:(NSData *)data MIMEType:(NSString *)MIMEType forParam:(NSString *)param;
/**
Creates a new RKParamsAttachment and sets the value for a named parameter to a
data object with the specified MIME Type and attachment file name.
@bug **DEPRECATED**: Use [RKParams setData:MIMEType:forParam:] and set the
fileName on the returned RKParamsAttachment instead.
@param data NSData object of the data to be attached
@param MIMEType String of the MIME type of the data
@param fileName String of the attachment file name
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setData:(NSData *)data MIMEType:(NSString *)MIMEType fileName:(NSString *)fileName forParam:(NSString *)param DEPRECATED_ATTRIBUTE;
/**
Creates a new RKParamsAttachment and sets the value for a named parameter to
the data contained in a file at the given path with the specified MIME Type and
attachment file name.
@bug **DEPRECATED**: Use [RKParams setFile:forParam:] and set the MIMEType and
fileName on the returned RKParamsAttachment instead.
@param filePath String of the path to the file to be attached
@param MIMEType String of the MIME type of the data
@param fileName String of the attachment file name
@param param Key name of the attachment to add
@return the new RKParamsAttachment that was added to the attachments array
*/
– (RKParamsAttachment *)setFile:(NSString *)filePath MIMEType:(NSString *)MIMEType fileName:(NSString *)fileName forParam:(NSString *)param DEPRECATED_ATTRIBUTE;
/**
Get the dictionary of params which are plain text as specified by
[RFC 5849](http://tools.ietf.org/html/rfc5849#section-3.4.1.3).
This is largely used for RKClient’s OAuth1 implementation.
The params in this dictionary include those where:
– The entity-body is single-part.
– The entity-body follows the encoding requirements of the
“application/x-www-form-urlencoded” content-type as defined by
[W3C.REC-html40-19980424].
– The HTTP request entity-header includes the “Content-Type” header field set
to “application/x-www-form-urlencoded”.
@return NSDictionary of key/values extracting from the RKParamsAttachment
objects that meet the plain text criteria
*/
– (NSDictionary *)dictionaryOfPlainTextParams;
///—————————————————————————–
/// @name Resetting and checking states
///—————————————————————————–
/**
Resets the state of the RKParams stream.
*/
– (void)reset;
/**
Return a composite MD5 checksum value for all attachments.
*/
– (NSString *)MD5;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKParams.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKParams.m
//
// RKParams.m
// RestKit
//
// Created by Blake Watters on 8/3/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKParams.h”
#import “RKLog.h”
#import “NSString+RKAdditions.h”
// Need for iOS 5 UIDevice workaround
#if TARGET_OS_IPHONE
#import
#endif
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
/**
* The boundary used used for multi-part headers
*/
NSString* const kRKStringBoundary = @”0xKhTmLbOuNdArY”;
@implementation RKParams
+ (RKParams*)params {
RKParams* params = [[[RKParams alloc] init] autorelease];
return params;
}
+ (RKParams*)paramsWithDictionary:(NSDictionary*)dictionary {
RKParams* params = [[[RKParams alloc] initWithDictionary:dictionary] autorelease];
return params;
}
– (id)init {
self = [super init];
if (self) {
_attachments = [NSMutableArray new];
_footer = [[[NSString stringWithFormat:@”–%@–\r\n”, kRKStringBoundary] dataUsingEncoding:NSUTF8StringEncoding] retain];
_footerLength = [_footer length];
}
return self;
}
– (void)dealloc {
[_attachments release];
[_footer release];
[super dealloc];
}
– (RKParams *)initWithDictionary:(NSDictionary *)dictionary {
self = [self init];
if (self) {
// NOTE: We sort the keys to try and ensure given identical dictionaries we’ll wind up
// with matching MD5 checksums.
NSArray *sortedKeys = [[dictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
for (NSString *key in sortedKeys) {
id value = [dictionary objectForKey:key];
[self setValue:value forParam:key];
}
}
return self;
}
– (RKParamsAttachment *)setValue:(id
RKParamsAttachment *attachment = [[RKParamsAttachment alloc] initWithName:param value:value];
[_attachments addObject:attachment];
[attachment release];
return attachment;
}
– (NSDictionary *)dictionaryOfPlainTextParams {
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for (RKParamsAttachment *attachment in _attachments)
if (attachment.value) // if the value exist, it is plain text param
[result setValue:attachment.value forKey:attachment.name];
return [NSDictionary dictionaryWithDictionary:result];
}
– (RKParamsAttachment *)setFile:(NSString *)filePath forParam:(NSString *)param {
NSParameterAssert(filePath);
NSParameterAssert(param);
RKParamsAttachment *attachment = [[RKParamsAttachment alloc] initWithName:param file:filePath];
[_attachments addObject:attachment];
[attachment release];
return attachment;
}
– (RKParamsAttachment *)setData:(NSData *)data forParam:(NSString *)param {
NSParameterAssert(data);
NSParameterAssert(param);
RKParamsAttachment *attachment = [[RKParamsAttachment alloc] initWithName:param data:data];
[_attachments addObject:attachment];
[attachment release];
return attachment;
}
– (RKParamsAttachment *)setData:(NSData *)data MIMEType:(NSString *)MIMEType forParam:(NSString *)param {
NSParameterAssert(data);
NSParameterAssert(MIMEType);
NSParameterAssert(param);
RKParamsAttachment *attachment = [self setData:data forParam:param];
if (MIMEType != nil) {
attachment.MIMEType = MIMEType;
}
return attachment;
}
– (RKParamsAttachment *)setData:(NSData *)data MIMEType:(NSString *)MIMEType fileName:(NSString *)fileName forParam:(NSString *)param {
NSParameterAssert(data);
NSParameterAssert(param);
RKParamsAttachment *attachment = [self setData:data forParam:param];
if (MIMEType) {
attachment.MIMEType = MIMEType;
}
if (fileName) {
attachment.fileName = fileName;
}
return attachment;
}
– (RKParamsAttachment *)setFile:(NSString *)filePath MIMEType:(NSString *)MIMEType fileName:(NSString *)fileName forParam:(NSString *)param {
NSParameterAssert(filePath);
NSParameterAssert(param);
RKParamsAttachment *attachment = [self setFile:filePath forParam:param];
if (MIMEType) {
attachment.MIMEType = MIMEType;
}
if (fileName) {
attachment.fileName = fileName;
}
return attachment;
}
#pragma mark RKRequestSerializable methods
– (NSString *)HTTPHeaderValueForContentType {
return [NSString stringWithFormat:@”multipart/form-data; boundary=%@”, kRKStringBoundary];
}
– (NSUInteger)HTTPHeaderValueForContentLength {
return _length;
}
– (void)reset {
_bytesDelivered = 0;
_length = 0;
_streamStatus = NSStreamStatusNotOpen;
}
– (NSInputStream *)HTTPBodyStream {
// Open each of our attachments
[_attachments makeObjectsPerformSelector:@selector(open)];
// Calculate the length of the stream
_length = _footerLength;
for (RKParamsAttachment *attachment in _attachments) {
_length += [attachment length];
}
return (NSInputStream*)self;
}
#pragma mark NSInputStream methods
– (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)maxLength {
NSUInteger bytesSentInThisRead = 0, bytesRead;
NSUInteger lengthOfAttachments = (_length – _footerLength);
// Proxy the read through to our attachments
_streamStatus = NSStreamStatusReading;
while (_bytesDelivered < _length && bytesSentInThisRead < maxLength && _currentPart < [_attachments count]) {
if ((bytesRead = [[_attachments objectAtIndex:_currentPart] read:buffer + bytesSentInThisRead maxLength:maxLength - bytesSentInThisRead]) == 0) {
_currentPart ++;
continue;
}
bytesSentInThisRead += bytesRead;
_bytesDelivered += bytesRead;
}
// If we have sent all the attachments data, begin emitting the boundary footer
if ((_bytesDelivered >= lengthOfAttachments) && (bytesSentInThisRead < maxLength)) {
NSUInteger footerBytesSent, footerBytesRemaining, bytesRemainingInBuffer;
// Calculate our position in the stream & buffer
footerBytesSent = _bytesDelivered - lengthOfAttachments;
footerBytesRemaining = _footerLength - footerBytesSent;
bytesRemainingInBuffer = maxLength - bytesSentInThisRead;
// Send the entire footer back if there is room
bytesRead = (footerBytesRemaining < bytesRemainingInBuffer) ? footerBytesRemaining : bytesRemainingInBuffer;
[_footer getBytes:buffer + bytesSentInThisRead range:NSMakeRange(footerBytesSent, bytesRead)];
bytesSentInThisRead += bytesRead;
_bytesDelivered += bytesRead;
}
return bytesSentInThisRead;
}
- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len {
return NO;
}
- (BOOL)hasBytesAvailable {
return _bytesDelivered < _length;
}
- (void)open {
_streamStatus = NSStreamStatusOpen;
RKLogTrace(@"RKParams stream opened...");
}
- (void)close {
if (_streamStatus != NSStreamStatusClosed) {
_streamStatus = NSStreamStatusClosed;
RKLogTrace(@"RKParams stream closed. Releasing self.");
#if TARGET_OS_IPHONE
// NOTE: When we are assigned to the URL request, we get
// retained. We release ourselves here to ensure the retain
// count will hit zero after upload is complete.
//
// This behavior does not seem to happen on iOS 5. This is a workaround until
// the problem can be analyzed in more detail
if ([[[UIDevice currentDevice] systemVersion] compare:@"5.0" options:NSNumericSearch] == NSOrderedAscending) {
[self release];
}
#endif
}
}
- (NSStreamStatus)streamStatus {
if (_streamStatus != NSStreamStatusClosed && _bytesDelivered >= _length) {
_streamStatus = NSStreamStatusAtEnd;
}
return _streamStatus;
}
– (NSArray *)attachments {
return [NSArray arrayWithArray:_attachments];
}
– (NSString *)MD5 {
NSMutableString *attachmentsMD5 = [[NSMutableString new] autorelease];
for (RKParamsAttachment *attachment in self.attachments) {
[attachmentsMD5 appendString:[attachment MD5]];
}
return [attachmentsMD5 MD5];
}
#pragma mark Core Foundation stream methods
– (void)_scheduleInCFRunLoop:(NSRunLoop *)runLoop forMode:(id)mode {
}
– (void)_setCFClientFlags:(CFOptionFlags)flags callback:(CFReadStreamClientCallBack)callback context:(CFStreamClientContext)context {
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKParams.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKParamsAttachment.h
//
// RKParamsAttachment.h
// RestKit
//
// Created by Blake Watters on 8/6/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
Models an individual part of a multi-part MIME document. These attachments are
stacked together within the RKParams document to allow for uploading files via
HTTP.
Typically, interactions with the RKParamsAttachment are accomplished through
the RKParams class and there shouldn’t be much need to deal directly with this
class.
*/
@interface RKParamsAttachment : NSObject {
NSString *_name;
NSString *_fileName;
NSString *_MIMEType;
@private
NSString *_filePath;
NSData *_body;
NSInputStream *_bodyStream;
NSData *_MIMEHeader;
NSUInteger _MIMEHeaderLength;
NSUInteger _bodyLength;
NSUInteger _length;
NSUInteger _delivered;
id
}
///—————————————————————————–
/// @name Creating an Attachment
///—————————————————————————–
/**
Returns a newly initialized attachment with a given parameter name and value.
@param name The parameter name of this attachment in the multi-part document.
@param value A value that is used to create the attachment body
@return An initialized attachment with the given name and value.
*/
– (id)initWithName:(NSString *)name value:(id
/**
Returns a newly initialized attachment with a given parameter name and the data
stored in an NSData object.
@param name The parameter name of this attachment in the multi-part document.
@param data The data that is used to create the attachment body.
@return An initialized attachment with the given name and data.
*/
– (id)initWithName:(NSString *)name data:(NSData *)data;
/**
Returns a newly initialized attachment with a given parameter name and the data
stored on disk at the given file path.
@param name The parameter name of this attachment in the multi-part document.
@param filePath The complete path of a file to use its data contents as the
attachment body.
@return An initialized attachment with the name and the contents of the file at
the path given.
*/
– (id)initWithName:(NSString *)name file:(NSString *)filePath;
///—————————————————————————–
/// @name Working with the Attachment
///—————————————————————————–
/**
The parameter name of this attachment in the multi-part document.
*/
@property (nonatomic, retain) NSString *name;
/**
The MIME type of the attached file in the MIME stream. MIME Type will be
auto-detected from the file extension of the attached file.
**Default**: nil
*/
@property (nonatomic, retain) NSString *MIMEType;
/**
The MIME boundary string
*/
@property (nonatomic, readonly) NSString *MIMEBoundary;
/**
The complete path to the attached file on disk.
*/
@property (nonatomic, readonly) NSString *filePath;
/**
The name of the attached file in the MIME stream
**Default**: The name of the file attached or nil if there is not one.
*/
@property (nonatomic, retain) NSString *fileName;
/**
The value that is set when initialized through initWithName:value:
*/
@property (nonatomic, retain) id
/**
Open the attachment stream to begin reading. This will generate a MIME header
and prepare the attachment for writing to an RKParams stream.
*/
– (void)open;
/**
The length of the entire attachment including the MIME header and the body.
@return Unsigned integer of the MIME header and the body.
*/
– (NSUInteger)length;
/**
Calculate and return an MD5 checksum for the body of this attachment.
This works for simple values, NSData structures in memory, or by efficiently
streaming a file and calculating an MD5.
*/
– (NSString *)MD5;
///—————————————————————————–
/// @name Input streaming
///—————————————————————————–
/**
Read the attachment body in a streaming fashion for NSInputStream.
@param buffer A data buffer. The buffer must be large enough to contain the
number of bytes specified by len.
@param len The maximum number of bytes to read.
@return A number indicating the outcome of the operation:
– A positive number indicates the number of bytes read;
– 0 indicates that the end of the buffer was reached;
– A negative number means that the operation failed.
*/
– (NSUInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKParamsAttachment.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKParamsAttachment.m
//
// RKParamsAttachment.m
// RestKit
//
// Created by Blake Watters on 8/6/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKParamsAttachment.h”
#import “RKLog.h”
#import “NSData+RKAdditions.h”
#import “FileMD5Hash.h”
#import “NSString+RKAdditions.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
/**
* The multi-part boundary. See RKParams.m
*/
extern NSString* const kRKStringBoundary;
@implementation RKParamsAttachment
@synthesize filePath = _filePath;
@synthesize fileName = _fileName;
@synthesize MIMEType = _MIMEType;
@synthesize name = _name;
@synthesize value = _value;
– (id)initWithName:(NSString *)name {
self = [self init];
if (self) {
self.name = name;
self.fileName = name;
}
return self;
}
– (id)initWithName:(NSString *)name value:(id
if ((self = [self initWithName:name])) {
if ([value respondsToSelector:@selector(dataUsingEncoding:)]) {
_body = [[(NSString*)value dataUsingEncoding:NSUTF8StringEncoding] retain];
} else {
_body = [[[NSString stringWithFormat:@”%@”, value] dataUsingEncoding:NSUTF8StringEncoding] retain];
}
_bodyStream = [[NSInputStream alloc] initWithData:_body];
_bodyLength = [_body length];
_value = [value retain];
}
return self;
}
– (id)initWithName:(NSString*)name data:(NSData*)data {
self = [self initWithName:name];
if (self) {
_body = [data retain];
_bodyStream = [[NSInputStream alloc] initWithData:data];
_bodyLength = [data length];
}
return self;
}
– (id)initWithName:(NSString*)name file:(NSString*)filePath {
self = [self initWithName:name];
if (self) {
NSAssert1([[NSFileManager defaultManager] fileExistsAtPath:filePath], @”Expected file to exist at path: %@”, filePath);
_filePath = [filePath retain];
_fileName = [[filePath lastPathComponent] retain];
NSString *MIMEType = [filePath MIMETypeForPathExtension];
if (! MIMEType) MIMEType = @”application/octet-stream”;
_MIMEType = [MIMEType retain];
_bodyStream = [[NSInputStream alloc] initWithFileAtPath:filePath];
NSError* error;
NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error];
if (attributes) {
_bodyLength = [[attributes objectForKey:NSFileSize] unsignedIntegerValue];
}
else {
RKLogError(@”Encountered an error while determining file size: %@”, error);
}
}
return self;
}
– (void)dealloc {
[_value release];
[_name release];
[_body release];
[_filePath release];
[_fileName release];
[_MIMEType release];
[_MIMEHeader release];
_MIMEHeader = nil;
[_bodyStream close];
[_bodyStream release];
_bodyStream = nil;
[super dealloc];
}
– (NSString*)MIMEBoundary {
return kRKStringBoundary;
}
#pragma mark NSStream methods
– (void)open {
// Generate the MIME header for this part
if (self.fileName && self.MIMEType) {
// Typical for file attachments
_MIMEHeader = [[[NSString stringWithFormat:@”–%@\r\nContent-Disposition: form-data; name=\”%@\”; ”
@”filename=\”%@\”\r\nContent-Type: %@\r\n\r\n”,
[self MIMEBoundary], self.name, self.fileName, self.MIMEType] dataUsingEncoding:NSUTF8StringEncoding] retain];
} else if (self.MIMEType) {
// Typical for data values
_MIMEHeader = [[[NSString stringWithFormat:@”–%@\r\nContent-Disposition: form-data; name=\”%@\”\r\n”
@”Content-Type: %@\r\n\r\n”,
[self MIMEBoundary], self.name, self.MIMEType] dataUsingEncoding:NSUTF8StringEncoding] retain];
} else {
// Typical for raw values
_MIMEHeader = [[[NSString stringWithFormat:@”–%@\r\nContent-Disposition: form-data; name=\”%@\”\r\n\r\n”,
[self MIMEBoundary], self.name]
dataUsingEncoding:NSUTF8StringEncoding] retain];
}
// Calculate lengths
_MIMEHeaderLength = [_MIMEHeader length];
_length = _MIMEHeaderLength + _bodyLength + 2; // \r\n is the + 2
// Open the stream
[_bodyStream open];
}
– (NSUInteger)length {
return _length;
}
– (NSUInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)maxLength {
NSUInteger sent = 0, read;
// We are done with the read
if (_delivered >= _length) {
return 0;
}
// First we send back the MIME headers
if (_delivered < _MIMEHeaderLength && sent < maxLength) {
NSUInteger headerBytesRemaining, bytesRemainingInBuffer;
headerBytesRemaining = _MIMEHeaderLength - _delivered;
bytesRemainingInBuffer = maxLength;
// Send the entire header if there is room
read = (headerBytesRemaining < bytesRemainingInBuffer) ? headerBytesRemaining : bytesRemainingInBuffer;
[_MIMEHeader getBytes:buffer range:NSMakeRange(_delivered, read)];
sent += read;
_delivered += sent;
}
// Read the attachment body out of our underlying stream
while (_delivered >= _MIMEHeaderLength && _delivered < (_length - 2) && sent < maxLength) {
if ((read = [_bodyStream read:(buffer + sent) maxLength:(maxLength - sent)]) == 0) {
break;
}
sent += read;
_delivered += read;
}
// Append the \r\n
if (_delivered >= (_length – 2) && sent < maxLength) {
if (_delivered == (_length - 2)) {
*(buffer + sent) = '\r';
sent ++;
_delivered ++;
}
*(buffer + sent) = '\n';
sent ++;
_delivered ++;
}
return sent;
}
- (NSString *)MD5 {
if (_body) {
return [_body MD5];
} else if (_filePath) {
CFStringRef fileAttachmentMD5 = FileMD5HashCreateWithPath((CFStringRef)_filePath,
FileHashDefaultChunkSizeForReadingData);
return [(NSString *)fileAttachmentMD5 autorelease];
} else {
RKLogWarning(@"Failed to generate MD5 for attachment: unknown data type.");
return nil;
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKParamsAttachment.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKReachabilityObserver.h
//
// RKReachabilityObserver.h
// RestKit
//
// Created by Blake Watters on 9/14/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import
///—————————————————————————–
/// @name Constants
///—————————————————————————–
/**
Posted when the network state has changed
*/
extern NSString * const RKReachabilityDidChangeNotification;
/**
User Info key for accessing the SCNetworkReachabilityFlags from a
RKReachabilityDidChangeNotification
*/
extern NSString * const RKReachabilityFlagsUserInfoKey;
/**
Posted when network state has been initially determined
*/
extern NSString * const RKReachabilityWasDeterminedNotification;
typedef enum {
/**
Network reachability not yet known
*/
RKReachabilityIndeterminate,
/**
Network is not reachable
*/
RKReachabilityNotReachable,
/**
Network is reachable via a WiFi connection
*/
RKReachabilityReachableViaWiFi,
/**
Network is reachable via a “wireless wide area network” (WWAN). i.e. GPRS,
Edge, 3G, etc.
*/
RKReachabilityReachableViaWWAN
} RKReachabilityNetworkStatus;
/**
Provides a notification based interface for monitoring changes
to network status.
When initialized, creates an SCReachabilityReg and schedules it for callback
notifications on the main dispatch queue. As notifications are intercepted from
SystemConfiguration, the observer will update its state and emit
`[RKReachabilityDidChangeNotifications](RKReachabilityDidChangeNotification)`
to inform listeners about state changes.
Portions of this software are derived from the Apple Reachability
code sample: http://developer.apple.com/library/ios/#samplecode/Reachability/Listings/Classes_Reachability_m.html
*/
@interface RKReachabilityObserver : NSObject {
NSString *_host;
SCNetworkReachabilityRef _reachabilityRef;
BOOL _reachabilityDetermined;
BOOL _monitoringLocalWiFi;
SCNetworkReachabilityFlags _reachabilityFlags;
}
///—————————————————————————–
/// @name Creating a Reachability Observer
///—————————————————————————–
/**
Creates and returns a RKReachabilityObserver instance observing reachability
changes to the hostname or IP address referenced in a given string. The
observer will monitor the ability to reach the specified remote host and emit
notifications when its reachability status changes.
The hostNameOrIPAddress will be introspected to determine if it contains an IP
address encoded into a string or a DNS name. The observer will be configured
appropriately based on the contents of the string.
@bug Note that iOS 5 has known issues with hostname based reachability
@param hostNameOrIPAddress An NSString containing a hostname or IP address to
be observed.
@return A reachability observer targeting the given hostname/IP address or nil
if it could not be observed.
*/
+ (RKReachabilityObserver *)reachabilityObserverForHost:(NSString *)hostNameOrIPAddress;
/**
Creates and returns a reachabilityObserverForInternet instance observing the
reachability to the Internet in general.
@return A reachability observer targeting INADDR_ANY or nil if it could not be
observed.
*/
+ (RKReachabilityObserver *)reachabilityObserverForInternet;
/**
Creates and returns a reachabilityObserverForInternet instance observing the
reachability to the Internet via the local WiFi interface. Internet access
available via the WWAN (3G, Edge, etc) will not be considered reachable.
@return A reachability observer targeting IN_LINKLOCALNETNUM or nil if it could
not be observed.
*/
+ (RKReachabilityObserver *)reachabilityObserverForLocalWifi;
/**
Creates and returns a RKReachabilityObserver instance observing reachability
changes to the sockaddr address provided.
@param address A socket address to determine reachability for.
@return A reachability observer targeting the given socket address or nil if it
could not be observed.
*/
+ (RKReachabilityObserver *)reachabilityObserverForAddress:(const struct sockaddr *)address;
/**
Creates and returns a RKReachabilityObserver instance observing reachability
changes to the IP address provided.
@param internetAddress A 32-bit integer representation of an IP address
@return A reachability observer targeting the given IP address or nil if it
could not be observed.
*/
+ (RKReachabilityObserver *)reachabilityObserverForInternetAddress:(in_addr_t)internetAddress;
/**
Returns a RKReachabilityObserver instance observing reachability changes to the
hostname or IP address referenced in a given string. The observer will monitor
the ability to reach the specified remote host and emit notifications when its
reachability status changes.
The hostNameOrIPAddress will be introspected to determine if it contains an IP
address encoded into a string or a DNS name. The observer will be configured
appropriately based on the contents of the string.
@bug Note that iOS 5 has known issues with hostname based reachability
@param hostNameOrIPAddress An NSString containing a hostname or IP address to
be observed.
@return A reachability observer targeting the given hostname/IP address or nil
if it could not be observed.
*/
– (id)initWithHost:(NSString *)hostNameOrIPAddress;
/**
Returns a RKReachabilityObserver instance observing reachability changes to the
sockaddr address provided.
@param address A socket address to determine reachability for.
@return A reachability observer targeting the given socket address or nil if it
could not be observed.
*/
– (id)initWithAddress:(const struct sockaddr *)address;
///—————————————————————————–
/// @name Determining the Host
///—————————————————————————–
/**
The remote hostname or IP address being observed for reachability.
*/
@property (nonatomic, readonly) NSString *host;
///—————————————————————————–
/// @name Managing Reachability States
///—————————————————————————–
/**
Current state of determining reachability
When initialized, RKReachabilityObserver instances are in an indeterminate
state to indicate that reachability status has not been yet established. After
the first callback is processed by the observer, the observer will answer YES
for reachabilityDetermined and networkStatus will return a determinate
response.
@return YES if reachability has been determined
*/
@property (nonatomic, readonly, getter=isReachabilityDetermined) BOOL reachabilityDetermined;
/**
Current network status as determined by examining the state of the currently
cached reachabilityFlags
@return Status of the network as RKReachabilityNetworkStatus
*/
@property (nonatomic, readonly) RKReachabilityNetworkStatus networkStatus;
/**
Current state of the local WiFi interface’s reachability
When the local WiFi interface is being monitored, only three reachability
states are possible:
– RKReachabilityIndeterminate
– RKReachabilityNotReachable
– RKReachabilityReachableViaWiFi
If the device has connectivity through a WWAN connection only it will consider
the network not reachable.
@see reachabilityObserverForLocalWifi
@return YES if the reachability observer is monitoring the local WiFi interface
*/
@property (nonatomic, readonly, getter=isMonitoringLocalWiFi) BOOL monitoringLocalWiFi;
/**
The reachability flags as of the last invocation of the reachability callback
Each time the reachability callback is invoked with an asynchronous update of
reachability status the flags are cached and made accessible via the
reachabilityFlags method.
Flags can also be directly obtained via [RKReachabilityObserver getFlags]
@see getFlags
@return The most recently cached reachability flags reflecting current network
status.
*/
@property (nonatomic, readonly) SCNetworkReachabilityFlags reachabilityFlags;
/**
Acquires the current network reachability flags, answering YES if
successfully acquired; answering NO otherwise.
Beware! The System Configuration framework operates synchronously by
default. See Technical Q&A QA1693, Synchronous Networking On The Main
Thread. Asking for flags blocks the current thread and potentially kills your
iOS application if the reachability enquiry does not respond before the
watchdog times out.
*/
– (BOOL)getFlags;
///—————————————————————————–
/// @name Reachability Introspection
///—————————————————————————–
/**
Returns YES when the Internet is reachable (via WiFi or WWAN)
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isNetworkReachable;
/**
Returns YES when we the network is reachable via WWAN
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isReachableViaWWAN;
/**
Returns YES when we the network is reachable via WiFi
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isReachableViaWiFi;
/**
Returns YES when WWAN may be available, but not active until a connection has been established.
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isConnectionRequired;
/**
Returns YES if a dynamic, on-demand connection is available
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isConnectionOnDemand;
/**
Returns YES if user intervention is required to initiate a connection
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if called before reachability is determined
*/
– (BOOL)isInterventionRequired;
/**
Returns a string representation of the currently cached reachabilityFlags for inspection
@return A string containing single character representations of the bits in an
SCNetworkReachabilityFlags
*/
– (NSString *)reachabilityFlagsDescription;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKReachabilityObserver.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKReachabilityObserver.m
//
// RKReachabilityObserver.m
// RestKit
//
// Created by Blake Watters on 9/14/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#endif
#import “RKReachabilityObserver.h”
#include
#include
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetworkReachability
@interface RKReachabilityObserver (Private)
@property (nonatomic, assign) SCNetworkReachabilityFlags reachabilityFlags;
// Internal initializer
– (id)initWithReachabilityRef:(SCNetworkReachabilityRef)reachabilityRef;
– (void)scheduleObserver;
– (void)unscheduleObserver;
@end
// Constants
NSString* const RKReachabilityDidChangeNotification = @”RKReachabilityDidChangeNotification”;
NSString* const RKReachabilityFlagsUserInfoKey = @”RKReachabilityFlagsUserInfoKey”;
NSString* const RKReachabilityWasDeterminedNotification = @”RKReachabilityWasDeterminedNotification”;
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
RKReachabilityObserver *observer = (RKReachabilityObserver *) info;
observer.reachabilityFlags = flags;
[pool release];
}
#pragma mark –
@implementation RKReachabilityObserver
@synthesize host = _host;
@synthesize reachabilityFlags = _reachabilityFlags;
@synthesize reachabilityDetermined = _reachabilityDetermined;
@synthesize monitoringLocalWiFi = _monitoringLocalWiFi;
+ (RKReachabilityObserver *)reachabilityObserverForAddress:(const struct sockaddr *)address {
return [[[self alloc] initWithAddress:address] autorelease];
}
+ (RKReachabilityObserver *)reachabilityObserverForInternetAddress:(in_addr_t)internetAddress {
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(internetAddress);
return [self reachabilityObserverForAddress:(struct sockaddr *)&address];
}
+ (RKReachabilityObserver *)reachabilityObserverForInternet {
return [self reachabilityObserverForInternetAddress:INADDR_ANY];
}
+ (RKReachabilityObserver *)reachabilityObserverForLocalWifi {
return [self reachabilityObserverForInternetAddress:IN_LINKLOCALNETNUM];
}
+ (RKReachabilityObserver *)reachabilityObserverForHost:(NSString *)hostNameOrIPAddress {
return [[[self alloc] initWithHost:hostNameOrIPAddress] autorelease];
}
– (id)initWithAddress:(const struct sockaddr *)address {
self = [super init];
if (self) {
_reachabilityRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, address);
if (_reachabilityRef == NULL) {
RKLogWarning(@”Unable to initialize reachability reference”);
[self release];
self = nil;
} else {
// For technical details regarding link-local connections, please
// see the following source file at Apple’s open-source site.
//
// http://www.opensource.apple.com/source/bootp/bootp-89/IPConfiguration.bproj/linklocal.c
//
_monitoringLocalWiFi = address->sa_len == sizeof(struct sockaddr_in) && address->sa_family == AF_INET && IN_LINKLOCAL(ntohl(((const struct sockaddr_in *)address)->sin_addr.s_addr));
// Save the IP address
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((const struct sockaddr_in *)address)->sin_addr, str, INET_ADDRSTRLEN);
_host = [[NSString alloc] initWithCString:str encoding:NSUTF8StringEncoding];
if (_monitoringLocalWiFi) {
RKLogInfo(@”Reachability observer initialized for Local Wifi”);
} else if (address->sa_len == sizeof(struct sockaddr_in) && address->sa_family == AF_INET) {
RKLogInfo(@”Reachability observer initialized with IP address: %@.”, _host);
}
// We can immediately determine reachability to an IP address
dispatch_async(dispatch_get_main_queue(), ^{
// Obtain the flags after giving other objects a chance to observe us
[self getFlags];
});
// Schedule the observer
[self scheduleObserver];
}
}
return self;
}
– (id)initWithHost:(NSString *)hostNameOrIPAddress {
// Determine if the string contains a hostname or IP address
struct sockaddr_in sa;
char *hostNameOrIPAddressCString = (char *) [hostNameOrIPAddress UTF8String];
int result = inet_pton(AF_INET, hostNameOrIPAddressCString, &(sa.sin_addr));
if (result != 0) {
// IP Address
struct sockaddr_in remote_saddr;
bzero(&remote_saddr, sizeof(struct sockaddr_in));
remote_saddr.sin_len = sizeof(struct sockaddr_in);
remote_saddr.sin_family = AF_INET;
inet_aton(hostNameOrIPAddressCString, &(remote_saddr.sin_addr));
return [self initWithAddress:(struct sockaddr *) &remote_saddr];
}
// Hostname
self = [self init];
if (self) {
_host = [hostNameOrIPAddress retain];
_reachabilityRef = SCNetworkReachabilityCreateWithName(CFAllocatorGetDefault(), hostNameOrIPAddressCString);
RKLogInfo(@”Reachability observer initialized with hostname %@”, hostNameOrIPAddress);
if (_reachabilityRef == NULL) {
RKLogWarning(@”Unable to initialize reachability reference”);
[self release];
self = nil;
} else {
[self scheduleObserver];
}
}
return self;
}
– (void)dealloc {
RKLogTrace(@”Deallocating reachability observer %@”, self);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self unscheduleObserver];
if (_reachabilityRef) {
CFRelease(_reachabilityRef);
}
[_host release];
[super dealloc];
}
– (BOOL)getFlags {
SCNetworkReachabilityFlags flags = 0;
BOOL result = SCNetworkReachabilityGetFlags(_reachabilityRef, &flags);
if (result) self.reachabilityFlags = flags;
return result;
}
– (NSString *)stringFromNetworkStatus:(RKReachabilityNetworkStatus)status {
switch (status) {
case RKReachabilityIndeterminate:
return @”RKReachabilityIndeterminate”;
break;
case RKReachabilityNotReachable:
return @”RKReachabilityNotReachable”;
break;
case RKReachabilityReachableViaWiFi:
return @”RKReachabilityReachableViaWiFi”;
break;
case RKReachabilityReachableViaWWAN:
return @”RKReachabilityReachableViaWWAN”;
break;
default:
break;
}
return nil;
}
– (NSString *)reachabilityFlagsDescription {
return [NSString stringWithFormat:@”%c%c %c%c%c%c%c%c%c”,
#if TARGET_OS_IPHONE
(_reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN) ? ‘W’ : ‘-‘,
#else
// If we are not on iOS, always output a dash for WWAN
‘-‘,
#endif
(_reachabilityFlags & kSCNetworkReachabilityFlagsReachable) ? ‘R’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsTransientConnection) ? ‘t’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired) ? ‘c’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? ‘C’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsInterventionRequired) ? ‘i’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? ‘D’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsIsLocalAddress) ? ‘l’ : ‘-‘,
(_reachabilityFlags & kSCNetworkReachabilityFlagsIsDirect) ? ‘d’ : ‘-‘];
}
– (RKReachabilityNetworkStatus)networkStatus {
NSAssert(_reachabilityRef != NULL, @”currentNetworkStatus called with NULL reachabilityRef”);
RKReachabilityNetworkStatus status = RKReachabilityNotReachable;
if (!self.reachabilityDetermined) {
RKLogTrace(@”Reachability observer %@ has not yet established reachability. networkStatus = %@”, self, @”RKReachabilityIndeterminate”);
return RKReachabilityIndeterminate;
}
RKLogTrace(@”Reachability Flags: %@\n”, [self reachabilityFlagsDescription]);
// If we are observing WiFi, we are only reachable via WiFi when flags are direct
if (self.isMonitoringLocalWiFi) {
if ((_reachabilityFlags & kSCNetworkReachabilityFlagsReachable) && (_reachabilityFlags & kSCNetworkReachabilityFlagsIsDirect)) {
// <-- reachable AND direct
status = RKReachabilityReachableViaWiFi;
} else {
// <-- NOT reachable OR NOT direct
status = RKReachabilityNotReachable;
}
} else {
if ((_reachabilityFlags & kSCNetworkReachabilityFlagsReachable)) {
// <-- reachable
#if TARGET_OS_IPHONE
if ((_reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN)) {
// <-- reachable AND is wireless wide-area network (iOS only)
status = RKReachabilityReachableViaWWAN;
} else {
#endif
// <-- reachable AND is NOT wireless wide-area network (iOS only)
if ((_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionOnTraffic) || (_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionOnDemand)) {
// <-- reachable, on-traffic OR on-demand connection
if ((_reachabilityFlags & kSCNetworkReachabilityFlagsInterventionRequired)) {
// <-- reachable, on-traffic OR on-demand connection, intervention required
status = (_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired) ? RKReachabilityNotReachable : RKReachabilityReachableViaWiFi;
} else {
// <-- reachable, on-traffic OR on-demand connection, intervention NOT required
status = RKReachabilityReachableViaWiFi;
}
} else {
// <-- reachable, NOT on-traffic OR on-demand connection
status = (_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired) ? RKReachabilityNotReachable : RKReachabilityReachableViaWiFi;
}
#if TARGET_OS_IPHONE
}
#endif
} else {
// <-- NOT reachable
status = RKReachabilityNotReachable;
}
}
RKLogTrace(@"Reachability observer %@ determined networkStatus = %@", self, [self stringFromNetworkStatus:status]);
return status;
}
#pragma Reachability Flag Introspection
- (void)validateIntrospection {
NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
NSAssert(self.isReachabilityDetermined, @"Cannot inspect reachability state: no reachabilityFlags available. Be sure to check isReachabilityDetermined");
}
- (BOOL)isNetworkReachable {
[self validateIntrospection];
BOOL reachable = (RKReachabilityNotReachable != [self networkStatus]);
RKLogDebug(@"Reachability observer %@ determined isNetworkReachable = %d", self, reachable);
return reachable;
}
- (BOOL)isConnectionRequired {
[self validateIntrospection];
BOOL required = (_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired);
RKLogDebug(@"Reachability observer %@ determined isConnectionRequired = %d", self, required);
return required;
}
- (BOOL)isReachableViaWWAN {
[self validateIntrospection];
return self.networkStatus == RKReachabilityReachableViaWWAN;
}
- (BOOL)isReachableViaWiFi {
[self validateIntrospection];
return self.networkStatus == RKReachabilityReachableViaWiFi;
}
- (BOOL)isConnectionOnDemand {
[self validateIntrospection];
return ((_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired) &&
(_reachabilityFlags & (kSCNetworkReachabilityFlagsConnectionOnTraffic |
kSCNetworkReachabilityFlagsConnectionOnDemand)));
}
- (BOOL)isInterventionRequired {
[self validateIntrospection];
return ((_reachabilityFlags & kSCNetworkReachabilityFlagsConnectionRequired) &&
(_reachabilityFlags & kSCNetworkReachabilityFlagsInterventionRequired));
}
#pragma mark Observer scheduling
- (void)scheduleObserver {
SCNetworkReachabilityContext context = { .info = self };
RKLogDebug(@"Scheduling reachability observer %@ in main dispatch queue", self);
if (! SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context)) {
RKLogWarning(@"%@: SCNetworkReachabilitySetCallback() failed: %s", self, SCErrorString(SCError()));
return;
}
if (! SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, dispatch_get_main_queue())) {
RKLogWarning("%@: SCNetworkReachabilitySetDispatchQueue() failed: %s", self, SCErrorString(SCError()));
return;
}
}
- (void)unscheduleObserver {
if (_reachabilityRef) {
RKLogDebug(@"%@: Unscheduling reachability observer from main dispatch queue", self);
if (! SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, NULL)) {
RKLogWarning("%@: SCNetworkReachabilitySetDispatchQueue() failed: %s\n", self, SCErrorString(SCError()));
return;
}
} else {
RKLogDebug(@"%@: Failed to unschedule reachability observer %@: reachability reference is nil.", self, _reachabilityRef);
}
}
- (void)setReachabilityFlags:(SCNetworkReachabilityFlags)reachabilityFlags {
// Save the reachability flags
_reachabilityFlags = reachabilityFlags;
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:reachabilityFlags] forKey:RKReachabilityFlagsUserInfoKey];
if (! self.reachabilityDetermined) {
_reachabilityDetermined = YES;
RKLogInfo(@"Network availability has been determined for reachability observer %@", self);
[[NSNotificationCenter defaultCenter] postNotificationName:RKReachabilityWasDeterminedNotification object:self userInfo:userInfo];
}
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName:RKReachabilityDidChangeNotification object:self userInfo:userInfo];
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p host=%@ isReachabilityDetermined=%@ isMonitoringLocalWiFi=%d reachabilityFlags=%@>“,
NSStringFromClass([self class]), self, self.host, self.isReachabilityDetermined ? @”YES” : @”NO”,
self.isMonitoringLocalWiFi ? @”YES” : @”NO”, [self reachabilityFlagsDescription]];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKReachabilityObserver.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequest.h
//
// RKRequest.h
// RestKit
//
// Created by Jeremy Ellison on 7/27/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#endif
#import
#import
#import “RKRequestSerializable.h”
@class RKRequestCache;
/**
HTTP methods for requests
*/
typedef enum RKRequestMethod {
RKRequestMethodInvalid = -1,
RKRequestMethodGET,
RKRequestMethodPOST,
RKRequestMethodPUT,
RKRequestMethodDELETE,
RKRequestMethodHEAD
} RKRequestMethod;
NSString *RKRequestMethodNameFromType(RKRequestMethod);
RKRequestMethod RKRequestMethodTypeFromName(NSString *);
/**
Cache policy for determining how to use RKCache
*/
typedef enum {
/**
Never use the cache
*/
RKRequestCachePolicyNone = 0,
/**
Load from the cache when we are offline
*/
RKRequestCachePolicyLoadIfOffline = 1 << 0,
/**
Load from the cache if we encounter an error
*/
RKRequestCachePolicyLoadOnError = 1 << 1,
/**
Load from the cache if we have data stored and the server returns a 304
(not modified) response
*/
RKRequestCachePolicyEtag = 1 << 2,
/**
Load from the cache if we have data stored
*/
RKRequestCachePolicyEnabled = 1 << 3,
/**
Load from the cache if we are within the timeout window
*/
RKRequestCachePolicyTimeout = 1 << 4,
/**
The default cache policy is etag and timeout support
*/
RKRequestCachePolicyDefault = RKRequestCachePolicyEtag | RKRequestCachePolicyTimeout
} RKRequestCachePolicy;
#if TARGET_OS_IPHONE
/**
Background Request Policy
On iOS 4.x and higher, UIKit provides support for continuing activities for a
limited amount of time in the background. RestKit provides simple support for
continuing a request when in the background.
*/
typedef enum RKRequestBackgroundPolicy {
/**
Take no action with regards to backgrounding
*/
RKRequestBackgroundPolicyNone = 0,
/**
Cancel the request on transition to the background
*/
RKRequestBackgroundPolicyCancel,
/**
Continue the request in the background until time expires
*/
RKRequestBackgroundPolicyContinue,
/**
Stop the request and place it back on the queue. It will fire when the app
reopens.
*/
RKRequestBackgroundPolicyRequeue
} RKRequestBackgroundPolicy;
#endif
/**
Authentication type for the request
Based on the authentication type that is selected, authentication functionality
is triggered and other options may be required.
*/
typedef enum {
/**
Disable the use of authentication
*/
RKRequestAuthenticationTypeNone = 0,
/**
Use NSURLConnection's HTTP AUTH auto-negotiation
*/
RKRequestAuthenticationTypeHTTP,
/**
Force the use of HTTP Basic authentication.
This will supress AUTH challenges as RestKit will add an Authorization
header establishing login via HTTP basic. This is an optimization that
skips the challenge portion of the request.
*/
RKRequestAuthenticationTypeHTTPBasic,
/**
Enable the use of OAuth 1.0 authentication.
OAuth1ConsumerKey, OAuth1ConsumerSecret, OAuth1AccessToken, and
OAuth1AccessTokenSecret must be set when using this type.
*/
RKRequestAuthenticationTypeOAuth1,
/**
Enable the use of OAuth 2.0 authentication.
OAuth2AccessToken must be set when using this type.
*/
RKRequestAuthenticationTypeOAuth2
} RKRequestAuthenticationType;
@class RKRequest, RKResponse, RKRequestQueue, RKReachabilityObserver;
@protocol RKRequestDelegate, RKConfigurationDelegate;
///-----------------------------------------------------------------------------
/// @name Block Declarations
///-----------------------------------------------------------------------------
typedef void(^RKRequestDidLoadResponseBlock)(RKResponse *response);
typedef void(^RKRequestDidFailLoadWithErrorBlock)(NSError *error);
/**
Models the request portion of an HTTP request/response cycle.
*/
@interface RKRequest : NSObject {
BOOL _sentSynchronously;
NSURLConnection *_connection;
id
NSTimer *_timeoutTimer;
RKRequestCachePolicy _cachePolicy;
RKRequestDidLoadResponseBlock _onDidLoadResponse;
RKRequestDidFailLoadWithErrorBlock _onDidFailLoadWithError;
#if TARGET_OS_IPHONE
RKRequestBackgroundPolicy _backgroundPolicy;
UIBackgroundTaskIdentifier _backgroundTaskIdentifier;
#endif
}
///—————————————————————————–
/// @name Creating a Request
///—————————————————————————–
/**
Creates and returns a RKRequest object initialized to load content from a
provided URL.
@param URL The remote URL to load
@return An autoreleased RKRequest object initialized with URL.
*/
+ (RKRequest *)requestWithURL:(NSURL *)URL;
/**
Initializes a RKRequest object to load from a provided URL
@param URL The remote URL to load
@return An RKRequest object initialized with URL.
*/
– (id)initWithURL:(NSURL *)URL;
/**
Creates and returns a RKRequest object initialized to load content from a
provided URL with a specified delegate.
@bug **DEPRECATED** in v0.10.0: Use [RKRequest requestWithURL:] instead
@param URL The remote URL to load
@param delegate The delegate that will handle the response callbacks.
@return An autoreleased RKRequest object initialized with URL.
*/
+ (RKRequest *)requestWithURL:(NSURL *)URL delegate:(id)delegate DEPRECATED_ATTRIBUTE;
/**
Initializes a RKRequest object to load from a provided URL
@bug **DEPRECATED** in v0.10.0: Use [RKRequest initWithURL:] instead
@param URL The remote URL to load
@param delegate The delegate that will handle the response callbacks.
@return An RKRequest object initialized with URL.
*/
– (id)initWithURL:(NSURL *)URL delegate:(id)delegate DEPRECATED_ATTRIBUTE;
///—————————————————————————–
/// @name Setting Properties
///—————————————————————————–
/**
The URL this request is loading
*/
@property (nonatomic, retain) NSURL *URL;
/**
The resourcePath portion of the request’s URL
*/
@property (nonatomic, retain) NSString *resourcePath;
/**
The HTTP verb in which the request is sent
**Default**: RKRequestMethodGET
*/
@property (nonatomic, assign) RKRequestMethod method;
/**
Returns HTTP method as a string used for this request.
This should be set through the method property using an RKRequestMethod type.
@see [RKRequest method]
*/
@property (nonatomic, readonly) NSString *HTTPMethod;
/**
The response returned when the receiver was sent.
*/
@property (nonatomic, retain, readonly) RKResponse *response;
/**
A serializable collection of parameters sent as the HTTP body of the request
*/
@property (nonatomic, retain) NSObject
/**
A dictionary of additional HTTP Headers to send with the request
*/
@property (nonatomic, retain) NSDictionary *additionalHTTPHeaders;
/**
The run loop mode under which the underlying NSURLConnection is performed
*Default*: NSRunLoopCommonModes
*/
@property (nonatomic, copy) NSString *runLoopMode;
/**
* An opaque pointer to associate user defined data with the request.
*/
@property (nonatomic, retain) id userData;
/**
The underlying NSMutableURLRequest sent for this request
*/
@property (nonatomic, readonly) NSMutableURLRequest *URLRequest;
/**
The default value used to decode HTTP body content when HTTP headers received do not provide information on the content.
This encoding will be used by the RKResponse when creating the body content
*/
@property (nonatomic, assign) NSStringEncoding defaultHTTPEncoding;
///—————————————————————————–
/// @name Working with the HTTP Body
///—————————————————————————–
/**
Sets the request body using the provided NSDictionary after passing the
NSDictionary through serialization using the currently configured parser for
the provided MIMEType.
@param body An NSDictionary of key/value pairs to be serialized and sent as
the HTTP body.
@param MIMEType The MIMEType for the parser to use for the dictionary.
*/
– (void)setBody:(NSDictionary *)body forMIMEType:(NSString *)MIMEType;
/**
The HTTP body as a NSData used for this request
*/
@property (nonatomic, retain) NSData *HTTPBody;
/**
The HTTP body as a string used for this request
*/
@property (nonatomic, retain) NSString *HTTPBodyString;
///—————————————————————————–
/// @name Delegates
///—————————————————————————–
/**
The delegate to inform when the request is completed
If the object implements the RKRequestDelegate protocol, it will receive
request lifecycle event messages.
*/
@property (nonatomic, assign) id
/**
A delegate responsible for configuring the request. Centralizes common
configuration data (such as HTTP headers, authentication information, etc)
for re-use.
RKClient and RKObjectManager conform to the RKConfigurationDelegate protocol.
Request and object loader instances built through these objects will have a
reference to their parent client/object manager assigned as the configuration
delegate.
**Default**: nil
@see RKClient
@see RKObjectManager
*/
@property (nonatomic, assign) id
///—————————————————————————–
/// @name Handling Blocks
///—————————————————————————–
/**
A block to invoke when the receiver has loaded a response.
@see [RKRequestDelegate request:didLoadResponse:]
*/
@property (nonatomic, copy) RKRequestDidLoadResponseBlock onDidLoadResponse;
/**
A block to invoke when the receuver has failed loading due to an error.
@see [RKRequestDelegate request:didFailLoadWithError:]
*/
@property (nonatomic, copy) RKRequestDidFailLoadWithErrorBlock onDidFailLoadWithError;
/**
Whether this request should follow server redirects or not.
@default YES
*/
@property (nonatomic, assign) BOOL followRedirect;
#if TARGET_OS_IPHONE
///—————————————————————————–
/// @name Background Tasks
///—————————————————————————–
/**
The policy to take on transition to the background (iOS 4.x and higher only)
**Default:** RKRequestBackgroundPolicyCancel
*/
@property (nonatomic, assign) RKRequestBackgroundPolicy backgroundPolicy;
/**
Returns the identifier of the task that has been sent to the background.
*/
@property (nonatomic, readonly) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
#endif
///—————————————————————————–
/// @name Authentication
///—————————————————————————–
/**
The type of authentication to use for this request.
This must be assigned one of the following:
– `RKRequestAuthenticationTypeNone`: Disable the use of authentication
– `RKRequestAuthenticationTypeHTTP`: Use NSURLConnection’s HTTP AUTH
auto-negotiation
– `RKRequestAuthenticationTypeHTTPBasic`: Force the use of HTTP Basic
authentication. This will supress AUTH challenges as RestKit will add an
Authorization header establishing login via HTTP basic. This is an
optimization that skips the challenge portion of the request.
– `RKRequestAuthenticationTypeOAuth1`: Enable the use of OAuth 1.0
authentication. OAuth1ConsumerKey, OAuth1ConsumerSecret, OAuth1AccessToken,
and OAuth1AccessTokenSecret must be set.
– `RKRequestAuthenticationTypeOAuth2`: Enable the use of OAuth 2.0
authentication. OAuth2AccessToken must be set.
**Default**: RKRequestAuthenticationTypeNone
*/
@property (nonatomic, assign) RKRequestAuthenticationType authenticationType;
/**
The username to use for authentication via HTTP AUTH.
Used to respond to an authentication challenge when authenticationType is
RKRequestAuthenticationTypeHTTP or RKRequestAuthenticationTypeHTTPBasic.
@see authenticationType
*/
@property (nonatomic, retain) NSString *username;
/**
The password to use for authentication via HTTP AUTH.
Used to respond to an authentication challenge when authenticationType is
RKRequestAuthenticationTypeHTTP or RKRequestAuthenticationTypeHTTPBasic.
@see authenticationType
*/
@property (nonatomic, retain) NSString *password;
///—————————————————————————–
/// @name OAuth1 Secrets
///—————————————————————————–
/**
The OAuth 1.0 consumer key
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1ConsumerKey;
/**
The OAuth 1.0 consumer secret
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1ConsumerSecret;
/**
The OAuth 1.0 access token
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1AccessToken;
/**
The OAuth 1.0 access token secret
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth1
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth1AccessTokenSecret;
///—————————————————————————–
/// @name OAuth2 Secrets
///—————————————————————————–
/**
The OAuth 2.0 access token
Used to build an Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth2
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth2AccessToken;
/**
The OAuth 2.0 refresh token
Used to retrieve a new access token before expiration and to build an
Authorization header when authenticationType is
RKRequestAuthenticationTypeOAuth2
@bug **NOT IMPLEMENTED**: This functionality is not yet implemented.
@see authenticationType
*/
@property (nonatomic, retain) NSString *OAuth2RefreshToken;
///—————————————————————————–
/// @name Caching
///—————————————————————————–
/**
Returns the cache key for getting/setting the cache entry for this request in
the cache.
The cacheKey is an MD5 value computed by hashing a combination of the
destination URL, the HTTP verb, and the request body (when possible).
*/
@property (nonatomic, readonly) NSString *cacheKey;
/**
The cache policy used when storing this request into the request cache
*/
@property (nonatomic, assign) RKRequestCachePolicy cachePolicy;
/**
The request cache to store and load responses for this request.
Generally configured by the RKClient instance that minted this request
This must be assigned one of the following:
– `RKRequestCachePolicyNone`: Never use the cache.
– `RKRequestCachePolicyLoadIfOffline`: Load from the cache when offline.
– `RKRequestCachePolicyLoadOnError`: Load from the cache if an error is
encountered.
– `RKRequestCachePolicyEtag`: Load from the cache if there is data stored and
the server returns a 304 (Not Modified) response.
– `RKRequestCachePolicyEnabled`: Load from the cache whenever data has been
stored.
– `RKRequestCachePolicyTimeout`: Load from the cache if the
cacheTimeoutInterval is reached before the server responds.
*/
@property (nonatomic, retain) RKRequestCache *cache;
/**
Returns YES if the request is cacheable
Only GET requests are considered cacheable (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html).
*/
– (BOOL)isCacheable;
/**
The timeout interval within which the request should not be sent and the cached
response should be used. Used if the cache policy includes
RKRequestCachePolicyTimeout.
*/
@property (nonatomic, assign) NSTimeInterval cacheTimeoutInterval;
///—————————————————————————–
/// @name Handling SSL Validation
///—————————————————————————–
/**
Flag for disabling SSL certificate validation.
When YES, SSL certificates will not be validated.
*Default*: NO
@warning **WARNING**: This is a potential security exposure and should be used
**ONLY while debugging** in a controlled environment.
*/
@property (nonatomic, assign) BOOL disableCertificateValidation;
/**
A set of additional certificates to be used in evaluating server SSL
certificates.
*/
@property (nonatomic, retain) NSSet *additionalRootCertificates;
///—————————————————————————–
/// @name Sending and Managing the Request
///—————————————————————————–
/**
Setup the NSURLRequest.
The request must be prepared right before dispatching.
@return A boolean for the success of the URL preparation.
*/
– (BOOL)prepareURLRequest;
/**
The request queue that this request belongs to
*/
@property (nonatomic, assign) RKRequestQueue *queue;
/**
Send the request asynchronously. It will be added to the queue and dispatched
as soon as possible.
*/
– (void)send;
/**
Immediately dispatch a request asynchronously, skipping the request queue.
*/
– (void)sendAsynchronously;
/**
Send the request synchronously and return a hydrated response object.
@return An RKResponse object with the result of the request.
*/
– (RKResponse *)sendSynchronously;
/**
Returns a Boolean value indicating whether the request has been cancelled.
@return YES if the request was sent a cancel message, otherwise NO.
*/
@property(nonatomic, assign, readonly, getter=isCancelled) BOOL cancelled;
/**
Cancels the underlying URL connection.
This will call the requestDidCancel: delegate method if your delegate responds
to it. This does not subsequently set the the request’s delegate to nil.
However, it’s good practice to cancel the RKRequest and immediately set the
delegate property to nil within the delegate’s dealloc method.
@see NSURLConnection:cancel
*/
– (void)cancel;
/**
The reachability observer to consult for network status. Used for performing
offline cache loads.
Generally configured by the RKClient instance that minted this request.
*/
@property (nonatomic, retain) RKReachabilityObserver *reachabilityObserver;
///—————————————————————————–
/// @name Resetting the State
///—————————————————————————–
/**
Resets the state of an RKRequest so that it can be re-sent.
*/
– (void)reset;
///—————————————————————————–
/// @name Callbacks
///—————————————————————————–
/**
Callback performed to notify the request that the underlying NSURLConnection
has failed with an error.
@param error An NSError object containing the RKRestKitError that triggered
the callback.
*/
– (void)didFailLoadWithError:(NSError *)error;
/**
Callback performed to notify the request that the underlying NSURLConnection
has completed with a response.
@param response An RKResponse object with the result of the request.
*/
– (void)didFinishLoad:(RKResponse *)response;
///—————————————————————————–
/// @name Timing Out the Request
///—————————————————————————–
/**
The timeout interval within which the request should be cancelled if no data
has been received.
The timeout timer is cancelled as soon as we start receiving data and are
expecting the request to finish.
**Default**: 120.0 seconds
*/
@property (nonatomic, assign) NSTimeInterval timeoutInterval;
/**
Creates a timeoutTimer to trigger the timeout method
This is mainly used so we can test that the timer is only being created once.
*/
– (void)createTimeoutTimer;
/**
Cancels request due to connection timeout exceeded.
This method is invoked by the timeoutTimer upon its expiration and will return
an RKRequestConnectionTimeoutError via didFailLoadWithError:
*/
– (void)timeout;
/**
Invalidates the timeout timer.
Called by RKResponse when the NSURLConnection begins receiving data.
*/
– (void)invalidateTimeoutTimer;
///—————————————————————————–
/// @name Determining the Request Type and State
///—————————————————————————–
/**
Returns YES when this is a GET request
*/
– (BOOL)isGET;
/**
Returns YES when this is a POST request
*/
– (BOOL)isPOST;
/**
Returns YES when this is a PUT request
*/
– (BOOL)isPUT;
/**
Returns YES when this is a DELETE request
*/
– (BOOL)isDELETE;
/**
Returns YES when this is a HEAD request
*/
– (BOOL)isHEAD;
/**
Returns YES when this request is in-progress
*/
@property (nonatomic, assign, readonly, getter = isLoading) BOOL loading;
/**
Returns YES when this request has been completed
*/
@property (nonatomic, assign, readonly, getter = isLoaded) BOOL loaded;
/**
Returns YES when this request has not yet been sent
*/
– (BOOL)isUnsent;
/**
Returns YES when the request was sent to the specified resource path
@param resourcePath A string of the resource path that we want to check against
*/
– (BOOL)wasSentToResourcePath:(NSString *)resourcePath;
/**
Returns YES when the receiver was sent to the specified resource path with a given request method.
@param resourcePath A string of the resource path that we want to check against
@param method The HTTP method to confirm the request was sent with.
*/
– (BOOL)wasSentToResourcePath:(NSString *)resourcePath method:(RKRequestMethod)method;
@end
/**
Lifecycle events for an RKRequest object
*/
@protocol RKRequestDelegate
@optional
///—————————————————————————–
/// @name Observing Request Progress
///—————————————————————————–
/**
Tells the delegate the request is about to be prepared for sending to the remote host.
@param request The RKRequest object that is about to be sent.
*/
– (void)requestWillPrepareForSend:(RKRequest *)request;
/**
Sent when a request has received a response from the remote host.
@param request The RKRequest object that received a response.
@param response The RKResponse object for the HTTP response that was received.
*/
– (void)request:(RKRequest *)request didReceiveResponse:(RKResponse *)response;
/**
Sent when a request has started loading
@param request The RKRequest object that has begun loading.
*/
– (void)requestDidStartLoad:(RKRequest *)request;
/**
Sent when a request has uploaded data to the remote site
@param request The RKRequest object that is handling the loading.
@param bytesWritten An integer of the bytes of the chunk just sent to the
remote site.
@param totalBytesWritten An integer of the total bytes that have been sent to
the remote site.
@param totalBytesExpectedToWrite An integer of the total bytes that will be
sent to the remote site.
*/
– (void)request:(RKRequest *)request didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
/**
Sent when request has received data from remote site
@param request The RKRequest object that is handling the loading.
@param bytesReceived An integer of the bytes of the chunk just received from
the remote site.
@param totalBytesReceived An integer of the total bytes that have been
received from the remote site.
@param totalBytesExpectedToReceive An integer of the total bytes that will be
received from the remote site.
*/
– (void)request:(RKRequest *)request didReceiveData:(NSInteger)bytesReceived totalBytesReceived:(NSInteger)totalBytesReceived totalBytesExpectedToReceive:(NSInteger)totalBytesExpectedToReceive;
///—————————————————————————–
/// @name Handling Successful Requests
///—————————————————————————–
/**
Sent when a request has finished loading
@param request The RKRequest object that was handling the loading.
@param response The RKResponse object containing the result of the request.
*/
– (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response;
///—————————————————————————–
/// @name Handling Failed Requests
///—————————————————————————–
/**
Sent when a request has failed due to an error
@param request The RKRequest object that was handling the loading.
@param error An NSError object containing the RKRestKitError that triggered
the callback.
*/
– (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error;
/**
Sent to the delegate when a request was cancelled
@param request The RKRequest object that was cancelled.
*/
– (void)requestDidCancelLoad:(RKRequest *)request;
/**
Sent to the delegate when a request has timed out. This is sent when a
backgrounded request expired before completion.
@param request The RKRequest object that timed out.
*/
– (void)requestDidTimeout:(RKRequest *)request;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequest.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequest.m
//
// RKRequest.m
// RestKit
//
// Created by Jeremy Ellison on 7/27/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequest.h”
#import “RKResponse.h”
#import “NSDictionary+RKRequestSerialization.h”
#import “RKNotifications.h”
#import “Support.h”
#import “RKURL.h”
#import “NSData+RKAdditions.h”
#import “NSString+RKAdditions.h”
#import “RKLog.h”
#import “RKRequestCache.h”
#import “GCOAuth.h”
#import “NSURL+RKAdditions.h”
#import “RKReachabilityObserver.h”
#import “RKRequestQueue.h”
#import “RKParams.h”
#import “RKParserRegistry.h”
#import “RKRequestSerialization.h”
NSString *RKRequestMethodNameFromType(RKRequestMethod method) {
switch (method) {
case RKRequestMethodGET:
return @”GET”;
break;
case RKRequestMethodPOST:
return @”POST”;
break;
case RKRequestMethodPUT:
return @”PUT”;
break;
case RKRequestMethodDELETE:
return @”DELETE”;
break;
case RKRequestMethodHEAD:
return @”HEAD”;
break;
default:
break;
}
return nil;
}
RKRequestMethod RKRequestMethodTypeFromName(NSString *methodName) {
if ([methodName isEqualToString:@”GET”]) {
return RKRequestMethodGET;
} else if ([methodName isEqualToString:@”POST”]) {
return RKRequestMethodPOST;
} else if ([methodName isEqualToString:@”PUT”]) {
return RKRequestMethodPUT;
} else if ([methodName isEqualToString:@”DELETE”]) {
return RKRequestMethodDELETE;
} else if ([methodName isEqualToString:@”HEAD”]) {
return RKRequestMethodHEAD;
}
return RKRequestMethodInvalid;
}
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
@interface RKRequest ()
@property (nonatomic, assign, readwrite, getter = isLoaded) BOOL loaded;
@property (nonatomic, assign, readwrite, getter = isLoading) BOOL loading;
@property (nonatomic, assign, readwrite, getter = isCancelled) BOOL cancelled;
@property (nonatomic, retain, readwrite) RKResponse *response;
@end
@implementation RKRequest
@class GCOAuth;
@synthesize URL = _URL;
@synthesize URLRequest = _URLRequest;
@synthesize delegate = _delegate;
@synthesize additionalHTTPHeaders = _additionalHTTPHeaders;
@synthesize params = _params;
@synthesize userData = _userData;
@synthesize authenticationType = _authenticationType;
@synthesize username = _username;
@synthesize password = _password;
@synthesize method = _method;
@synthesize cachePolicy = _cachePolicy;
@synthesize cache = _cache;
@synthesize cacheTimeoutInterval = _cacheTimeoutInterval;
@synthesize OAuth1ConsumerKey = _OAuth1ConsumerKey;
@synthesize OAuth1ConsumerSecret = _OAuth1ConsumerSecret;
@synthesize OAuth1AccessToken = _OAuth1AccessToken;
@synthesize OAuth1AccessTokenSecret = _OAuth1AccessTokenSecret;
@synthesize OAuth2AccessToken = _OAuth2AccessToken;
@synthesize OAuth2RefreshToken = _OAuth2RefreshToken;
@synthesize queue = _queue;
@synthesize timeoutInterval = _timeoutInterval;
@synthesize reachabilityObserver = _reachabilityObserver;
@synthesize defaultHTTPEncoding = _defaultHTTPEncoding;
@synthesize configurationDelegate = _configurationDelegate;
@synthesize onDidLoadResponse;
@synthesize onDidFailLoadWithError;
@synthesize additionalRootCertificates = _additionalRootCertificates;
@synthesize disableCertificateValidation = _disableCertificateValidation;
@synthesize followRedirect = _followRedirect;
@synthesize runLoopMode = _runLoopMode;
@synthesize loaded = _loaded;
@synthesize loading = _loading;
@synthesize response = _response;
@synthesize cancelled = _cancelled;
#if TARGET_OS_IPHONE
@synthesize backgroundPolicy = _backgroundPolicy;
@synthesize backgroundTaskIdentifier = _backgroundTaskIdentifier;
#endif
+ (RKRequest*)requestWithURL:(NSURL*)URL {
return [[[RKRequest alloc] initWithURL:URL] autorelease];
}
– (id)initWithURL:(NSURL*)URL {
self = [self init];
if (self) {
_URL = [URL retain];
[self reset];
_authenticationType = RKRequestAuthenticationTypeNone;
_cachePolicy = RKRequestCachePolicyDefault;
_cacheTimeoutInterval = 0;
_timeoutInterval = 120.0;
_defaultHTTPEncoding = NSUTF8StringEncoding;
_followRedirect = YES;
}
return self;
}
– (id)init {
self = [super init];
if (self) {
self.runLoopMode = NSRunLoopCommonModes;
#if TARGET_OS_IPHONE
_backgroundPolicy = RKRequestBackgroundPolicyNone;
_backgroundTaskIdentifier = 0;
BOOL backgroundOK = &UIBackgroundTaskInvalid != NULL;
if (backgroundOK) {
_backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}
#endif
}
return self;
}
– (void)reset {
if (self.isLoading) {
RKLogWarning(@”Request was reset while loading: %@. Canceling.”, self);
[self cancel];
}
[_URLRequest release];
_URLRequest = [[NSMutableURLRequest alloc] initWithURL:_URL];
[_URLRequest setCachePolicy:NSURLRequestReloadIgnoringCacheData];
[_connection release];
_connection = nil;
self.loading = NO;
self.loaded = NO;
self.cancelled = NO;
}
– (void)cleanupBackgroundTask {
#if TARGET_OS_IPHONE
BOOL backgroundOK = &UIBackgroundTaskInvalid != NULL;
if (backgroundOK && UIBackgroundTaskInvalid == self.backgroundTaskIdentifier) {
return;
}
UIApplication* app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) {
[app endBackgroundTask:_backgroundTaskIdentifier];
_backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}
#endif
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
self.delegate = nil;
if (_onDidLoadResponse) Block_release(_onDidLoadResponse);
if (_onDidFailLoadWithError) Block_release(_onDidFailLoadWithError);
_delegate = nil;
_configurationDelegate = nil;
[_reachabilityObserver release];
_reachabilityObserver = nil;
[_connection cancel];
[_connection release];
_connection = nil;
[_response release];
_response = nil;
[_userData release];
_userData = nil;
[_URL release];
_URL = nil;
[_URLRequest release];
_URLRequest = nil;
[_params release];
_params = nil;
[_additionalHTTPHeaders release];
_additionalHTTPHeaders = nil;
[_username release];
_username = nil;
[_password release];
_password = nil;
[_cache release];
_cache = nil;
[_OAuth1ConsumerKey release];
_OAuth1ConsumerKey = nil;
[_OAuth1ConsumerSecret release];
_OAuth1ConsumerSecret = nil;
[_OAuth1AccessToken release];
_OAuth1AccessToken = nil;
[_OAuth1AccessTokenSecret release];
_OAuth1AccessTokenSecret = nil;
[_OAuth2AccessToken release];
_OAuth2AccessToken = nil;
[_OAuth2RefreshToken release];
_OAuth2RefreshToken = nil;
[onDidFailLoadWithError release];
onDidFailLoadWithError = nil;
[onDidLoadResponse release];
onDidLoadResponse = nil;
[self invalidateTimeoutTimer];
[_timeoutTimer release];
_timeoutTimer = nil;
[_runLoopMode release];
_runLoopMode = nil;
// Cleanup a background task if there is any
[self cleanupBackgroundTask];
[super dealloc];
}
– (BOOL)shouldSendParams {
return (_params && (_method != RKRequestMethodGET && _method != RKRequestMethodHEAD));
}
– (void)setRequestBody {
if ([self shouldSendParams]) {
// Prefer the use of a stream over a raw body
if ([_params respondsToSelector:@selector(HTTPBodyStream)]) {
// NOTE: This causes the stream to be retained. For RKParams, this will
// cause a leak unless the stream is released. See [RKParams close]
[_URLRequest setHTTPBodyStream:[_params HTTPBodyStream]];
} else {
[_URLRequest setHTTPBody:[_params HTTPBody]];
}
}
}
– (NSData*)HTTPBody {
return self.URLRequest.HTTPBody;
}
– (void)setHTTPBody:(NSData *)HTTPBody {
[self.URLRequest setHTTPBody:HTTPBody];
}
– (NSString*)HTTPBodyString {
return [[[NSString alloc] initWithData:self.URLRequest.HTTPBody encoding:NSASCIIStringEncoding] autorelease];
}
– (void)setHTTPBodyString:(NSString *)HTTPBodyString {
[self.URLRequest setHTTPBody:[HTTPBodyString dataUsingEncoding:NSASCIIStringEncoding]];
}
– (void)addHeadersToRequest {
NSString *header = nil;
for (header in _additionalHTTPHeaders) {
[_URLRequest setValue:[_additionalHTTPHeaders valueForKey:header] forHTTPHeaderField:header];
}
if ([self shouldSendParams]) {
// Temporarily support older RKRequestSerializable implementations
if ([_params respondsToSelector:@selector(HTTPHeaderValueForContentType)]) {
[_URLRequest setValue:[_params HTTPHeaderValueForContentType] forHTTPHeaderField:@”Content-Type”];
} else if ([_params respondsToSelector:@selector(ContentTypeHTTPHeader)]) {
[_URLRequest setValue:[_params performSelector:@selector(ContentTypeHTTPHeader)] forHTTPHeaderField:@”Content-Type”];
}
if ([_params respondsToSelector:@selector(HTTPHeaderValueForContentLength)]) {
[_URLRequest setValue:[NSString stringWithFormat:@”%d”, [_params HTTPHeaderValueForContentLength]] forHTTPHeaderField:@”Content-Length”];
}
} else {
[_URLRequest setValue:@”0″ forHTTPHeaderField:@”Content-Length”];
}
// Add authentication headers so we don’t have to deal with an extra cycle for each message requiring basic auth.
if (self.authenticationType == RKRequestAuthenticationTypeHTTPBasic && _username && _password) {
CFHTTPMessageRef dummyRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, (CFStringRef)[self HTTPMethod], (CFURLRef)[self URL], kCFHTTPVersion1_1);
if (dummyRequest) {
CFHTTPMessageAddAuthentication(dummyRequest, nil, (CFStringRef)_username, (CFStringRef)_password,kCFHTTPAuthenticationSchemeBasic, FALSE);
CFStringRef authorizationString = CFHTTPMessageCopyHeaderFieldValue(dummyRequest, CFSTR(“Authorization”));
if (authorizationString) {
[_URLRequest setValue:(NSString *)authorizationString forHTTPHeaderField:@”Authorization”];
CFRelease(authorizationString);
}
CFRelease(dummyRequest);
}
}
// Add OAuth headers if necessary
// OAuth 1
if(self.authenticationType == RKRequestAuthenticationTypeOAuth1){
NSURLRequest *echo = nil;
// use the suitable parameters dict
NSDictionary *parameters = nil;
if ([self.params isKindOfClass:[RKParams class]])
parameters = [(RKParams *)self.params dictionaryOfPlainTextParams];
else
parameters = [_URL queryParameters];
if (self.method == RKRequestMethodPUT)
echo = [GCOAuth URLRequestForPath:[_URL path]
PUTParameters:parameters
scheme:[_URL scheme]
host:[_URL hostAndPort]
consumerKey:self.OAuth1ConsumerKey
consumerSecret:self.OAuth1ConsumerSecret
accessToken:self.OAuth1AccessToken
tokenSecret:self.OAuth1AccessTokenSecret];
else if (self.method == RKRequestMethodPOST)
echo = [GCOAuth URLRequestForPath:[_URL path]
POSTParameters:parameters
scheme:[_URL scheme]
host:[_URL hostAndPort]
consumerKey:self.OAuth1ConsumerKey
consumerSecret:self.OAuth1ConsumerSecret
accessToken:self.OAuth1AccessToken
tokenSecret:self.OAuth1AccessTokenSecret];
else
echo = [GCOAuth URLRequestForPath:[_URL path]
GETParameters:[_URL queryParameters]
scheme:[_URL scheme]
host:[_URL hostAndPort]
consumerKey:self.OAuth1ConsumerKey
consumerSecret:self.OAuth1ConsumerSecret
accessToken:self.OAuth1AccessToken
tokenSecret:self.OAuth1AccessTokenSecret];
[_URLRequest setValue:[echo valueForHTTPHeaderField:@”Authorization”] forHTTPHeaderField:@”Authorization”];
[_URLRequest setValue:[echo valueForHTTPHeaderField:@”Accept-Encoding”] forHTTPHeaderField:@”Accept-Encoding”];
[_URLRequest setValue:[echo valueForHTTPHeaderField:@”User-Agent”] forHTTPHeaderField:@”User-Agent”];
}
// OAuth 2 valid request
if(self.authenticationType == RKRequestAuthenticationTypeOAuth2) {
NSString *authorizationString = [NSString stringWithFormat:@”OAuth2 %@”,self.OAuth2AccessToken];
[_URLRequest setValue:authorizationString forHTTPHeaderField:@”Authorization”];
}
if (self.cachePolicy & RKRequestCachePolicyEtag) {
NSString* etag = [self.cache etagForRequest:self];
if (etag) {
RKLogTrace(@”Setting If-None-Match header to ‘%@'”, etag);
[_URLRequest setValue:etag forHTTPHeaderField:@”If-None-Match”];
}
}
}
// Setup the NSURLRequest. The request must be prepared right before dispatching
– (BOOL)prepareURLRequest {
[_URLRequest setHTTPMethod:[self HTTPMethod]];
if ([self.delegate respondsToSelector:@selector(requestWillPrepareForSend:)]) {
[self.delegate requestWillPrepareForSend:self];
}
[self setRequestBody];
[self addHeadersToRequest];
NSString* body = [[NSString alloc] initWithData:[_URLRequest HTTPBody] encoding:NSUTF8StringEncoding];
RKLogTrace(@”Prepared %@ URLRequest ‘%@’. HTTP Headers: %@. HTTP Body: %@.”, [self HTTPMethod], _URLRequest, [_URLRequest allHTTPHeaderFields], body);
[body release];
return YES;
}
– (void)cancelAndInformDelegate:(BOOL)informDelegate {
self.cancelled = YES;
[_connection cancel];
[_connection release];
_connection = nil;
[self invalidateTimeoutTimer];
self.loading = NO;
if (informDelegate && [_delegate respondsToSelector:@selector(requestDidCancelLoad:)]) {
[_delegate requestDidCancelLoad:self];
}
}
– (NSString *)HTTPMethod {
return RKRequestMethodNameFromType(self.method);
}
// NOTE: We could factor the knowledge about the queue out of RKRequest entirely, but it will break behavior.
– (void)send {
NSAssert(NO == self.isLoading || NO == self.isLoaded, @”Cannot send a request that is loading or loaded without resetting it first.”);
if (self.queue) {
[self.queue addRequest:self];
} else {
[self sendAsynchronously];
}
}
– (void)fireAsynchronousRequest {
RKLogDebug(@”Sending asynchronous %@ request to URL %@.”, [self HTTPMethod], [[self URL] absoluteString]);
if (![self prepareURLRequest]) {
RKLogWarning(@”Failed to send request asynchronously: prepareURLRequest returned NO.”);
return;
}
self.loading = YES;
if ([self.delegate respondsToSelector:@selector(requestDidStartLoad:)]) {
[self.delegate requestDidStartLoad:self];
}
RKResponse* response = [[[RKResponse alloc] initWithRequest:self] autorelease];
_connection = [[[[NSURLConnection alloc] initWithRequest:_URLRequest delegate:response startImmediately:NO] autorelease] retain];
[_connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:self.runLoopMode];
[_connection start];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestSentNotification object:self userInfo:nil];
}
– (BOOL)shouldLoadFromCache {
// if RKRequestCachePolicyEnabled or if RKRequestCachePolicyTimeout and we are in the timeout
if ([self.cache hasResponseForRequest:self]) {
if (self.cachePolicy & RKRequestCachePolicyEnabled) {
return YES;
} else if (self.cachePolicy & RKRequestCachePolicyTimeout) {
NSDate* date = [self.cache cacheDateForRequest:self];
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
return interval <= self.cacheTimeoutInterval;
}
}
return NO;
}
- (RKResponse*)loadResponseFromCache {
RKLogDebug(@"Found cached content, loading...");
return [self.cache responseForRequest:self];
}
- (BOOL)shouldDispatchRequest {
if (nil == self.reachabilityObserver || NO == [self.reachabilityObserver isReachabilityDetermined]) {
return YES;
}
return [self.reachabilityObserver isNetworkReachable];
}
- (void)sendAsynchronously {
NSAssert(NO == self.loading || NO == self.loaded, @"Cannot send a request that is loading or loaded without resetting it first.");
_sentSynchronously = NO;
if ([self shouldLoadFromCache]) {
RKResponse* response = [self loadResponseFromCache];
self.loading = YES;
[self performSelector:@selector(didFinishLoad:) withObject:response afterDelay:0];
} else if ([self shouldDispatchRequest]) {
[self createTimeoutTimer];
#if TARGET_OS_IPHONE
// Background Request Policy support
UIApplication* app = [UIApplication sharedApplication];
if (self.backgroundPolicy == RKRequestBackgroundPolicyNone ||
NO == [app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) {
// No support for background (iOS 3.x) or the policy is none -- just fire the request
[self fireAsynchronousRequest];
} else if (self.backgroundPolicy == RKRequestBackgroundPolicyCancel || self.backgroundPolicy == RKRequestBackgroundPolicyRequeue) {
// For cancel or requeue behaviors, we watch for background transition notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidEnterBackgroundNotification:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[self fireAsynchronousRequest];
} else if (self.backgroundPolicy == RKRequestBackgroundPolicyContinue) {
RKLogInfo(@"Beginning background task to perform processing...");
// Fork a background task for continueing a long-running request
__block RKRequest* weakSelf = self;
__block id
_backgroundTaskIdentifier = [app beginBackgroundTaskWithExpirationHandler:^{
RKLogInfo(@”Background request time expired, canceling request.”);
[weakSelf cancelAndInformDelegate:NO];
[weakSelf cleanupBackgroundTask];
if ([weakDelegate respondsToSelector:@selector(requestDidTimeout:)]) {
[weakDelegate requestDidTimeout:weakSelf];
}
}];
// Start the potentially long-running request
[self fireAsynchronousRequest];
}
#else
[self fireAsynchronousRequest];
#endif
} else {
RKLogTrace(@”Declined to dispatch request %@: reachability observer reported the network is not available.”, self);
if (_cachePolicy & RKRequestCachePolicyLoadIfOffline &&
[self.cache hasResponseForRequest:self]) {
self.loading = YES;
[self didFinishLoad:[self loadResponseFromCache]];
} else {
self.loading = YES;
RKLogError(@”Failed to send request to %@ due to unreachable network. Reachability observer = %@”, [[self URL] absoluteString], self.reachabilityObserver);
NSString* errorMessage = [NSString stringWithFormat:@”The client is unable to contact the resource at %@”, [[self URL] absoluteString]];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
nil];
NSError* error = [NSError errorWithDomain:RKErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
[self performSelector:@selector(didFailLoadWithError:) withObject:error afterDelay:0];
}
}
}
– (RKResponse*)sendSynchronously {
NSAssert(NO == self.loading || NO == self.loaded, @”Cannot send a request that is loading or loaded without resetting it first.”);
NSHTTPURLResponse* URLResponse = nil;
NSError* error;
NSData* payload = nil;
RKResponse* response = nil;
_sentSynchronously = YES;
if ([self shouldLoadFromCache]) {
response = [self loadResponseFromCache];
self.loading = YES;
[self didFinishLoad:response];
} else if ([self shouldDispatchRequest]) {
RKLogDebug(@”Sending synchronous %@ request to URL %@.”, [self HTTPMethod], [[self URL] absoluteString]);
if (![self prepareURLRequest]) {
RKLogWarning(@”Failed to send request synchronously: prepareURLRequest returned NO.”);
return nil;
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestSentNotification object:self userInfo:nil];
self.loading = YES;
if ([self.delegate respondsToSelector:@selector(requestDidStartLoad:)]) {
[self.delegate requestDidStartLoad:self];
}
_URLRequest.timeoutInterval = _timeoutInterval;
payload = [NSURLConnection sendSynchronousRequest:_URLRequest returningResponse:&URLResponse error:&error];
if (payload != nil) error = nil;
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
if (error.code == NSURLErrorTimedOut) {
[self timeout];
} else if (payload == nil) {
[self didFailLoadWithError:error];
} else {
[self didFinishLoad:response];
}
} else {
if (_cachePolicy & RKRequestCachePolicyLoadIfOffline &&
[self.cache hasResponseForRequest:self]) {
response = [self loadResponseFromCache];
} else {
NSString* errorMessage = [NSString stringWithFormat:@”The client is unable to contact the resource at %@”, [[self URL] absoluteString]];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
nil];
error = [NSError errorWithDomain:RKErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
[self didFailLoadWithError:error];
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
}
}
return response;
}
– (void)cancel {
[self cancelAndInformDelegate:YES];
}
– (void)createTimeoutTimer {
_timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:self.timeoutInterval target:self selector:@selector(timeout) userInfo:nil repeats:NO];
}
– (void)timeout {
[self cancelAndInformDelegate:NO];
RKLogError(@”Failed to send request to %@ due to connection timeout. Timeout interval = %f”, [[self URL] absoluteString], self.timeoutInterval);
NSString* errorMessage = [NSString stringWithFormat:@”The client timed out connecting to the resource at %@”, [[self URL] absoluteString]];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
nil];
NSError* error = [NSError errorWithDomain:RKErrorDomain code:RKRequestConnectionTimeoutError userInfo:userInfo];
[self didFailLoadWithError:error];
}
– (void)invalidateTimeoutTimer {
[_timeoutTimer invalidate];
_timeoutTimer = nil;
}
– (void)didFailLoadWithError:(NSError*)error {
if (_cachePolicy & RKRequestCachePolicyLoadOnError &&
[self.cache hasResponseForRequest:self]) {
[self didFinishLoad:[self loadResponseFromCache]];
} else {
self.loaded = YES;
self.loading = NO;
if ([_delegate respondsToSelector:@selector(request:didFailLoadWithError:)]) {
[_delegate request:self didFailLoadWithError:error];
}
if (self.onDidFailLoadWithError) {
self.onDidFailLoadWithError(error);
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:error forKey:RKRequestDidFailWithErrorNotificationUserInfoErrorKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFailWithErrorNotification
object:self
userInfo:userInfo];
}
// NOTE: This notification must be posted last as the request queue releases the request when it
// receives the notification
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFinishLoadingNotification object:self];
}
– (void)updateInternalCacheDate {
NSDate* date = [NSDate date];
RKLogInfo(@”Updating cache date for request %@ to %@”, self, date);
[self.cache setCacheDate:date forRequest:self];
}
– (void)didFinishLoad:(RKResponse *)response {
self.loading = NO;
self.loaded = YES;
RKLogInfo(@”Status Code: %ld”, (long) [response statusCode]);
RKLogDebug(@”Body: %@”, [response bodyAsString]);
self.response = response;
if ((_cachePolicy & RKRequestCachePolicyEtag) && [response isNotModified]) {
self.response = [self loadResponseFromCache];
[self updateInternalCacheDate];
}
if (![response wasLoadedFromCache] && [response isSuccessful] && (_cachePolicy != RKRequestCachePolicyNone)) {
[self.cache storeResponse:response forRequest:self];
}
if ([_delegate respondsToSelector:@selector(request:didLoadResponse:)]) {
[_delegate request:self didLoadResponse:self.response];
}
if (self.onDidLoadResponse) {
self.onDidLoadResponse(self.response);
}
if ([response isServiceUnavailable]) {
[[NSNotificationCenter defaultCenter] postNotificationName:RKServiceDidBecomeUnavailableNotification object:self];
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:self.response
forKey:RKRequestDidLoadResponseNotificationUserInfoResponseKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidLoadResponseNotification
object:self
userInfo:userInfo];
// NOTE: This notification must be posted last as the request queue releases the request when it
// receives the notification
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFinishLoadingNotification object:self];
}
– (BOOL)isGET {
return _method == RKRequestMethodGET;
}
– (BOOL)isPOST {
return _method == RKRequestMethodPOST;
}
– (BOOL)isPUT {
return _method == RKRequestMethodPUT;
}
– (BOOL)isDELETE {
return _method == RKRequestMethodDELETE;
}
– (BOOL)isHEAD {
return _method == RKRequestMethodHEAD;
}
– (BOOL)isUnsent {
return self.loading == NO && self.loaded == NO;
}
– (NSString*)resourcePath {
NSString* resourcePath = nil;
if ([self.URL isKindOfClass:[RKURL class]]) {
RKURL* url = (RKURL*)self.URL;
resourcePath = url.resourcePath;
}
return resourcePath;
}
– (void)setURL:(NSURL *)URL {
[URL retain];
[_URL release];
_URL = URL;
_URLRequest.URL = URL;
}
– (void)setResourcePath:(NSString *)resourcePath {
if ([self.URL isKindOfClass:[RKURL class]]) {
self.URL = [(RKURL *)self.URL URLByReplacingResourcePath:resourcePath];
} else {
self.URL = [RKURL URLWithBaseURL:self.URL resourcePath:resourcePath];
}
}
– (BOOL)wasSentToResourcePath:(NSString*)resourcePath {
return [[self resourcePath] isEqualToString:resourcePath];
}
– (BOOL)wasSentToResourcePath:(NSString *)resourcePath method:(RKRequestMethod)method {
return (self.method == method && [self wasSentToResourcePath:resourcePath]);
}
– (void)appDidEnterBackgroundNotification:(NSNotification*)notification {
#if TARGET_OS_IPHONE
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
if (self.backgroundPolicy == RKRequestBackgroundPolicyCancel) {
[self cancel];
} else if (self.backgroundPolicy == RKRequestBackgroundPolicyRequeue) {
// Cancel the existing request
[self cancelAndInformDelegate:NO];
[self send];
}
#endif
}
– (BOOL)isCacheable {
return _method == RKRequestMethodGET;
}
– (NSString*)cacheKey {
if (! [self isCacheable]) {
return nil;
}
// Use [_params HTTPBody] because the URLRequest body may not have been set up yet.
NSString* compositeCacheKey = nil;
if (_params) {
if ([_params respondsToSelector:@selector(HTTPBody)]) {
compositeCacheKey = [NSString stringWithFormat:@”%@-%d-%@”, self.URL, _method, [_params HTTPBody]];
} else if ([_params isKindOfClass:[RKParams class]]) {
compositeCacheKey = [NSString stringWithFormat:@”%@-%d-%@”, self.URL, _method, [(RKParams *)_params MD5]];
}
} else {
compositeCacheKey = [NSString stringWithFormat:@”%@-%d”, self.URL, _method];
}
NSAssert(compositeCacheKey, @”Expected a cacheKey to be generated for request %@, but got nil”, compositeCacheKey);
return [compositeCacheKey MD5];
}
– (void)setBody:(NSDictionary *)body forMIMEType:(NSString *)MIMEType {
id
NSError *error = nil;
NSString* parsedValue = [parser stringFromObject:body error:&error];
RKLogTrace(@”parser=%@, error=%@, parsedValue=%@”, parser, error, parsedValue);
if (error == nil && parsedValue) {
self.params = [RKRequestSerialization serializationWithData:[parsedValue dataUsingEncoding:NSUTF8StringEncoding]
MIMEType:MIMEType];
}
}
// Deprecations
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate {
return [[[RKRequest alloc] initWithURL:URL delegate:delegate] autorelease];
}
– (id)initWithURL:(NSURL*)URL delegate:(id)delegate {
self = [self initWithURL:URL];
if (self) {
_delegate = delegate;
}
return self;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequest.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequest_Internals.h
//
// RKRequest_Internals.h
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
@interface RKRequest (Internals)
– (BOOL)prepareURLRequest;
– (void)didFailLoadWithError:(NSError*)error;
– (void)finalizeLoad:(BOOL)successful;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequest_Internals.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestCache.h
//
// RKRequestCache.h
// RestKit
//
// Created by Jeff Arena on 4/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequest.h”
#import “RKResponse.h”
#import “RKCache.h”
/**
Cache storage policy used to determines how long we keep a specific cache for.
*/
typedef enum {
/**
The cache is disabled. Attempts to store data will silently fail.
*/
RKRequestCacheStoragePolicyDisabled,
/**
Cache data for the length of the session and clear when the app exits.
*/
RKRequestCacheStoragePolicyForDurationOfSession,
/**
Cache data permanently until explicitly expired or flushed.
*/
RKRequestCacheStoragePolicyPermanently
} RKRequestCacheStoragePolicy;
/**
Location of session specific cache files within the Caches path.
*/
extern NSString * const RKRequestCacheSessionCacheDirectory;
/**
Location of permanent cache files within the Caches path.
*/
extern NSString * const RKRequestCachePermanentCacheDirectory;
/**
@constant RKRequestCache Header Keys
Constants for accessing cache specific X-RESTKIT
headers used to store cache metadata within the cache entry.
*/
/** The key for accessing the date the entry was cached. **/
extern NSString * const RKRequestCacheDateHeaderKey;
/** The key for accessing the status code of the cached request. **/
extern NSString * const RKRequestCacheStatusCodeHeadersKey;
/** The key for accessing the MIME Type of the cached request. **/
extern NSString * const RKRequestCacheMIMETypeHeadersKey;
/** The key for accessing the URL of the cached request. **/
extern NSString * const RKRequestCacheURLHeadersKey;
/**
Stores and retrieves cache entries for RestKit request objects.
*/
@interface RKRequestCache : NSObject {
RKRequestCacheStoragePolicy _storagePolicy;
RKCache *_cache;
}
///—————————————————————————–
/// @name Initializating the Cache
///—————————————————————————–
/**
Initializes the receiver with a cache at a given path and storage policy.
@param cachePath The path to store cached data in.
@param storagePolicy The storage policy to use for cached data.
@return An initialized request cache object.
*/
– (id)initWithPath:(NSString *)cachePath storagePolicy:(RKRequestCacheStoragePolicy)storagePolicy;
///—————————————————————————–
/// @name Locating the Cache
///—————————————————————————–
/**
Returns the full pathname to the cache.
*/
@property (nonatomic, readonly) NSString *path;
/**
Returns the cache path for the specified request.
@param request An RKRequest object to determine the cache path.
@return A string of the cache path for the specified request.
*/
– (NSString *)pathForRequest:(RKRequest *)request;
/**
Determine if a response exists for a request.
@param request An RKRequest object that is looking for cached content.
@return A boolean value for if a response exists in the cache.
*/
– (BOOL)hasResponseForRequest:(RKRequest *)request;
///—————————————————————————–
/// @name Populating the Cache
///—————————————————————————–
/**
Store a request’s response in the cache.
@param response The response to be stored in the cache.
@param request The request that retrieved the response.
*/
– (void)storeResponse:(RKResponse *)response forRequest:(RKRequest *)request;
/**
Set the cache date for a request.
@param date The date the response for a request was cached.
@param request The request to store the cache date for.
*/
– (void)setCacheDate:(NSDate *)date forRequest:(RKRequest *)request;
///—————————————————————————–
/// @name Preparing Requests and Responses
///—————————————————————————–
/**
Returns a dictionary of cached headers for a cached request.
@param request The request to retrieve cached headers for.
@return An NSDictionary of the cached headers that were stored for the
specified request.
*/
– (NSDictionary *)headersForRequest:(RKRequest *)request;
/**
Returns an ETag for a request if it is stored in the cached headers.
@param request The request that an ETag is to be determined for.
@return A string of the ETag value stored for the specified request.
*/
– (NSString *)etagForRequest:(RKRequest *)request;
/**
Returns the date of the cached request.
@param request The request that needs a cache date returned.
@return A date object for the cached request.
*/
– (NSDate *)cacheDateForRequest:(RKRequest *)request;
/**
Returns the cached response for a given request.
@param request The request used to find the cached response.
@return An RKResponse object that was cached for a given request.
*/
– (RKResponse *)responseForRequest:(RKRequest *)request;
///—————————————————————————–
/// @name Invalidating the Cache
///—————————————————————————–
/**
The storage policy for the cache.
*/
@property (nonatomic, assign) RKRequestCacheStoragePolicy storagePolicy;
/**
Invalidate the cache for a given request.
@param request The request that needs its cache invalidated.
*/
– (void)invalidateRequest:(RKRequest *)request;
/**
Invalidate any caches that fall under the given storage policy.
@param storagePolicy The RKRequestCacheStorePolicy used to determine which
caches need to be invalidated.
*/
– (void)invalidateWithStoragePolicy:(RKRequestCacheStoragePolicy)storagePolicy;
/**
Invalidate all caches on disk.
*/
– (void)invalidateAll;
///—————————————————————————–
/// @name Helpers
///—————————————————————————–
/**
The date formatter used to generate the cache date for the HTTP header.
*/
+ (NSDateFormatter *)rfc1123DateFormatter;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestCache.m
//
// RKRequestCache.m
// RestKit
//
// Created by Jeff Arena on 4/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequestCache.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetworkCache
NSString * const RKRequestCacheSessionCacheDirectory = @”SessionStore”;
NSString * const RKRequestCachePermanentCacheDirectory = @”PermanentStore”;
NSString * const RKRequestCacheHeadersExtension = @”headers”;
NSString * const RKRequestCacheDateHeaderKey = @”X-RESTKIT-CACHEDATE”;
NSString * const RKRequestCacheStatusCodeHeadersKey = @”X-RESTKIT-CACHED-RESPONSE-CODE”;
NSString * const RKRequestCacheMIMETypeHeadersKey = @”X-RESTKIT-CACHED-MIME-TYPE”;
NSString * const RKRequestCacheURLHeadersKey = @”X-RESTKIT-CACHED-URL”;
static NSDateFormatter* __rfc1123DateFormatter;
@implementation RKRequestCache
@synthesize storagePolicy = _storagePolicy;
+ (NSDateFormatter*)rfc1123DateFormatter {
if (__rfc1123DateFormatter == nil) {
__rfc1123DateFormatter = [[NSDateFormatter alloc] init];
[__rfc1123DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[__rfc1123DateFormatter setDateFormat:@”EEE, dd MMM yyyy HH:mm:ss ‘GMT'”];
}
return __rfc1123DateFormatter;
}
– (id)initWithPath:(NSString*)cachePath storagePolicy:(RKRequestCacheStoragePolicy)storagePolicy {
self = [super init];
if (self) {
_cache = [[RKCache alloc] initWithPath:cachePath
subDirectories:
[NSArray arrayWithObjects:RKRequestCacheSessionCacheDirectory,
RKRequestCachePermanentCacheDirectory, nil]];
self.storagePolicy = storagePolicy;
}
return self;
}
– (void)dealloc {
[_cache release];
_cache = nil;
[super dealloc];
}
– (NSString*)path {
return _cache.cachePath;
}
– (NSString*)pathForRequest:(RKRequest*)request {
NSString* pathForRequest = nil;
NSString* requestCacheKey = [request cacheKey];
if (requestCacheKey) {
if (_storagePolicy == RKRequestCacheStoragePolicyForDurationOfSession) {
pathForRequest = [RKRequestCacheSessionCacheDirectory stringByAppendingPathComponent:requestCacheKey];
} else if (_storagePolicy == RKRequestCacheStoragePolicyPermanently) {
pathForRequest = [RKRequestCachePermanentCacheDirectory stringByAppendingPathComponent:requestCacheKey];
}
RKLogTrace(@”Found cacheKey ‘%@’ for %@”, pathForRequest, request);
} else {
RKLogTrace(@”Failed to find cacheKey for %@ due to nil cacheKey”, request);
}
return pathForRequest;
}
– (BOOL)hasResponseForRequest:(RKRequest*)request {
BOOL hasEntryForRequest = NO;
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
hasEntryForRequest = ([_cache hasEntry:cacheKey] &&
[_cache hasEntry:[cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension]]);
}
RKLogTrace(@”Determined hasResponseForRequest: %@ => %@”, request, hasEntryForRequest ? @”YES” : @”NO”);
return hasEntryForRequest;
}
– (void)storeResponse:(RKResponse*)response forRequest:(RKRequest*)request {
if ([self hasResponseForRequest:request]) {
[self invalidateRequest:request];
}
if (_storagePolicy != RKRequestCacheStoragePolicyDisabled) {
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
[_cache writeData:response.body withCacheKey:cacheKey];
NSMutableDictionary* headers = [response.allHeaderFields mutableCopy];
if (headers) {
// TODO: expose this?
NSHTTPURLResponse* urlResponse = [response valueForKey:@”_httpURLResponse”];
// Cache Loaded Time
[headers setObject:[[RKRequestCache rfc1123DateFormatter] stringFromDate:[NSDate date]]
forKey:RKRequestCacheDateHeaderKey];
// Cache status code
[headers setObject:[NSNumber numberWithInteger:urlResponse.statusCode]
forKey:RKRequestCacheStatusCodeHeadersKey];
// Cache MIME Type
[headers setObject:urlResponse.MIMEType
forKey:RKRequestCacheMIMETypeHeadersKey];
// Cache URL
[headers setObject:[urlResponse.URL absoluteString]
forKey:RKRequestCacheURLHeadersKey];
// Save
[_cache writeDictionary:headers withCacheKey:[cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension]];
}
[headers release];
}
}
}
– (RKResponse*)responseForRequest:(RKRequest*)request {
RKResponse* response = nil;
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
NSData* responseData = [_cache dataForCacheKey:cacheKey];
NSDictionary* responseHeaders = [_cache dictionaryForCacheKey:[cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension]];
response = [[[RKResponse alloc] initWithRequest:request body:responseData headers:responseHeaders] autorelease];
}
RKLogDebug(@”Found cached RKResponse ‘%@’ for ‘%@'”, response, request);
return response;
}
– (NSDictionary*)headersForRequest:(RKRequest*)request {
NSDictionary* headers = nil;
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
NSString* headersCacheKey = [cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension];
headers = [_cache dictionaryForCacheKey:headersCacheKey];
if (headers) {
RKLogDebug(@”Read cached headers ‘%@’ from headersCacheKey ‘%@’ for ‘%@'”, headers, headersCacheKey, request);
} else {
RKLogDebug(@”Read nil cached headers from headersCacheKey ‘%@’ for ‘%@'”, headersCacheKey, request);
}
} else {
RKLogDebug(@”Unable to read cached headers for ‘%@’: cacheKey not found”, request);
}
return headers;
}
– (NSString*)etagForRequest:(RKRequest*)request {
NSString* etag = nil;
NSDictionary* responseHeaders = [self headersForRequest:request];
if (responseHeaders) {
for (NSString* responseHeader in responseHeaders) {
if ([[responseHeader uppercaseString] isEqualToString:[@”ETag” uppercaseString]]) {
etag = [responseHeaders objectForKey:responseHeader];
}
}
}
RKLogDebug(@”Found cached ETag ‘%@’ for ‘%@'”, etag, request);
return etag;
}
– (void)setCacheDate:(NSDate*)date forRequest:(RKRequest*)request {
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
NSMutableDictionary* responseHeaders = [[self headersForRequest:request] mutableCopy];
[responseHeaders setObject:[[RKRequestCache rfc1123DateFormatter] stringFromDate:date]
forKey:RKRequestCacheDateHeaderKey];
[_cache writeDictionary:responseHeaders
withCacheKey:[cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension]];
[responseHeaders release];
}
}
– (NSDate*)cacheDateForRequest:(RKRequest*)request {
NSDate* date = nil;
NSString* dateString = nil;
NSDictionary* responseHeaders = [self headersForRequest:request];
if (responseHeaders) {
for (NSString* responseHeader in responseHeaders) {
if ([[responseHeader uppercaseString] isEqualToString:[RKRequestCacheDateHeaderKey uppercaseString]]) {
dateString = [responseHeaders objectForKey:responseHeader];
}
}
}
date = [[RKRequestCache rfc1123DateFormatter] dateFromString:dateString];
RKLogDebug(@”Found cached date ‘%@’ for ‘%@'”, date, request);
return date;
}
– (void)invalidateRequest:(RKRequest*)request {
RKLogDebug(@”Invalidating cache entry for ‘%@'”, request);
NSString* cacheKey = [self pathForRequest:request];
if (cacheKey) {
[_cache invalidateEntry:cacheKey];
[_cache invalidateEntry:[cacheKey stringByAppendingPathExtension:RKRequestCacheHeadersExtension]];
RKLogTrace(@”Removed cache entry at path ‘%@’ for ‘%@'”, cacheKey, request);
}
}
– (void)invalidateWithStoragePolicy:(RKRequestCacheStoragePolicy)storagePolicy {
if (storagePolicy != RKRequestCacheStoragePolicyDisabled) {
if (storagePolicy == RKRequestCacheStoragePolicyForDurationOfSession) {
[_cache invalidateSubDirectory:RKRequestCacheSessionCacheDirectory];
} else {
[_cache invalidateSubDirectory:RKRequestCachePermanentCacheDirectory];
}
}
}
– (void)invalidateAll {
RKLogInfo(@”Invalidating all cache entries…”);
[_cache invalidateSubDirectory:RKRequestCacheSessionCacheDirectory];
[_cache invalidateSubDirectory:RKRequestCachePermanentCacheDirectory];
}
– (void)setStoragePolicy:(RKRequestCacheStoragePolicy)storagePolicy {
[self invalidateWithStoragePolicy:RKRequestCacheStoragePolicyForDurationOfSession];
if (storagePolicy == RKRequestCacheStoragePolicyDisabled) {
[self invalidateWithStoragePolicy:RKRequestCacheStoragePolicyPermanently];
}
_storagePolicy = storagePolicy;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestQueue.h
//
// RKRequestQueue.h
// RestKit
//
// Created by Blake Watters on 12/1/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKRequest.h”
@protocol RKRequestQueueDelegate;
/**
A lightweight queue implementation responsible for dispatching and managing
RKRequest objects.
*/
@interface RKRequestQueue : NSObject {
NSString *_name;
NSMutableArray *_requests;
NSMutableSet *_loadingRequests;
NSObject
NSUInteger _concurrentRequestsLimit;
NSUInteger _requestTimeout;
NSTimer *_queueTimer;
BOOL _suspended;
BOOL _showsNetworkActivityIndicatorWhenBusy;
}
///—————————————————————————–
/// @name Creating a Request Queue
///—————————————————————————–
/**
Creates and returns a new request queue.
@return An autoreleased RKRequestQueue object.
*/
+ (id)requestQueue;
/**
Returns a new retained request queue with the given name. If there is already
an existing queue with the given name, nil will be returned.
@param name A symbolic name for the queue.
@return A new retained RKRequestQueue with the given name or nil if one already
exists with the given name.
*/
+ (id)newRequestQueueWithName:(NSString *)name;
///—————————————————————————–
/// @name Retrieving an Existing Queue
///—————————————————————————–
/**
Returns queue with the specified name. If no queue is found with the name
provided, a new queue will be initialized and returned.
@param name A symbolic name for the queue.
@return An existing RKRequestQueue with the given name or a new queue if none
currently exist.
*/
+ (id)requestQueueWithName:(NSString *)name;
///—————————————————————————–
/// @name Naming Queues
///—————————————————————————–
/**
A symbolic name for the queue.
Used to return existing queue references via
[RKRequestQueue requestQueueWithName:]
*/
@property (nonatomic, retain, readonly) NSString *name;
/**
Determine if a queue exists with a given name.
@param name The queue name to search against.
@return YES when there is a queue with the given name.
*/
+ (BOOL)requestQueueExistsWithName:(NSString *)name;
///—————————————————————————–
/// @name Monitoring State Changes
///—————————————————————————–
/**
The delegate to inform when the request queue state machine changes.
If the object implements the RKRequestQueueDelegate protocol, it will receive
request lifecycle event messages.
*/
@property (nonatomic, assign) id
///—————————————————————————–
/// @name Managing the Queue
///—————————————————————————–
/**
The number of concurrent requests supported by this queue.
**Default**: 5 concurrent requests
*/
@property (nonatomic) NSUInteger concurrentRequestsLimit;
/**
Request timeout value used by the queue.
**Default**: 5 minutes (300 seconds)
*/
@property (nonatomic, assign) NSUInteger requestTimeout;
/**
Returns the total number of requests in the queue.
*/
@property (nonatomic, readonly) NSUInteger count;
/**
Add an asynchronous request to the queue and send it as as soon as possible.
@param request The request to be added to the queue.
*/
– (void)addRequest:(RKRequest *)request;
/**
Cancel a request that is in progress.
@param request The request to be cancelled.
*/
– (void)cancelRequest:(RKRequest *)request;
/**
Cancel all requests with a given delegate.
@param delegate The delegate assigned to the requests to be cancelled.
*/
– (void)cancelRequestsWithDelegate:(id
/**
Aborts all requests with a given delegate by nullifying the delegate
reference and canceling the request.
Useful when an object that acts as the delegate for one or more requests
is being deallocated and all outstanding requests should be cancelled
without generating any further delegate callbacks.
@param delegate The object acting as the delegate for all enqueued requests that are to be aborted.
*/
– (void)abortRequestsWithDelegate:(id
/**
Cancel all active or pending requests.
*/
– (void)cancelAllRequests;
/**
Determine if a given request is currently in this queue.
@param request The request to check the queue for.
@return YES if the specified request is in this queue.
*/
– (BOOL)containsRequest:(RKRequest *)request;
///—————————————————————————–
/// @name Processing Queued Requests
///—————————————————————————–
/**
Start checking for and processing requests.
*/
– (void)start;
/**
Sets the flag that determines if new load requests are allowed to reach the
network.
Because network requests tend to slow down performance, this property can be
used to temporarily delay them. All requests made while suspended are queued,
and when suspended becomes false again they are executed.
*/
@property (nonatomic) BOOL suspended;
/**
Returns the total number of requests that are currently loading.
*/
@property (nonatomic, readonly) NSUInteger loadingCount;
#if TARGET_OS_IPHONE
/**
Sets the flag for showing the network activity indicatory.
When YES, this queue will spin the network activity in the menu bar when it is
processing requests.
**Default**: NO
*/
@property (nonatomic) BOOL showsNetworkActivityIndicatorWhenBusy;
#endif
///—————————————————————————–
/// @name Global Queues (Deprecated)
///—————————————————————————–
/**
Returns the global queue
@bug **DEPRECATED** in v0.10.0: All RKClient instances now own their own
individual request queues.
@see [RKClient requestQueue]
@return Global request queue.
*/
+ (RKRequestQueue *)sharedQueue DEPRECATED_ATTRIBUTE;
/**
Sets the global queue
@bug **DEPRECATED** in v0.10.0: All RKClient instances now own their own
individual request queues.
@see [RKClient requestQueue]
@param requestQueue The request queue to assign as the global queue.
*/
+ (void)setSharedQueue:(RKRequestQueue *)requestQueue DEPRECATED_ATTRIBUTE;
@end
/**
Lifecycle events for an RKRequestQueue
*/
@protocol RKRequestQueueDelegate
@optional
///—————————————————————————–
/// @name Starting and Stopping the Queue
///—————————————————————————–
/**
Sent when the queue transitions from an empty state to processing requests.
@param queue The queue that began processing requests.
*/
– (void)requestQueueDidBeginLoading:(RKRequestQueue *)queue;
/**
Sent when queue transitions from a processing state to an empty start.
@param queue The queue that finished processing requests.
*/
– (void)requestQueueDidFinishLoading:(RKRequestQueue *)queue;
/**
Sent when the queue has been suspended and request processing has been halted.
@param queue The request queue that has been suspended.
*/
– (void)requestQueueWasSuspended:(RKRequestQueue *)queue;
/**
Sent when the queue has been unsuspended and request processing has resumed.
@param queue The request queue that has resumed processing.
*/
– (void)requestQueueWasUnsuspended:(RKRequestQueue *)queue;
///—————————————————————————–
/// @name Processing Requests
///—————————————————————————–
/**
Sent before queue sends a request.
@param queue The queue that will process the request.
@param request The request to be processed.
*/
– (void)requestQueue:(RKRequestQueue *)queue willSendRequest:(RKRequest *)request;
/**
Sent after queue has sent a request.
@param queue The queue that processed the request.
@param request The processed request.
*/
– (void)requestQueue:(RKRequestQueue *)queue didSendRequest:(RKRequest *)request;
/**
Sent when queue received a response for a request.
@param queue The queue that received the response.
@param response The response that was received.
*/
– (void)requestQueue:(RKRequestQueue *)queue didLoadResponse:(RKResponse *)response;
/**
Sent when queue has cancelled a request.
@param queue The queue that cancelled the request.
@param request The cancelled request.
*/
– (void)requestQueue:(RKRequestQueue *)queue didCancelRequest:(RKRequest *)request;
/**
Sent when an attempted request fails.
@param queue The queue in which the request failed from.
@param request The failed request.
@param error An NSError object containing the RKRestKitError that caused the
request to fail.
*/
– (void)requestQueue:(RKRequestQueue *)queue didFailRequest:(RKRequest *)request withError:(NSError *)error;
@end
#if TARGET_OS_IPHONE
/**
A category on UIApplication to allow for jointly managing the network activity
indicator.
Adopted from ‘iOS Recipes’ book: http://pragprog.com/book/cdirec/ios-recipes
*/
@interface UIApplication (RKNetworkActivity)
/**
Returns the number of network activity requests.
*/
@property (nonatomic, assign, readonly) NSInteger networkActivityCount;
/**
Push a network activity request onto the stack.
*/
– (void)pushNetworkActivity;
/**
Pop a network activity request off the stack.
*/
– (void)popNetworkActivity;
/**
Reset the network activity stack.
*/
– (void)resetNetworkActivity;
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestQueue.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestQueue.m
//
// RKRequestQueue.m
// RestKit
//
// Created by Blake Watters on 12/1/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#endif
#import “RKClient.h”
#import “RKRequestQueue.h”
#import “RKResponse.h”
#import “RKNotifications.h”
#import “RKLog.h”
#import “RKFixCategoryBug.h”
RK_FIX_CATEGORY_BUG(UIApplication_RKNetworkActivity)
// Constants
static NSMutableArray* RKRequestQueueInstances = nil;
static const NSTimeInterval kFlushDelay = 0.3;
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetworkQueue
@interface RKRequestQueue ()
@property (nonatomic, retain, readwrite) NSString* name;
@end
@implementation RKRequestQueue
@synthesize name = _name;
@synthesize delegate = _delegate;
@synthesize concurrentRequestsLimit = _concurrentRequestsLimit;
@synthesize requestTimeout = _requestTimeout;
@synthesize suspended = _suspended;
#if TARGET_OS_IPHONE
@synthesize showsNetworkActivityIndicatorWhenBusy = _showsNetworkActivityIndicatorWhenBusy;
#endif
+ (RKRequestQueue*)sharedQueue {
RKLogWarning(@”Deprecated invocation of [RKRequestQueue sharedQueue]. Returning [RKClient sharedClient].requestQueue. Update your code to reference the queue you want explicitly.”);
return [RKClient sharedClient].requestQueue;
}
+ (void)setSharedQueue:(RKRequestQueue*)requestQueue {
RKLogWarning(@”Deprecated access to [RKRequestQueue setSharedQueue:]. Invoking [[RKClient sharedClient] setRequestQueue:]. Update your code to reference the specific queue instance you want.”);
[RKClient sharedClient].requestQueue = requestQueue;
}
+ (id)requestQueue {
return [[self new] autorelease];
}
+ (id)newRequestQueueWithName:(NSString*)name {
if (RKRequestQueueInstances == nil) {
RKRequestQueueInstances = [NSMutableArray new];
}
if ([self requestQueueExistsWithName:name]) {
return nil;
}
RKRequestQueue* queue = [self new];
queue.name = name;
[RKRequestQueueInstances addObject:[NSValue valueWithNonretainedObject:queue]];
return queue;
}
+ (id)requestQueueWithName:(NSString *)name {
if (RKRequestQueueInstances == nil) {
RKRequestQueueInstances = [NSMutableArray new];
}
// Find existing reference
NSArray *requestQueueInstances = [RKRequestQueueInstances copy];
RKRequestQueue *namedQueue = nil;
for (NSValue* value in requestQueueInstances) {
RKRequestQueue* queue = (RKRequestQueue*) [value nonretainedObjectValue];
if ([queue.name isEqualToString:name]) {
namedQueue = queue;
break;
}
}
[requestQueueInstances release];
if (namedQueue == nil) {
namedQueue = [self requestQueue];
namedQueue.name = name;
[RKRequestQueueInstances addObject:[NSValue valueWithNonretainedObject:namedQueue]];
}
return namedQueue;
}
+ (BOOL)requestQueueExistsWithName:(NSString*)name {
BOOL queueExists = NO;
if (RKRequestQueueInstances) {
NSArray *requestQueueInstances = [RKRequestQueueInstances copy];
for (NSValue* value in requestQueueInstances) {
RKRequestQueue* queue = (RKRequestQueue*) [value nonretainedObjectValue];
if ([queue.name isEqualToString:name]) {
queueExists = YES;
break;
}
}
[requestQueueInstances release];
}
return queueExists;
}
– (id)init {
if ((self = [super init])) {
_requests = [[NSMutableArray alloc] init];
_loadingRequests = [[NSMutableSet alloc] init];
_suspended = YES;
_concurrentRequestsLimit = 5;
_requestTimeout = 300;
_showsNetworkActivityIndicatorWhenBusy = NO;
#if TARGET_OS_IPHONE
BOOL backgroundOK = &UIApplicationDidEnterBackgroundNotification != NULL;
if (backgroundOK) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willTransitionToBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willTransitionToForeground)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
#endif
}
return self;
}
– (void)removeFromNamedQueues {
if (self.name) {
for (NSValue* value in RKRequestQueueInstances) {
RKRequestQueue* queue = (RKRequestQueue*) [value nonretainedObjectValue];
if ([queue.name isEqualToString:self.name]) {
[RKRequestQueueInstances removeObject:value];
return;
}
}
}
}
– (void)dealloc {
RKLogDebug(@”Queue instance is being deallocated: %@”, self);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self removeFromNamedQueues];
[_queueTimer invalidate];
[_loadingRequests release];
_loadingRequests = nil;
[_requests release];
_requests = nil;
[super dealloc];
}
– (NSUInteger)count {
return [_requests count];
}
– (NSString*)description {
return [NSString stringWithFormat:@”<%@: %p name=%@ suspended=%@ requestCount=%d loadingCount=%d/%d>“,
NSStringFromClass([self class]), self, self.name, self.suspended ? @”YES” : @”NO”,
self.count, self.loadingCount, self.concurrentRequestsLimit];
}
– (NSUInteger)loadingCount {
return [_loadingRequests count];
}
– (void)addLoadingRequest:(RKRequest*)request {
if (self.loadingCount == 0) {
RKLogTrace(@”Loading count increasing from 0 to 1. Firing requestQueueDidBeginLoading”);
// Transitioning from empty to processing
if ([_delegate respondsToSelector:@selector(requestQueueDidBeginLoading:)]) {
[_delegate requestQueueDidBeginLoading:self];
}
#if TARGET_OS_IPHONE
if (self.showsNetworkActivityIndicatorWhenBusy) {
[[UIApplication sharedApplication] pushNetworkActivity];
}
#endif
}
@synchronized(self) {
[_loadingRequests addObject:request];
}
RKLogTrace(@”Loading count now %ld for queue %@”, (long) self.loadingCount, self);
}
– (void)removeLoadingRequest:(RKRequest*)request {
if (self.loadingCount == 1 && [_loadingRequests containsObject:request]) {
RKLogTrace(@”Loading count decreasing from 1 to 0. Firing requestQueueDidFinishLoading”);
// Transition from processing to empty
if ([_delegate respondsToSelector:@selector(requestQueueDidFinishLoading:)]) {
[_delegate requestQueueDidFinishLoading:self];
}
#if TARGET_OS_IPHONE
if (self.showsNetworkActivityIndicatorWhenBusy) {
[[UIApplication sharedApplication] popNetworkActivity];
}
#endif
}
@synchronized(self) {
[_loadingRequests removeObject:request];
}
RKLogTrace(@”Loading count now %ld for queue %@”, (long) self.loadingCount, self);
}
– (void)loadNextInQueueDelayed {
if (!_queueTimer) {
_queueTimer = [NSTimer scheduledTimerWithTimeInterval:kFlushDelay
target:self
selector:@selector(loadNextInQueue)
userInfo:nil
repeats:NO];
RKLogTrace(@”Timer initialized with delay %f for queue %@”, kFlushDelay, self);
}
}
– (RKRequest*)nextRequest {
for (NSUInteger i = 0; i < [_requests count]; i++) {
RKRequest* request = [_requests objectAtIndex:i];
if ([request isUnsent]) {
return request;
}
}
return nil;
}
- (void)loadNextInQueue {
// We always want to dispatch requests from the main thread so the current thread does not terminate
// and cause us to lose the delegate callbacks
if (! [NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(loadNextInQueue) withObject:nil waitUntilDone:NO];
return;
}
// Make sure that the Request Queue does not fire off any requests until the Reachability state has been determined.
if (self.suspended) {
_queueTimer = nil;
[self loadNextInQueueDelayed];
RKLogTrace(@"Deferring request loading for queue %@ due to suspension", self);
return;
}
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
_queueTimer = nil;
@synchronized(self) {
RKRequest* request = [self nextRequest];
while (request && self.loadingCount < _concurrentRequestsLimit) {
RKLogTrace(@"Processing request %@ in queue %@", request, self);
if ([_delegate respondsToSelector:@selector(requestQueue:willSendRequest:)]) {
[_delegate requestQueue:self willSendRequest:request];
}
[self addLoadingRequest:request];
RKLogDebug(@"Sent request %@ from queue %@. Loading count = %ld of %ld", request, self, (long) self.loadingCount, (long) _concurrentRequestsLimit);
[request sendAsynchronously];
if ([_delegate respondsToSelector:@selector(requestQueue:didSendRequest:)]) {
[_delegate requestQueue:self didSendRequest:request];
}
request = [self nextRequest];
}
}
if (_requests.count && !_suspended) {
[self loadNextInQueueDelayed];
}
[pool drain];
}
- (void)setSuspended:(BOOL)isSuspended {
if (_suspended != isSuspended) {
if (isSuspended) {
RKLogDebug(@"Queue %@ has been suspended", self);
// Becoming suspended
if ([_delegate respondsToSelector:@selector(requestQueueWasSuspended:)]) {
[_delegate requestQueueWasSuspended:self];
}
} else {
RKLogDebug(@"Queue %@ has been unsuspended", self);
// Becoming unsupended
if ([_delegate respondsToSelector:@selector(requestQueueWasUnsuspended:)]) {
[_delegate requestQueueWasUnsuspended:self];
}
}
}
_suspended = isSuspended;
if (!_suspended) {
[self loadNextInQueue];
} else if (_queueTimer) {
[_queueTimer invalidate];
_queueTimer = nil;
}
}
- (void)addRequest:(RKRequest*)request {
RKLogTrace(@"Request %@ added to queue %@", request, self);
NSAssert(![self containsRequest:request], @"Attempting to add the same request multiple times");
@synchronized(self) {
[_requests addObject:request];
request.queue = self;
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processRequestDidFinishLoadingNotification:)
name:RKRequestDidFinishLoadingNotification
object:request];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processRequestDidLoadResponseNotification:)
name:RKRequestDidLoadResponseNotification
object:request];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processRequestDidFailWithErrorNotification:)
name:RKRequestDidFailWithErrorNotification
object:request];
[self loadNextInQueue];
}
- (BOOL)removeRequest:(RKRequest*)request {
if ([self containsRequest:request]) {
RKLogTrace(@"Removing request %@ from queue %@", request, self);
@synchronized(self) {
[self removeLoadingRequest:request];
[_requests removeObject:request];
request.queue = nil;
}
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKRequestDidLoadResponseNotification object:request];
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKRequestDidFailWithErrorNotification object:request];
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKRequestDidFinishLoadingNotification object:request];
return YES;
}
RKLogWarning(@"Failed to remove request %@ from queue %@: it is not in the queue.", request, self);
return NO;
}
- (BOOL)containsRequest:(RKRequest*)request {
@synchronized(self) {
return [_requests containsObject:request];
}
}
- (void)cancelRequest:(RKRequest*)request loadNext:(BOOL)loadNext {
if ([request isUnsent]) {
RKLogDebug(@"Cancelled undispatched request %@ and removed from queue %@", request, self);
[self removeRequest:request];
request.delegate = nil;
if ([_delegate respondsToSelector:@selector(requestQueue:didCancelRequest:)]) {
[_delegate requestQueue:self didCancelRequest:request];
}
} else if ([self containsRequest:request] && [request isLoading]) {
RKLogDebug(@"Cancelled loading request %@ and removed from queue %@", request, self);
[request cancel];
request.delegate = nil;
if ([_delegate respondsToSelector:@selector(requestQueue:didCancelRequest:)]) {
[_delegate requestQueue:self didCancelRequest:request];
}
[self removeRequest:request];
if (loadNext) {
[self loadNextInQueue];
}
}
}
- (void)cancelRequest:(RKRequest*)request {
[self cancelRequest:request loadNext:YES];
}
- (void)cancelRequestsWithDelegate:(NSObject
RKLogDebug(@”Cancelling all request in queue %@ with delegate %p”, self, delegate);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* requestsCopy = [NSArray arrayWithArray:_requests];
for (RKRequest* request in requestsCopy) {
if (request.delegate && request.delegate == delegate) {
[self cancelRequest:request];
}
}
[pool drain];
}
– (void)abortRequestsWithDelegate:(NSObject
RKLogDebug(@”Aborting all request in queue %@ with delegate %p”, self, delegate);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* requestsCopy = [NSArray arrayWithArray:_requests];
for (RKRequest* request in requestsCopy) {
if (request.delegate && request.delegate == delegate) {
request.delegate = nil;
[self cancelRequest:request];
}
}
[pool drain];
}
– (void)cancelAllRequests {
RKLogDebug(@”Cancelling all request in queue %@”, self);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* requestsCopy = [NSArray arrayWithArray:_requests];
for (RKRequest* request in requestsCopy) {
[self cancelRequest:request loadNext:NO];
}
[pool drain];
}
– (void)start {
RKLogDebug(@”Started queue %@”, self);
[self setSuspended:NO];
}
– (void)processRequestDidLoadResponseNotification:(NSNotification *)notification {
NSAssert([notification.object isKindOfClass:[RKRequest class]], @”Notification expected to contain an RKRequest, got a %@”, NSStringFromClass([notification.object class]));
RKLogTrace(@”Received notification: %@”, notification);
RKRequest* request = (RKRequest*)notification.object;
NSDictionary* userInfo = [notification userInfo];
// We successfully loaded a response
RKLogDebug(@”Received response for request %@, removing from queue. (Now loading %ld of %ld)”, request, (long) self.loadingCount, (long) _concurrentRequestsLimit);
RKResponse* response = [userInfo objectForKey:RKRequestDidLoadResponseNotificationUserInfoResponseKey];
if ([_delegate respondsToSelector:@selector(requestQueue:didLoadResponse:)]) {
[_delegate requestQueue:self didLoadResponse:response];
}
[self removeLoadingRequest:request];
[self loadNextInQueue];
}
– (void)processRequestDidFailWithErrorNotification:(NSNotification *)notification {
NSAssert([notification.object isKindOfClass:[RKRequest class]], @”Notification expected to contain an RKRequest, got a %@”, NSStringFromClass([notification.object class]));
RKLogTrace(@”Received notification: %@”, notification);
RKRequest* request = (RKRequest*)notification.object;
NSDictionary* userInfo = [notification userInfo];
// We failed with an error
NSError* error = nil;
if (userInfo) {
error = [userInfo objectForKey:RKRequestDidFailWithErrorNotificationUserInfoErrorKey];
RKLogDebug(@”Request %@ failed loading in queue %@ with error: %@.(Now loading %ld of %ld)”, request, self,
[error localizedDescription], (long) self.loadingCount, (long) _concurrentRequestsLimit);
} else {
RKLogWarning(@”Received RKRequestDidFailWithErrorNotification without a userInfo, something is amiss…”);
}
if ([_delegate respondsToSelector:@selector(requestQueue:didFailRequest:withError:)]) {
[_delegate requestQueue:self didFailRequest:request withError:error];
}
[self removeLoadingRequest:request];
[self loadNextInQueue];
}
/*
Invoked via observation when a request has loaded a response or failed with an
error. Remove the completed request from the queue and continue processing
*/
– (void)processRequestDidFinishLoadingNotification:(NSNotification *)notification {
NSAssert([notification.object isKindOfClass:[RKRequest class]], @”Notification expected to contain an RKRequest, got a %@”, NSStringFromClass([notification.object class]));
RKLogTrace(@”Received notification: %@”, notification);
RKRequest* request = (RKRequest*)notification.object;
if ([self containsRequest:request]) {
[self removeRequest:request];
// Load the next request
[self loadNextInQueue];
} else {
RKLogWarning(@”Request queue %@ received unexpected lifecycle notification %@ for request %@: Request not found in queue.”, [notification name], self, request);
}
}
#pragma mark – Background Request Support
– (void)willTransitionToBackground {
RKLogDebug(@”App is transitioning into background, suspending queue”);
// Suspend the queue so background requests do not trigger additional requests on state changes
self.suspended = YES;
}
– (void)willTransitionToForeground {
RKLogDebug(@”App returned from background, unsuspending queue”);
self.suspended = NO;
}
@end
#if TARGET_OS_IPHONE
@implementation UIApplication (RKNetworkActivity)
static NSInteger networkActivityCount;
– (NSInteger)networkActivityCount {
@synchronized(self) {
return networkActivityCount;
}
}
– (void)refreshActivityIndicator {
if(![NSThread isMainThread]) {
SEL sel_refresh = @selector(refreshActivityIndicator);
[self performSelectorOnMainThread:sel_refresh withObject:nil waitUntilDone:NO];
return;
}
BOOL active = (self.networkActivityCount > 0);
self.networkActivityIndicatorVisible = active;
}
– (void)pushNetworkActivity {
@synchronized(self) {
networkActivityCount++;
}
[self refreshActivityIndicator];
}
– (void)popNetworkActivity {
@synchronized(self) {
if (networkActivityCount > 0) {
networkActivityCount–;
} else {
networkActivityCount = 0;
RKLogError(@”Unbalanced network activity: count already 0.”);
}
}
[self refreshActivityIndicator];
}
– (void)resetNetworkActivity {
@synchronized(self) {
networkActivityCount = 0;
}
[self refreshActivityIndicator];
}
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestQueue.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestSerializable.h
//
// RKRequestSerializable.h
// RestKit
//
// Created by Blake Watters on 8/3/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
This protocol is implemented by objects that can be serialized into a
representation suitable for transmission over a REST request. Suitable
serializations are x-www-form-urlencoded and multipart/form-data.
@warning One of the following methods MUST be implemented for your serializable
implementation to be complete:
– (NSData *)HTTPBody – If you are allowing serialization of a small in-memory
data structure, implement HTTPBody as it is much simpler.
– (NSInputStream *)HTTPBodyStream – This provides support for streaming a large
payload from disk instead of memory.
*/
@protocol RKRequestSerializable
///—————————————————————————–
/// @name HTTP Headers
///—————————————————————————–
/**
The value of the Content-Type header for the HTTP Body representation of the
serialization.
@return A string value of the Content-Type header for the HTTP body.
*/
– (NSString *)HTTPHeaderValueForContentType;
@optional
///—————————————————————————–
/// @name Body Implementation
///—————————————————————————–
/**
An NSData representing the HTTP Body serialization of the object implementing
the protocol.
@return An NSData object respresenting the HTTP body serialization.
*/
– (NSData *)HTTPBody;
/**
Returns an input stream for reading the serialization as a stream used to
provide support for handling large HTTP payloads.
@return An input stream for reading the serialization as a stream.
*/
– (NSInputStream *)HTTPBodyStream;
///—————————————————————————–
/// @name Optional HTTP Headers
///—————————————————————————–
/**
Returns the length of the HTTP Content-Length header.
@return Unsigned integer length of the HTTP Content-Length header.
*/
– (NSUInteger)HTTPHeaderValueForContentLength;
/**
The value of the Content-Type header for the HTTP Body representation of the
serialization.
@bug **DEPRECATED** in v0.10.0: Implement [RKRequestSerializable HTTPHeaderValueForContentType]
instead.
@return A string value of the Content-Type header for the HTTP body.
*/
– (NSString *)ContentTypeHTTPHeader DEPRECATED_ATTRIBUTE;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestSerializable.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestSerialization.h
//
// RKRequestSerialization.h
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequestSerializable.h”
/**
A simple implementation of the RKRequestSerializable protocol suitable for
wrapping a MIME Type string and HTTP Body into a format that can be sent as the
params of an RKRequest.
@see RKRequestSerializable
*/
@interface RKRequestSerialization : NSObject
NSData *_data;
NSString *_MIMEType;
}
///—————————————————————————–
/// @name Creating a Serialization
///—————————————————————————–
/**
Creates and returns a new serialization enclosing an NSData object with the
specified MIME type.
@param data An NSData object to initialize the serialization with.
@param MIMEType A string of the MIME type of the provided data.
@return An autoreleased RKRequestSerialization object with the data and MIME
type set.
*/
+ (id)serializationWithData:(NSData *)data MIMEType:(NSString *)MIMEType;
/**
Returns a new serialization enclosing an NSData object with the specified MIME
type.
@param data An NSData object to initialize the serialization with.
@param MIMEType A string of the MIME type of the provided data.
@return An RKRequestSerialization object with the data and MIME type set.
*/
– (id)initWithData:(NSData *)data MIMEType:(NSString *)MIMEType;
///—————————————————————————–
/// @name Properties
///—————————————————————————–
/**
Returns the data enclosed in this serialization.
*/
@property (nonatomic, readonly) NSData *data;
/**
Returns the MIME type of the data in this serialization.
*/
@property (nonatomic, readonly) NSString *MIMEType;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestSerialization.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKRequestSerialization.m
//
// RKRequestSerialization.m
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequestSerialization.h”
@implementation RKRequestSerialization
@synthesize data = _data;
@synthesize MIMEType = _MIMEType;
– (id)initWithData:(NSData *)data MIMEType:(NSString *)MIMEType {
NSAssert(data, @”Cannot create a request serialization without Data”);
NSAssert(MIMEType, @”Cannot create a request serialization without a MIME Type”);
self = [super init];
if (self) {
_data = [data retain];
_MIMEType = [MIMEType retain];
}
return self;
}
+ (id)serializationWithData:(NSData *)data MIMEType:(NSString *)MIMEType {
return [[[RKRequestSerialization alloc] initWithData:data MIMEType:MIMEType] autorelease];
}
– (void)dealloc {
[_data release];
[_MIMEType release];
[super dealloc];
}
– (NSString *)HTTPHeaderValueForContentType {
return self.MIMEType;
}
– (NSData *)HTTPBody {
return self.data;
}
– (NSUInteger)HTTPHeaderValueForContentLength {
return [self.data length];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKRequestSerialization.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKResponse.h
//
// RKResponse.h
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKRequest.h”
/**
Models the response portion of an HTTP request/response cycle
*/
@interface RKResponse : NSObject {
RKRequest *_request;
NSHTTPURLResponse *_httpURLResponse;
NSMutableData *_body;
NSError *_failureError;
BOOL _loading;
NSDictionary *_responseHeaders;
}
///—————————————————————————–
/// @name Creating a Response
///—————————————————————————–
/**
Initializes a new response object for a REST request.
@param request The request that the response being created belongs to.
@return An RKResponse object with the request parameter set.
*/
– (id)initWithRequest:(RKRequest *)request;
/**
Initializes a new response object from a cached request.
@param request The request that the response being created belongs to.
@param body The data of the body of the response.
@param headers A dictionary of the response’s headers.
@return An RKResponse object with the request, body, and header parameters set.
*/
– (id)initWithRequest:(RKRequest *)request body:(NSData *)body headers:(NSDictionary *)headers;
/**
Initializes a response object from the results of a synchronous request.
@param request The request that the response being created belongs to.
@param URLResponse The response from the NSURLConnection call containing the
headers and HTTP status code.
@param body The data of the body of the response.
@param error The error returned from the NSURLConnection call, if any.
@return An RKResponse object with the results of the synchronous request
derived from the NSHTTPURLResponse and body passed.
*/
– (id)initWithSynchronousRequest:(RKRequest *)request URLResponse:(NSHTTPURLResponse *)URLResponse body:(NSData *)body error:(NSError *)error;
///—————————————————————————–
/// @name Accessing the Request
///—————————————————————————–
/**
The request that generated this response.
*/
@property (nonatomic, assign, readonly) RKRequest *request;
/**
The URL the response was loaded from.
*/
@property (nonatomic, readonly) NSURL *URL;
///—————————————————————————–
/// @name Accessing the Response Components
///—————————————————————————–
/**
The status code of the HTTP response.
*/
@property (nonatomic, readonly) NSInteger statusCode;
/**
Return a dictionary of headers sent with the HTTP response.
*/
@property (nonatomic, readonly) NSDictionary *allHeaderFields;
/**
An NSArray of NSHTTPCookie objects associated with the response.
*/
@property (nonatomic, readonly) NSArray *cookies;
/**
Returns the localized human readable representation of the HTTP Status Code
returned.
*/
– (NSString *)localizedStatusCodeString;
///—————————————————————————–
/// @name Accessing Common Headers
///—————————————————————————–
/**
Returns the value of ‘Content-Type’ HTTP header
*/
– (NSString *)contentType;
/**
Returns the value of the ‘Content-Length’ HTTP header
*/
– (NSString *)contentLength;
/**
Returns the value of the ‘Location’ HTTP Header
*/
– (NSString *)location;
///—————————————————————————–
/// @name Reading the Body Content
///—————————————————————————–
/**
The data returned as the response body.
*/
@property (nonatomic, readonly) NSData *body;
/**
Returns the response body as an NSString
*/
– (NSString *)bodyAsString;
/**
Returns the response body parsed as JSON into an object
@bug **DEPRECATED** in v0.10.0
*/
– (id)bodyAsJSON DEPRECATED_ATTRIBUTE;
/**
Returns the response body parsed as JSON into an object
@param error An NSError to populate if something goes wrong while parsing the
body JSON into an object.
*/
– (id)parsedBody:(NSError **)error;
///—————————————————————————–
/// @name Handling Errors
///—————————————————————————–
/**
The error returned if the URL connection fails.
*/
@property (nonatomic, readonly) NSError *failureError;
/**
Determines if there is an error object and uses it’s localized message
@return A string of the localized error message.
*/
– (NSString *)failureErrorDescription;
/**
Indicates whether the response was loaded from RKCache
@return YES if the response was loaded from the cache
*/
– (BOOL)wasLoadedFromCache;
///—————————————————————————–
/// @name Determining the Status Range of the Response
///—————————————————————————–
/**
Indicates that the connection failed to reach the remote server. The details of
the failure are available on the failureError reader.
@return YES if the connection failed to reach the remote server.
*/
– (BOOL)isFailure;
/**
Indicates an invalid HTTP response code less than 100 or greater than 600
@return YES if the HTTP response code is less than 100 or greater than 600
*/
– (BOOL)isInvalid;
/**
Indicates an informational HTTP response code between 100 and 199
@return YES if the HTTP response code is between 100 and 199
*/
– (BOOL)isInformational;
/**
Indicates an HTTP response code between 200 and 299.
Confirms that the server received, understood, accepted and processed the
request successfully.
@return YES if the HTTP response code is between 200 and 299
*/
– (BOOL)isSuccessful;
/**
Indicates an HTTP response code between 300 and 399.
This class of status code indicates that further action needs to be taken by
the user agent in order to fulfil the request. The action required may be
carried out by the user agent without interaction with the user if and only if
the method used in the second request is GET or HEAD.
@return YES if the HTTP response code is between 300 and 399.
*/
– (BOOL)isRedirection;
/**
Indicates an HTTP response code between 400 and 499.
This status code is indented for cases in which the client seems to have erred.
@return YES if the HTTP response code is between 400 and 499.
*/
– (BOOL)isClientError;
/**
Indicates an HTTP response code between 500 and 599.
This state code occurs when the server failed to fulfill an apparently valid
request.
@return YES if the HTTP response code is between 500 and 599.
*/
– (BOOL)isServerError;
///—————————————————————————–
/// @name Determining Specific Statuses
///—————————————————————————–
/**
Indicates that the response is either a server or a client error.
@return YES if the response is either a server or client error, with a response
code between 400 and 599.
*/
– (BOOL)isError;
/**
Indicates an HTTP response code of 200.
@return YES if the response is 200 OK.
*/
– (BOOL)isOK;
/**
Indicates an HTTP response code of 201.
@return YES if the response is 201 Created.
*/
– (BOOL)isCreated;
/**
Indicates an HTTP response code of 204.
@return YES if the response is 204 No Content.
*/
– (BOOL)isNoContent;
/**
Indicates an HTTP response code of 304.
@return YES if the response is 304 Not Modified.
*/
– (BOOL)isNotModified;
/**
Indicates an HTTP response code of 401.
@return YES if the response is 401 Unauthorized.
*/
– (BOOL)isUnauthorized;
/**
Indicates an HTTP response code of 403.
@return YES if the response is 403 Forbidden.
*/
– (BOOL)isForbidden;
/**
Indicates an HTTP response code of 404.
@return YES if the response is 404 Not Found.
*/
– (BOOL)isNotFound;
/**
Indicates an HTTP response code of 409.
@return YES if the response is 409 Conflict.
*/
– (BOOL)isConflict;
/**
Indicates an HTTP response code of 410.
@return YES if the response is 410 Gone.
*/
– (BOOL)isGone;
/**
Indicates an HTTP response code of 422.
@return YES if the response is 422 Unprocessable Entity.
*/
– (BOOL)isUnprocessableEntity;
/**
Indicates an HTTP response code of 301, 302, 303 or 307.
@return YES if the response requires a redirect to finish processing.
*/
– (BOOL)isRedirect;
/**
Indicates an empty HTTP response code of 201, 204, or 304
@return YES if the response body is empty.
*/
– (BOOL)isEmpty;
/**
Indicates an HTTP response code of 503
@return YES if the response is 503 Service Unavailable.
*/
– (BOOL)isServiceUnavailable;
///—————————————————————————–
/// @name Accessing the Response’s MIME Type and Encoding
///—————————————————————————–
/**
The MIME Type of the response body.
*/
@property (nonatomic, readonly) NSString *MIMEType;
/**
True when the server turned an HTML response.
@return YES when the MIME type is text/html.
*/
– (BOOL)isHTML;
/**
True when the server turned an XHTML response
@return YES when the MIME type is application/xhtml+xml.
*/
– (BOOL)isXHTML;
/**
True when the server turned an XML response
@return YES when the MIME type is application/xml.
*/
– (BOOL)isXML;
/**
True when the server turned an JSON response
@return YES when the MIME type is application/json.
*/
– (BOOL)isJSON;
/**
Returns the name of the string encoding used for the response body
*/
– (NSString *)bodyEncodingName;
/**
Returns the string encoding used for the response body
*/
– (NSStringEncoding)bodyEncoding;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKResponse.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKResponse.m
//
// RKResponse.m
// RestKit
//
// Created by Blake Watters on 7/28/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKResponse.h”
#import “RKNotifications.h”
#import “RKLog.h”
#import “RKParserRegistry.h”
#import “RKRequestCache.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
#define RKResponseIgnoreDelegateIfCancelled(…) \
if (self.request && [self.request isCancelled]) { \
RKLogDebug(@”%s: Ignoring NSURLConnection delegate message sent after cancel.”, __PRETTY_FUNCTION__); \
return __VA_ARGS__; \
}
@implementation RKResponse
@synthesize body = _body;
@synthesize request = _request;
@synthesize failureError = _failureError;
– (id)init {
self = [super init];
if (self) {
_body = [[NSMutableData alloc] init];
_failureError = nil;
_loading = NO;
_responseHeaders = nil;
}
return self;
}
– (id)initWithRequest:(RKRequest *)request {
self = [self init];
if (self) {
// We don’t retain here as we’re letting RKRequestQueue manage
// request ownership
_request = request;
}
return self;
}
– (id)initWithRequest:(RKRequest*)request body:(NSData*)body headers:(NSDictionary*)headers {
self = [self initWithRequest:request];
if (self) {
[_body release];
_body = [[NSMutableData dataWithData:body] retain];
_responseHeaders = [headers retain];
}
return self;
}
– (id)initWithSynchronousRequest:(RKRequest*)request URLResponse:(NSHTTPURLResponse*)URLResponse body:(NSData*)body error:(NSError*)error {
self = [super init];
if (self) {
_request = request;
_httpURLResponse = [URLResponse retain];
_failureError = [error retain];
_body = [[NSMutableData dataWithData:body] retain];
_loading = NO;
}
return self;
}
– (void)dealloc {
_request = nil;
[_httpURLResponse release];
_httpURLResponse = nil;
[_body release];
_body = nil;
[_failureError release];
_failureError = nil;
[_responseHeaders release];
_responseHeaders = nil;
[super dealloc];
}
– (BOOL)hasCredentials {
return _request.username && _request.password;
}
– (BOOL)isServerTrusted:(SecTrustRef)trust {
BOOL proceed = NO;
if (_request.disableCertificateValidation) {
proceed = YES;
} else if ([_request.additionalRootCertificates count] > 0 ) {
CFArrayRef rootCerts = (CFArrayRef)[_request.additionalRootCertificates allObjects];
SecTrustResultType result;
OSStatus returnCode;
if (rootCerts && CFArrayGetCount(rootCerts)) {
// this could fail, but the trust evaluation will proceed (it’s likely to fail, of course)
SecTrustSetAnchorCertificates(trust, rootCerts);
}
returnCode = SecTrustEvaluate(trust, &result);
if (returnCode == errSecSuccess) {
proceed = (result == kSecTrustResultProceed || result == kSecTrustResultConfirm || result == kSecTrustResultUnspecified);
if (result == kSecTrustResultRecoverableTrustFailure) {
// TODO: should try to recover here
// call SecTrustGetCssmResult() for more information about the failure
}
}
}
return proceed;
}
// Handle basic auth & SSL certificate validation
– (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
RKResponseIgnoreDelegateIfCancelled();
RKLogDebug(@”Received authentication challenge”);
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
if ([self isServerTrusted:trust]) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:trust] forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
return;
}
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:[NSString stringWithFormat:@”%@”, _request.username]
password:[NSString stringWithFormat:@”%@”, _request.password]
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential
forAuthenticationChallenge:challenge];
} else {
RKLogWarning(@”Failed authentication challenge after %ld failures”, (long) [challenge previousFailureCount]);
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
– (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space {
RKResponseIgnoreDelegateIfCancelled(NO);
RKLogDebug(@”Asked if canAuthenticateAgainstProtectionSpace: with authenticationMethod = %@”, [space authenticationMethod]);
if ([[space authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
// server is using an SSL certificate that the OS can’t validate
// see whether the client settings allow validation here
if (_request.disableCertificateValidation || [_request.additionalRootCertificates count] > 0) {
return YES;
} else {
return NO;
}
}
// Handle non-SSL challenges
BOOL hasCredentials = [self hasCredentials];
if (! hasCredentials) {
RKLogWarning(@”Received an authentication challenge without any credentials to satisfy the request.”);
}
return hasCredentials;
}
– (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
if (nil == response || _request.followRedirect) {
RKLogDebug(@”Proceeding with request to %@”, request);
return request;
} else {
RKLogDebug(@”Not following redirect to %@”, request);
return nil;
}
}
– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
RKResponseIgnoreDelegateIfCancelled();
[_body appendData:data];
[_request invalidateTimeoutTimer];
if ([[_request delegate] respondsToSelector:@selector(request:didReceiveData:totalBytesReceived:totalBytesExpectedToReceive:)]) {
[[_request delegate] request:_request didReceiveData:[data length] totalBytesReceived:[_body length] totalBytesExpectedToReceive:_httpURLResponse.expectedContentLength];
}
}
– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
RKResponseIgnoreDelegateIfCancelled();
RKLogDebug(@”NSHTTPURLResponse Status Code: %ld”, (long) [response statusCode]);
RKLogDebug(@”Headers: %@”, [response allHeaderFields]);
_httpURLResponse = [response retain];
[_request invalidateTimeoutTimer];
if ([[_request delegate] respondsToSelector:@selector(request:didReceiveResponse:)]) {
[[_request delegate] request:_request didReceiveResponse:self];
}
}
– (void)connectionDidFinishLoading:(NSURLConnection *)connection {
RKResponseIgnoreDelegateIfCancelled();
RKLogTrace(@”Read response body: %@”, [self bodyAsString]);
[_request didFinishLoad:self];
}
– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
RKResponseIgnoreDelegateIfCancelled();
_failureError = [error retain];
[_request invalidateTimeoutTimer];
[_request didFailLoadWithError:_failureError];
}
– (NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request {
RKResponseIgnoreDelegateIfCancelled(nil);
RKLogWarning(@”RestKit was asked to retransmit a new body stream for a request. Possible connection error or authentication challenge?”);
return nil;
}
// In the event that the url request is a post, this delegate method will be called before
// either connection:didReceiveData: or connection:didReceiveResponse:
// However this method is only called if there is payload data to be sent.
// Therefore, we ensure the delegate recieves the did start loading here and
// in connection:didReceiveResponse: to ensure that the RKRequestDelegate
// callbacks get called in the correct order.
– (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
RKResponseIgnoreDelegateIfCancelled();
[_request invalidateTimeoutTimer];
if ([[_request delegate] respondsToSelector:@selector(request:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) {
[[_request delegate] request:_request didSendBodyData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];
}
}
– (NSString*)localizedStatusCodeString {
return [NSHTTPURLResponse localizedStringForStatusCode:[self statusCode]];
}
– (NSData *)body {
return _body;
}
– (NSString *)bodyEncodingName {
return [_httpURLResponse textEncodingName];
}
– (NSStringEncoding)bodyEncoding {
CFStringEncoding cfEncoding = kCFStringEncodingInvalidId;
NSString *textEncodingName = [self bodyEncodingName];
if (textEncodingName) {
cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef) textEncodingName);
}
return (cfEncoding == kCFStringEncodingInvalidId) ? self.request.defaultHTTPEncoding : CFStringConvertEncodingToNSStringEncoding(cfEncoding);
}
– (NSString *)bodyAsString {
return [[[NSString alloc] initWithData:self.body encoding:[self bodyEncoding]] autorelease];
}
– (id)bodyAsJSON {
[NSException raise:nil format:@”Reimplemented as parsedBody”];
return nil;
}
– (id)parsedBody:(NSError**)error {
id
if (! parser) {
RKLogWarning(@”Unable to parse response body: no parser registered for MIME Type ‘%@'”, [self MIMEType]);
return nil;
}
id object = [parser objectFromString:[self bodyAsString] error:error];
if (object == nil) {
if (error && *error) {
RKLogError(@”Unable to parse response body: %@”, [*error localizedDescription]);
}
return nil;
}
return object;
}
– (NSString*)failureErrorDescription {
if ([self isFailure]) {
return [_failureError localizedDescription];
} else {
return nil;
}
}
– (BOOL)wasLoadedFromCache {
return (_responseHeaders != nil);
}
– (NSURL*)URL {
if ([self wasLoadedFromCache]) {
return [NSURL URLWithString:[_responseHeaders valueForKey:RKRequestCacheURLHeadersKey]];
}
return [_httpURLResponse URL];
}
– (NSString*)MIMEType {
if ([self wasLoadedFromCache]) {
return [_responseHeaders valueForKey:RKRequestCacheMIMETypeHeadersKey];
}
return [_httpURLResponse MIMEType];
}
– (NSInteger)statusCode {
if ([self wasLoadedFromCache]) {
return [[_responseHeaders valueForKey:RKRequestCacheStatusCodeHeadersKey] intValue];
}
return ([_httpURLResponse respondsToSelector:@selector(statusCode)] ? [_httpURLResponse statusCode] : 200);
}
– (NSDictionary*)allHeaderFields {
if ([self wasLoadedFromCache]) {
return _responseHeaders;
}
return ([_httpURLResponse respondsToSelector:@selector(allHeaderFields)] ? [_httpURLResponse allHeaderFields] : nil);
}
– (NSArray*)cookies {
return [NSHTTPCookie cookiesWithResponseHeaderFields:self.allHeaderFields forURL:self.URL];
}
– (BOOL)isFailure {
return (nil != _failureError);
}
– (BOOL)isInvalid {
return ([self statusCode] < 100 || [self statusCode] > 600);
}
– (BOOL)isInformational {
return ([self statusCode] >= 100 && [self statusCode] < 200);
}
- (BOOL)isSuccessful {
return (([self statusCode] >= 200 && [self statusCode] < 300) || ([self wasLoadedFromCache]));
}
- (BOOL)isRedirection {
return ([self statusCode] >= 300 && [self statusCode] < 400);
}
- (BOOL)isClientError {
return ([self statusCode] >= 400 && [self statusCode] < 500);
}
- (BOOL)isServerError {
return ([self statusCode] >= 500 && [self statusCode] < 600);
}
- (BOOL)isError {
return ([self isClientError] || [self isServerError]);
}
- (BOOL)isOK {
return ([self statusCode] == 200);
}
- (BOOL)isCreated {
return ([self statusCode] == 201);
}
- (BOOL)isNoContent {
return ([self statusCode] == 204);
}
- (BOOL)isNotModified {
return ([self statusCode] == 304);
}
- (BOOL)isUnauthorized {
return ([self statusCode] == 401);
}
- (BOOL)isForbidden {
return ([self statusCode] == 403);
}
- (BOOL)isNotFound {
return ([self statusCode] == 404);
}
- (BOOL)isConflict {
return ([self statusCode] == 409);
}
- (BOOL)isGone {
return ([self statusCode] == 410);
}
- (BOOL)isUnprocessableEntity {
return ([self statusCode] == 422);
}
- (BOOL)isRedirect {
return ([self statusCode] == 301 || [self statusCode] == 302 || [self statusCode] == 303 || [self statusCode] == 307);
}
- (BOOL)isEmpty {
return ([self statusCode] == 201 || [self statusCode] == 204 || [self statusCode] == 304);
}
- (BOOL)isServiceUnavailable {
return ([self statusCode] == 503);
}
- (NSString*)contentType {
return ([[self allHeaderFields] objectForKey:@"Content-Type"]);
}
- (NSString*)contentLength {
return ([[self allHeaderFields] objectForKey:@"Content-Length"]);
}
- (NSString*)location {
return ([[self allHeaderFields] objectForKey:@"Location"]);
}
- (BOOL)isHTML {
NSString* contentType = [self contentType];
return (contentType && ([contentType rangeOfString:@"text/html"
options:NSCaseInsensitiveSearch|NSAnchoredSearch].length > 0 ||
[self isXHTML]));
}
– (BOOL)isXHTML {
NSString* contentType = [self contentType];
return (contentType &&
[contentType rangeOfString:@”application/xhtml+xml”
options:NSCaseInsensitiveSearch|NSAnchoredSearch].length > 0);
}
– (BOOL)isXML {
NSString* contentType = [self contentType];
return (contentType &&
[contentType rangeOfString:@”application/xml”
options:NSCaseInsensitiveSearch|NSAnchoredSearch].length > 0);
}
– (BOOL)isJSON {
NSString* contentType = [self contentType];
return (contentType &&
[contentType rangeOfString:@”application/json”
options:NSCaseInsensitiveSearch|NSAnchoredSearch].length > 0);
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKResponse.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKURL.h
//
// RKURL.h
// RestKit
//
// Created by Jeff Arena on 10/18/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
RKURL extends the Cocoa NSURL base class to provide support for the concepts of
base URL and resource path that are used extensively throughout the RestKit
framework. RKURL is immutable, but provides numerous methods for constructing
new RKURL instances where the received becomes the baseURL of the RKURL
instance.
Instances of RKURL are aware of:
– the baseURL they were constructed against, if any
– the resource path that was appended to that baseURL
– any query parameters present in the URL
### Example
NSDictionary *queryParams;
queryParams = [NSDictionary dictionaryWithObjectsAndKeys:@”pitbull”, @”username”,
@”pickles”, @”password”, nil];
RKURL *URL = [RKURL URLWithBaseURLString:@”http://restkit.org”
resourcePath:@”/test”
queryParameters:queryParams];
*/
@interface RKURL : NSURL
///—————————————————————————–
/// @name Creating an RKURL
///—————————————————————————–
/**
Creates and returns an RKURL object intialized with a provided base URL.
@param baseURL The URL object with which to initialize the RKURL object.
@return An RKURL object initialized with baseURL.
*/
+ (id)URLWithBaseURL:(NSURL *)baseURL;
/**
Creates and returns an RKURL object intialized with a provided base URL and
resource path.
@param baseURL The URL object with which to initialize the RKURL object.
@param resourcePath The resource path for the RKURL object.
@return An RKURL object initialized with baseURL and resourcePath.
*/
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath;
/**
Creates and returns an RKURL object intialized with a provided base URL,
resource path, and a dictionary of query parameters.
@param baseURL The URL object with which to initialize the RKURL object.
@param resourcePath The resource path for the RKURL object.
@param queryParameters The query parameters for the RKURL object.
@return An RKURL object initialized with baseURL, resourcePath, and
queryParameters.
*/
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters;
/**
Creates and returns an RKURL object intialized with a base URL constructed from
the specified base URL string.
@param baseURLString The string with which to initialize the RKURL object.
@return An RKURL object initialized with baseURLString.
*/
+ (id)URLWithBaseURLString:(NSString *)baseURLString;
/**
Creates and returns an RKURL object intialized with a base URL constructed from
the specified base URL string and resource path.
@param baseURLString The string with which to initialize the RKURL object.
@param resourcePath The resource path for the RKURL object.
@return An RKURL object initialized with baseURLString and resourcePath.
*/
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath;
/**
Creates and returns an RKURL object intialized with a base URL constructed from
the specified base URL string, resource path and a dictionary of query
parameters.
@param baseURLString The string with which to initialize the RKURL object.
@param resourcePath The resource path for the RKURL object.
@param queryParameters The query parameters for the RKURL object.
@return An RKURL object initialized with baseURLString, resourcePath and
queryParameters.
*/
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters;
/**
Initializes an RKURL object with a base URL, a resource path string, and a
dictionary of query parameters.
`initWithBaseURL:resourcePath:queryParameters:` is the designated initializer.
@param theBaseURL The NSURL with which to initialize the RKURL object.
@param theResourcePath The resource path for the RKURL object.
@param theQueryParameters The query parameters for the RKURL object.
@return An RKURL object initialized with baseURL, resourcePath and queryParameters.
*/
– (id)initWithBaseURL:(NSURL *)theBaseURL resourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters;
///—————————————————————————–
/// @name Accessing the URL parts
///—————————————————————————–
/**
Returns the base URL of the receiver.
The base URL includes everything up to the resource path, typically the portion
that is repeated in every API call.
*/
@property (nonatomic, copy, readonly) NSURL *baseURL;
/**
Returns the resource path of the receiver.
The resource path is the path portion of the complete URL beyond that contained
in the baseURL.
*/
@property (nonatomic, copy, readonly) NSString *resourcePath;
/**
Returns the query component of a URL conforming to RFC 1808 as a dictionary.
If the receiver does not conform to RFC 1808, returns nil just as
`NSURL query` does.
*/
@property (nonatomic, readonly) NSDictionary *queryParameters;
///—————————————————————————–
/// @name Modifying the URL
///—————————————————————————–
/**
Returns a new RKURL object with a new resource path appended to its path.
@param theResourcePath The resource path to append to the receiver’s path.
@return A new RKURL that refers to a new resource at theResourcePath.
*/
– (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath;
/**
Returns a new RKURL object with a new resource path appended to its path and a
dictionary of query parameters merged with the existing query component.
@param theResourcePath The resource path to append to the receiver’s path.
@param theQueryParameters A dictionary of query parameters to merge with any
existing query parameters.
@return A new RKURL that refers to a new resource at theResourcePath with a new
query component including the values from theQueryParameters.
*/
– (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters;
/**
Returns a new RKURL object with a dictionary of query parameters merged with
the existing query component.
@param theQueryParameters A dictionary of query parameters to merge with any
existing query parameters.
@return A new RKURL that refers to the same resource as the receiver with a new
query component including the values from theQueryParameters.
*/
– (RKURL *)URLByAppendingQueryParameters:(NSDictionary *)theQueryParameters;
/**
Returns a new RKURL object with the baseURL of the receiver and a new
resourcePath.
@param newResourcePath The resource path to replace the value of resourcePath
in the new RKURL object.
@return An RKURL object with newResourcePath appended to the receiver’s baseURL.
*/
– (RKURL *)URLByReplacingResourcePath:(NSString *)newResourcePath;
/**
Returns a new RKURL object with its resource path processed as a pattern and
evaluated against the specified object.
Resource paths may contain pattern strings prefixed by colons (“:”) that refer
to key-value coding accessible properties on the provided object.
For example:
// Given an RKURL initialized as:
RKURL *myURL = [RKURL URLWithBaseURLString:@”http://restkit.org”
resourcePath:@”/paginate?per_page=:perPage&page=:page”];
// And a dictionary containing values:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@”25″, @”perPage”,
@”5″, @”page”, nil];
// A new RKURL can be constructed by interpolating the dictionary with the original URL
RKURL *interpolatedURL = [myURL URLByInterpolatingResourcePathWithObject:dictionary];
The absoluteString of this new URL would be:
`http://restkit.org/paginate?per_page=25&page=5`
@see RKPathMatcher
@param object The object to call methods on for the pattern strings in the
resource path.
@return A new RKURL object with its resource path evaluated as a pattern and
interpolated with properties of object.
*/
– (RKURL *)URLByInterpolatingResourcePathWithObject:(id)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKURL.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/RKURL.m
//
// RKURL.m
// RestKit
//
// Created by Jeff Arena on 10/18/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKURL.h”
#import “RKClient.h”
#import “NSURL+RKAdditions.h”
#import “NSString+RKAdditions.h”
#import “NSDictionary+RKAdditions.h”
#import “RKLog.h”
@interface RKURL ()
@property (nonatomic, copy, readwrite) NSURL *baseURL;
@property (nonatomic, copy, readwrite) NSString *resourcePath;
@end
@implementation RKURL
@synthesize baseURL;
@synthesize resourcePath;
+ (id)URLWithBaseURL:(NSURL *)baseURL {
return [self URLWithBaseURL:baseURL resourcePath:nil queryParameters:nil];
}
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath {
return [self URLWithBaseURL:baseURL resourcePath:resourcePath queryParameters:nil];
}
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters {
return [[[self alloc] initWithBaseURL:baseURL resourcePath:resourcePath queryParameters:queryParameters] autorelease];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString {
return [self URLWithBaseURLString:baseURLString resourcePath:nil queryParameters:nil];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath {
return [self URLWithBaseURLString:baseURLString resourcePath:resourcePath queryParameters:nil];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters {
return [self URLWithBaseURL:[NSURL URLWithString:baseURLString] resourcePath:resourcePath queryParameters:queryParameters];
}
// Designated initializer. Note this diverges from NSURL due to a bug in Cocoa. We can’t
// call initWithString:relativeToURL: from a subclass.
– (id)initWithBaseURL:(NSURL *)theBaseURL resourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters {
// Merge any existing query parameters with the incoming dictionary
NSDictionary *resourcePathQueryParameters = [theResourcePath queryParameters];
NSMutableDictionary *mergedQueryParameters = [NSMutableDictionary dictionaryWithDictionary:[theBaseURL queryParameters]];
[mergedQueryParameters addEntriesFromDictionary:resourcePathQueryParameters];
[mergedQueryParameters addEntriesFromDictionary:theQueryParameters];
// Build the new URL path
NSRange queryCharacterRange = [theResourcePath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@”?”]];
NSString *resourcePathWithoutQueryString = (queryCharacterRange.location == NSNotFound) ? theResourcePath : [theResourcePath substringToIndex:queryCharacterRange.location];
NSString *baseURLPath = [[theBaseURL path] isEqualToString:@”/”] ? @”” : [[theBaseURL path] stringByStandardizingPath];
NSString *completePath = resourcePathWithoutQueryString ? [baseURLPath stringByAppendingString:resourcePathWithoutQueryString] : baseURLPath;
NSString* completePathWithQuery = [completePath stringByAppendingQueryParameters:mergedQueryParameters];
// NOTE: You can’t safely use initWithString:relativeToURL: in a NSURL subclass, see http://www.openradar.me/9729706
// So we unfortunately convert into an NSURL before going back into an NSString -> RKURL
NSURL* completeURL = [NSURL URLWithString:completePathWithQuery relativeToURL:theBaseURL];
if (!completeURL) {
RKLogError(@”Failed to build RKURL by appending resourcePath and query parameters ‘%@’ to baseURL ‘%@'”, theResourcePath, theBaseURL);
[self release];
return nil;
}
self = [self initWithString:[completeURL absoluteString]];
if (self) {
self.baseURL = theBaseURL;
self.resourcePath = theResourcePath;
}
return self;
}
– (void)dealloc {
[baseURL release];
baseURL = nil;
[resourcePath release];
resourcePath = nil;
[super dealloc];
}
– (NSDictionary *)queryParameters {
if (self.query) {
return [NSDictionary dictionaryWithURLEncodedString:self.query];
}
return nil;
}
– (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath {
return [RKURL URLWithBaseURL:self resourcePath:theResourcePath];
}
– (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters {
return [RKURL URLWithBaseURL:self resourcePath:theResourcePath queryParameters:theQueryParameters];
}
– (RKURL *)URLByAppendingQueryParameters:(NSDictionary *)theQueryParameters {
return [RKURL URLWithBaseURL:self resourcePath:nil queryParameters:theQueryParameters];
}
– (RKURL *)URLByReplacingResourcePath:(NSString *)newResourcePath {
return [RKURL URLWithBaseURL:self.baseURL resourcePath:newResourcePath];
}
– (RKURL *)URLByInterpolatingResourcePathWithObject:(id)object {
return [self URLByReplacingResourcePath:[self.resourcePath interpolateWithObject:object]];
}
#pragma mark – NSURL Overloads
/*
Overload implementations from NSURL. We consider a naked string to be initialized
with a baseURL == self. Otherwise appending/replacing resourcePath will not work.
*/
+ (id)URLWithString:(NSString *)URLString {
return [self URLWithBaseURLString:URLString];
}
– (id)initWithString:(NSString *)URLString {
self = [super initWithString:URLString];
if (self) {
self.baseURL = self;
}
return self;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Network/._RKURL.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._Network
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/ObjectMapping.h
//
// ObjectMapping.h
// RestKit
//
// Created by Blake Watters on 9/30/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectManager.h”
#import “RKObjectLoader.h”
#import “RKObjectMapping.h”
#import “RKObjectSerializer.h”
#import “RKObjectMappingProvider.h”
#import “RKObjectMappingResult.h”
#import “RKObjectMapper.h”
#import “RKParserRegistry.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._ObjectMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKConfigurationDelegate.h
//
// RKConfigurationDelegate.h
// RestKit
//
// Created by Blake Watters on 1/7/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
@class RKRequest, RKObjectLoader;
/**
The RKConfigurationDelegate formal protocol defines
methods enabling the centralization of RKRequest and
RKObjectLoader configuration. An object conforming to
the protocol can be used to set headers, authentication
credentials, etc.
RKClient and RKObjectManager conform to RKConfigurationDelegate
to configure request and object loader instances they build.
*/
@protocol RKConfigurationDelegate
@optional
/**
Configure a request before it is utilized
@param request A request object being configured for dispatch
*/
– (void)configureRequest:(RKRequest *)request;
/**
Configure an object loader before it is utilized
@param request An object loader being configured for dispatch
*/
– (void)configureObjectLoader:(RKObjectLoader *)objectLoader;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKConfigurationDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKDynamicObjectMapping.h
//
// RKDynamicObjectMapping.h
// RestKit
//
// Created by Blake Watters on 7/28/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingDefinition.h”
#import “RKObjectMapping.h”
/**
Return the appropriate object mapping given a mappable data
*/
@protocol RKDynamicObjectMappingDelegate
@required
– (RKObjectMapping *)objectMappingForData:(id)data;
@end
#ifdef NS_BLOCKS_AVAILABLE
typedef RKObjectMapping *(^RKDynamicObjectMappingDelegateBlock)(id);
#endif
/**
Defines a dynamic object mapping that determines the appropriate concrete
object mapping to apply at mapping time. This allows you to map very similar payloads
differently depending on the type of data contained therein.
*/
@interface RKDynamicObjectMapping : RKObjectMappingDefinition {
NSMutableArray *_matchers;
id
#ifdef NS_BLOCKS_AVAILABLE
RKDynamicObjectMappingDelegateBlock _objectMappingForDataBlock;
#endif
}
/**
A delegate to call back to determine the appropriate concrete object mapping
to apply to the mappable data.
@see RKDynamicObjectMappingDelegate
*/
@property (nonatomic, assign) id
#ifdef NS_BLOCKS_AVAILABLE
/**
A block to invoke to determine the appropriate concrete object mapping
to apply to the mappable data.
*/
@property (nonatomic, copy) RKDynamicObjectMappingDelegateBlock objectMappingForDataBlock;
#endif
/**
Return a new auto-released dynamic object mapping
*/
+ (RKDynamicObjectMapping *)dynamicMapping;
#if NS_BLOCKS_AVAILABLE
/**
Return a new auto-released dynamic object mapping after yielding it to the block for configuration
*/
+ (RKDynamicObjectMapping *)dynamicMappingUsingBlock:(void(^)(RKDynamicObjectMapping *dynamicMapping))block;
+ (RKDynamicObjectMapping *)dynamicMappingWithBlock:(void(^)(RKDynamicObjectMapping *dynamicMapping))block DEPRECATED_ATTRIBUTE;
#endif
/**
Defines a dynamic mapping rule stating that when the value of the key property matches the specified
value, the objectMapping should be used.
For example, suppose that we have a JSON fragment for a person that we want to map differently based on
the gender of the person. When the gender is ‘male’, we want to use the Boy class and when then the gender
is ‘female’ we want to use the Girl class. We might define our dynamic mapping like so:
RKDynamicObjectMapping* mapping = [RKDynamicObjectMapping dynamicMapping];
[mapping setObjectMapping:boyMapping whenValueOfKeyPath:@”gender” isEqualTo:@”male”];
[mapping setObjectMapping:boyMapping whenValueOfKeyPath:@”gender” isEqualTo:@”female”];
*/
– (void)setObjectMapping:(RKObjectMapping *)objectMapping whenValueOfKeyPath:(NSString *)keyPath isEqualTo:(id)value;
/**
Invoked by the RKObjectMapper and RKObjectMappingOperation to determine the appropriate RKObjectMapping to use
when mapping the specified dictionary of mappable data.
*/
– (RKObjectMapping *)objectMappingForDictionary:(NSDictionary *)dictionary;
@end
/**
Define an alias for the old class name for compatibility
@deprecated
*/
@interface RKObjectDynamicMapping : RKDynamicObjectMapping
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKDynamicObjectMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKDynamicObjectMapping.m
//
// RKDynamicObjectMapping.m
// RestKit
//
// Created by Blake Watters on 7/28/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKDynamicObjectMapping.h”
#import “RKDynamicObjectMappingMatcher.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
@implementation RKDynamicObjectMapping
@synthesize delegate = _delegate;
@synthesize objectMappingForDataBlock = _objectMappingForDataBlock;
+ (RKDynamicObjectMapping*)dynamicMapping {
return [[self new] autorelease];
}
#if NS_BLOCKS_AVAILABLE
+ (RKDynamicObjectMapping *)dynamicMappingUsingBlock:(void(^)(RKDynamicObjectMapping *))block {
RKDynamicObjectMapping* mapping = [self dynamicMapping];
block(mapping);
return mapping;
}
+ (RKDynamicObjectMapping*)dynamicMappingWithBlock:(void(^)(RKDynamicObjectMapping*))block {
return [self dynamicMappingUsingBlock:block];
}
#endif
– (id)init {
self = [super init];
if (self) {
_matchers = [NSMutableArray new];
}
return self;
}
– (void)dealloc {
[_matchers release];
[super dealloc];
}
– (void)setObjectMapping:(RKObjectMapping*)objectMapping whenValueOfKeyPath:(NSString*)keyPath isEqualTo:(id)value {
RKLogDebug(@”Adding dynamic object mapping for key ‘%@’ with value ‘%@’ to destination class: %@”, keyPath, value, NSStringFromClass(objectMapping.objectClass));
RKDynamicObjectMappingMatcher* matcher = [[RKDynamicObjectMappingMatcher alloc] initWithKey:keyPath value:value objectMapping:objectMapping];
[_matchers addObject:matcher];
[matcher release];
}
– (RKObjectMapping*)objectMappingForDictionary:(NSDictionary*)data {
NSAssert([data isKindOfClass:[NSDictionary class]], @”Dynamic object mapping can only be performed on NSDictionary mappables, got %@”, NSStringFromClass([data class]));
RKObjectMapping* mapping = nil;
RKLogTrace(@”Performing dynamic object mapping for mappable data: %@”, data);
// Consult the declarative matchers first
for (RKDynamicObjectMappingMatcher* matcher in _matchers) {
if ([matcher isMatchForData:data]) {
RKLogTrace(@”Found declarative match for data: %@.”, [matcher matchDescription]);
return matcher.objectMapping;
}
}
// Otherwise consult the delegates
if (self.delegate) {
mapping = [self.delegate objectMappingForData:data];
if (mapping) {
RKLogTrace(@”Found dynamic delegate match. Delegate = %@”, self.delegate);
return mapping;
}
}
if (self.objectMappingForDataBlock) {
mapping = self.objectMappingForDataBlock(data);
if (mapping) {
RKLogTrace(@”Found dynamic delegateBlock match. objectMappingForDataBlock = %@”, self.objectMappingForDataBlock);
}
}
return mapping;
}
@end
// Compatibility alias…
@implementation RKObjectDynamicMapping
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKDynamicObjectMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKDynamicObjectMappingMatcher.h
//
// RKDynamicObjectMappingMatcher.h
// RestKit
//
// Created by Jeff Arena on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import “RKObjectMapping.h”
@interface RKDynamicObjectMappingMatcher : NSObject {
NSString* _keyPath;
id _value;
RKObjectMapping* _objectMapping;
NSString* _primaryKeyAttribute;
BOOL (^_isMatchForDataBlock)(id data);
}
@property (nonatomic, readonly) RKObjectMapping* objectMapping;
@property (nonatomic, readonly) NSString* primaryKeyAttribute;
– (id)initWithKey:(NSString*)key value:(id)value objectMapping:(RKObjectMapping*)objectMapping;
– (id)initWithKey:(NSString*)key value:(id)value primaryKeyAttribute:(NSString*)primaryKeyAttribute;
– (id)initWithPrimaryKeyAttribute:(NSString*)primaryKeyAttribute evaluationBlock:(BOOL (^)(id data))block;
– (BOOL)isMatchForData:(id)data;
– (NSString*)matchDescription;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKDynamicObjectMappingMatcher.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKDynamicObjectMappingMatcher.m
//
// RKDynamicObjectMappingMatcher.m
// RestKit
//
// Created by Jeff Arena on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKDynamicObjectMappingMatcher.h”
// Implemented in RKObjectMappingOperation
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation RKDynamicObjectMappingMatcher
@synthesize objectMapping = _objectMapping;
@synthesize primaryKeyAttribute = _primaryKeyAttribute;
– (id)initWithKey:(NSString*)key value:(id)value objectMapping:(RKObjectMapping*)objectMapping {
self = [super init];
if (self) {
_keyPath = [key retain];
_value = [value retain];
_objectMapping = [objectMapping retain];
}
return self;
}
– (id)initWithKey:(NSString*)key value:(id)value primaryKeyAttribute:(NSString*)primaryKeyAttribute {
self = [super init];
if (self) {
_keyPath = [key retain];
_value = [value retain];
_primaryKeyAttribute = [primaryKeyAttribute retain];
}
return self;
}
– (id)initWithPrimaryKeyAttribute:(NSString*)primaryKeyAttribute evaluationBlock:(BOOL (^)(id data))block {
self = [super init];
if (self) {
_primaryKeyAttribute = [primaryKeyAttribute retain];
_isMatchForDataBlock = Block_copy(block);
}
return self;
}
– (void)dealloc {
[_keyPath release];
[_value release];
[_objectMapping release];
[_primaryKeyAttribute release];
if (_isMatchForDataBlock) {
Block_release(_isMatchForDataBlock);
}
[super dealloc];
}
– (BOOL)isMatchForData:(id)data {
if (_isMatchForDataBlock) {
return _isMatchForDataBlock(data);
}
return RKObjectIsValueEqualToValue([data valueForKeyPath:_keyPath], _value);
}
– (NSString*)matchDescription {
if (_isMatchForDataBlock) {
return @”No description available. Using block to perform match.”;
}
return [NSString stringWithFormat:@”%@ == %@”, _keyPath, _value];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKDynamicObjectMappingMatcher.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKErrorMessage.h
//
// RKError.h
// RestKit
//
// Created by Jeremy Ellison on 5/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
A destination class for mapping simple remote error messages.
*/
@interface RKErrorMessage : NSObject {
NSString* _errorMessage;
}
/**
The error message string mapped from the response payload
*/
@property (nonatomic, retain) NSString* errorMessage;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKErrorMessage.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKErrorMessage.m
//
// RKError.m
// RestKit
//
// Created by Jeremy Ellison on 5/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKErrorMessage.h”
@implementation RKErrorMessage
@synthesize errorMessage = _errorMessage;
– (void)dealloc {
[_errorMessage release];
[super dealloc];
}
– (NSString*)description {
return _errorMessage;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKErrorMessage.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKMappingOperationQueue.h
//
// RKMappingOperationQueue.h
// RestKit
//
// Created by Blake Watters on 9/20/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
Provides a simple interface for deferring portion of an larger object mapping
operation until the entire aggregate operation has completed. This is used by Core
Data to connect all object relationships once the entire object graph has been mapped,
rather than as each object is encountered.
Designed as a lightweight workalike for NSOperationQueue, which was not usable do to
its reliance on threading for concurrent operations. The threading was causing problems
with managed objects due to MOC being thread specific.
This class is not intended to be thread-safe and is used for queueing non-concurrent
operations that will be executed within the object mapper only. It is not a general purpose
work queue.
*/
@interface RKMappingOperationQueue : NSObject {
@protected
NSMutableArray *_operations;
}
/**
Adds an NSOperation to the queue for later execution
@param op The operation to enqueue
*/
– (void)addOperation:(NSOperation *)op;
/**
Adds an NSBlockOperation to the queue configured to executed the block passed
@param block A block to wrap into an operation for later execution
*/
– (void)addOperationWithBlock:(void (^)(void))block;
/**
Returns the collection of operations in the queue
@return A new aray containing the NSOperation objects in the order in which they were added to the queue
*/
– (NSArray *)operations;
/**
Returns the number of operations in the queue
@return The number of operations in the queue.
*/
– (NSUInteger)operationCount;
/**
Starts the execution of all operations in the queue in the order in which they were added to the queue. The
current threads execution will be blocked until all enqueued operations have returned.
*/
– (void)waitUntilAllOperationsAreFinished;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKMappingOperationQueue.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKMappingOperationQueue.m
//
// RKMappingOperationQueue.m
// RestKit
//
// Created by Blake Watters on 9/20/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKMappingOperationQueue.h”
@implementation RKMappingOperationQueue
– (id)init {
self = [super init];
if (self) {
_operations = [NSMutableArray new];
}
return self;
}
– (void)dealloc {
[_operations release];
[super dealloc];
}
– (void)addOperation:(NSOperation *)op {
[_operations addObject:op];
}
– (void)addOperationWithBlock:(void (^)(void))block {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block];
[_operations addObject:blockOperation];
}
– (NSArray *)operations {
return [NSArray arrayWithArray:_operations];
}
– (NSUInteger)operationCount {
return [_operations count];
}
– (void)waitUntilAllOperationsAreFinished {
for (NSOperation *operation in _operations) {
[operation start];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKMappingOperationQueue.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectAttributeMapping.h
//
// RKObjectElementMapping.h
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
// Defines the rules for mapping a particular element
@interface RKObjectAttributeMapping : NSObject
NSString *_sourceKeyPath;
NSString *_destinationKeyPath;
}
@property (nonatomic, retain) NSString *sourceKeyPath;
@property (nonatomic, retain) NSString *destinationKeyPath;
/**
Defines a mapping from one keyPath to another within an object mapping
*/
+ (RKObjectAttributeMapping *)mappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath;
/**
Returns YES if this attribute mapping targets the key of a nested dictionary.
When an object mapping is configured to target mapping of nested content via [RKObjectMapping mapKeyOfNestedDictionaryToAttribute:], a special attribute mapping is defined that targets
the key of the nested dictionary rather than a value within in. This method will return YES if
this attribute mapping is configured in such a way.
@see [RKObjectMapping mapKeyOfNestedDictionaryToAttribute:]
@return YES if this attribute mapping targets a nesting key path
*/
– (BOOL)isMappingForKeyOfNestedDictionary;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectAttributeMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectAttributeMapping.m
//
// RKObjectElementMapping.m
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectAttributeMapping.h”
extern NSString* const RKObjectMappingNestingAttributeKeyName;
@implementation RKObjectAttributeMapping
@synthesize sourceKeyPath = _sourceKeyPath;
@synthesize destinationKeyPath = _destinationKeyPath;
/**
@private
*/
– (id)initWithSourceKeyPath:(NSString *)sourceKeyPath andDestinationKeyPath:(NSString *)destinationKeyPath {
NSAssert(sourceKeyPath != nil, @”Cannot define an element mapping an element name to map from”);
NSAssert(destinationKeyPath != nil, @”Cannot define an element mapping without a property to apply the value to”);
self = [super init];
if (self) {
_sourceKeyPath = [sourceKeyPath retain];
_destinationKeyPath = [destinationKeyPath retain];
}
return self;
}
– (id)copyWithZone:(NSZone *)zone {
RKObjectAttributeMapping* copy = [[[self class] allocWithZone:zone] initWithSourceKeyPath:self.sourceKeyPath andDestinationKeyPath:self.destinationKeyPath];
return copy;
}
– (void)dealloc {
[_sourceKeyPath release];
[_destinationKeyPath release];
[super dealloc];
}
– (NSString *)description {
return [NSString stringWithFormat:@”RKObjectKeyPathMapping: %@ => %@”, self.sourceKeyPath, self.destinationKeyPath];
}
+ (RKObjectAttributeMapping *)mappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath {
RKObjectAttributeMapping *mapping = [[self alloc] initWithSourceKeyPath:sourceKeyPath andDestinationKeyPath:destinationKeyPath];
return [mapping autorelease];
}
– (BOOL)isMappingForKeyOfNestedDictionary {
return ([self.sourceKeyPath isEqualToString:RKObjectMappingNestingAttributeKeyName]);
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectAttributeMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectLoader.h
//
// RKObjectLoader.h
// RestKit
//
// Created by Blake Watters on 8/8/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “Network.h”
#import “RKObjectMapping.h”
#import “RKObjectMappingResult.h”
#import “RKObjectMappingProvider.h”
@class RKObjectMappingProvider;
@class RKObjectLoader;
// Block Types
typedef void(^RKObjectLoaderBlock)(RKObjectLoader *loader);
typedef void(^RKObjectLoaderDidFailWithErrorBlock)(NSError *error);
typedef void(^RKObjectLoaderDidLoadObjectsBlock)(NSArray *objects);
typedef void(^RKObjectLoaderDidLoadObjectBlock)(id object);
typedef void(^RKObjectLoaderDidLoadObjectsDictionaryBlock)(NSDictionary *dictionary);
/**
The delegate of an RKObjectLoader object must adopt the RKObjectLoaderDelegate protocol. Optional
methods of the protocol allow the delegate to handle asynchronous object mapping operations performed
by the object loader. Also note that the RKObjectLoaderDelegate protocol incorporates the
RKRequestDelegate protocol and the delegate may provide implementations of methods from RKRequestDelegate
as well.
@see RKRequestDelegate
*/
@protocol RKObjectLoaderDelegate
@required
/**
* Sent when an object loaded failed to load the collection due to an error
*/
– (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error;
@optional
/**
When implemented, sent to the delegate when the object laoder has completed successfully
and loaded a collection of objects. All objects mapped from the remote payload will be returned
as a single array.
*/
– (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects;
/**
When implemented, sent to the delegate when the object loader has completed succesfully.
If the load resulted in a collection of objects being mapped, only the first object
in the collection will be sent with this delegate method. This method simplifies things
when you know you are working with a single object reference.
*/
– (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObject:(id)object;
/**
When implemented, sent to the delegate when an object loader has completed successfully. The
dictionary will be expressed as pairs of keyPaths and objects mapped from the payload. This
method is useful when you have multiple root objects and want to differentiate them by keyPath.
*/
– (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjectDictionary:(NSDictionary *)dictionary;
/**
Invoked when the object loader has finished loading
*/
– (void)objectLoaderDidFinishLoading:(RKObjectLoader *)objectLoader;
/**
Informs the delegate that the object loader has serialized the source object into a serializable representation
for sending to the remote system. The serialization can be modified to allow customization of the request payload independent of mapping.
@param objectLoader The object loader performing the serialization.
@param sourceObject The object that was serialized.
@param serialization The serialization of sourceObject to be sent to the remote backend for processing.
*/
– (void)objectLoader:(RKObjectLoader *)objectLoader didSerializeSourceObject:(id)sourceObject toSerialization:(inout id
/**
Sent when an object loader encounters a response status code or MIME Type that RestKit does not know how to handle.
Response codes in the 2xx, 4xx, and 5xx range are all handled as you would expect. 2xx (successful) response codes
are considered a successful content load and object mapping will be attempted. 4xx and 5xx are interpretted as
errors and RestKit will attempt to object map an error out of the payload (provided the MIME Type is mappable)
and will invoke objectLoader:didFailWithError: after constructing an NSError. Any other status code is considered
unexpected and will cause objectLoaderDidLoadUnexpectedResponse: to be invoked provided that you have provided
an implementation in your delegate class.
RestKit will also invoke objectLoaderDidLoadUnexpectedResponse: in the event that content is loaded, but there
is not a parser registered to handle the MIME Type of the payload. This often happens when the remote backend
system RestKit is talking to generates an HTML error page on failure. If your remote system returns content
in a MIME Type other than application/json or application/xml, you must register the MIME Type and an appropriate
parser with the [RKParserRegistry sharedParser] instance.
Also note that in the event RestKit encounters an unexpected status code or MIME Type response an error will be
constructed and sent to the delegate via objectLoader:didFailsWithError: unless your delegate provides an
implementation of objectLoaderDidLoadUnexpectedResponse:. It is recommended that you provide an implementation
and attempt to handle common unexpected MIME types (particularly text/html and text/plain).
@optional
*/
– (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader *)objectLoader;
/**
Invoked just after parsing has completed, but before object mapping begins. This can be helpful
to extract data from the parsed payload that is not object mapped, but is interesting for one
reason or another. The mappableData will be made mutable via mutableCopy before the delegate
method is invoked.
Note that the mappable data is a pointer to a pointer to allow you to replace the mappable data
with a new object to be mapped. You must dereference it to access the value.
*/
– (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData;
@end
/**
* Wraps a request/response cycle and loads a remote object representation into local domain objects
*
* NOTE: When Core Data is linked into the application, the object manager will return instances of
* RKManagedObjectLoader instead of RKObjectLoader. RKManagedObjectLoader is a descendent class that
* includes Core Data specific mapping logic.
*/
@interface RKObjectLoader : RKRequest {
id _sourceObject;
id _targetObject;
dispatch_queue_t _mappingQueue;
}
/**
The object that acts as the delegate of the receiving object loader.
@see RKRequestDelegate
*/
@property (nonatomic, assign) id
/**
The block to invoke when the object loader fails due to an error.
@see [RKObjectLoaderDelegate objectLoader:didFailWithError:]
*/
@property (nonatomic, copy) RKObjectLoaderDidFailWithErrorBlock onDidFailWithError;
/**
The block to invoke when the object loader has completed object mapping and the consumer
wishes to retrieve a single object from the mapping result.
@see [RKObjectLoaderDelegate objectLoader:didLoadObject:]
@see RKObjectMappingResult
*/
@property (nonatomic, copy) RKObjectLoaderDidLoadObjectBlock onDidLoadObject;
/**
The block to invoke when the object loader has completed object mapping and the consumer
wishes to retrieve an collections of objects from the mapping result.
@see [RKObjectLoaderDelegate objectLoader:didLoadObjects:]
@see RKObjectMappingResult
*/
@property (nonatomic, copy) RKObjectLoaderDidLoadObjectsBlock onDidLoadObjects;
/**
The block to invoke when the object loader has completed object mapping and the consumer
wishes to retrieve the entire mapping result as a dictionary. Each key within the
dictionary will correspond to a mapped keyPath within the source JSON/XML and the value
will be the object mapped result.
@see [RKObjectLoaderDelegate objectLoader:didLoadObjects:]
@see RKObjectMappingResult
*/
@property (nonatomic, copy) RKObjectLoaderDidLoadObjectsDictionaryBlock onDidLoadObjectsDictionary;
/**
* The object mapping to use when processing the response. If this is nil,
* then RestKit will search the parsed response body for mappable keyPaths and
* perform mapping on all available content. For instances where your target JSON
* is not returned under a uniquely identifiable keyPath, you must specify the object
* mapping directly for RestKit to know how to map it.
*
* @default nil
* @see RKObjectMappingProvider
*/
@property (nonatomic, retain) RKObjectMapping *objectMapping;
/**
A mapping provider containing object mapping configurations for mapping remote
object representations into local domain objects.
@see RKObjectMappingProvider
*/
@property (nonatomic, retain) RKObjectMappingProvider *mappingProvider;
/**
* The underlying response object for this loader
*/
@property (nonatomic, retain, readonly) RKResponse *response;
/**
* The mapping result that was produced after the request finished loading and
* object mapping has completed. Provides access to the final products of the
* object mapper in a variety of formats.
*/
@property (nonatomic, readonly) RKObjectMappingResult *result;
///////////////////////////////////////////////////////////////////////////////////////////
// Serialization
/**
* The object mapping to use when serializing a target object for transport
* to the remote server.
*
* @see RKObjectMappingProvider
*/
@property (nonatomic, retain) RKObjectMapping *serializationMapping;
/**
* The MIME Type to serialize the targetObject into according to the mapping
* rules in the serializationMapping. Typical MIME Types for serialization are
* JSON (RKMIMETypeJSON) and URL Form Encoded (RKMIMETypeFormURLEncoded).
*
* @see RKMIMEType
*/
@property (nonatomic, retain) NSString *serializationMIMEType;
/**
The object being serialized for transport. This object will be transformed into a
serialization in the serializationMIMEType using the serializationMapping.
@see RKObjectSerializer
*/
@property (nonatomic, retain) NSObject *sourceObject;
/**
* The target object to map results back onto. If nil, a new object instance
* for the appropriate mapping will be created. If not nil, the results will
* be used to update the targetObject’s attributes and relationships.
*/
@property (nonatomic, retain) NSObject *targetObject;
/**
The Grand Central Dispatch queue to perform our parsing and object mapping
within. By default, object loaders will use the mappingQueue from the RKObjectManager
that created the loader. You can override this on a per-loader basis as necessary.
*/
@property (nonatomic, assign) dispatch_queue_t mappingQueue;
///////////////////////////////////////////////////////////////////////////////////////////
/**
Initialize and return an autoreleased object loader targeting a remote URL using a mapping provider
@param URL A RestKit RKURL targetting a particular baseURL and resourcePath
@param mappingProvider A mapping provider containing object mapping configurations for processing loaded payloads
*/
+ (id)loaderWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider;
/**
Initialize and return an autoreleased object loader targeting a remote URL using a mapping provider
@param URL A RestKit RKURL targetting a particular baseURL and resourcePath
@param mappingProvider A mapping provider containing object mapping configurations for processing loaded payloads
*/
– (id)initWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider;
/**
* Handle an error in the response preventing it from being mapped, called from -isResponseMappable
*/
– (void)handleResponseError;
@end
@class RKObjectManager;
@interface RKObjectLoader (Deprecations)
+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id
– (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectLoader.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectLoader.m
//
// RKObjectLoader.m
// RestKit
//
// Created by Blake Watters on 8/8/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectLoader.h”
#import “RKObjectMapper.h”
#import “RKObjectManager.h”
#import “RKObjectMapperError.h”
#import “RKObjectLoader_Internals.h”
#import “RKParserRegistry.h”
#import “RKRequest_Internals.h”
#import “RKObjectMappingProvider+Contexts.h”
#import “RKObjectSerializer.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitNetwork
@interface RKRequest (Private)
– (void)updateInternalCacheDate;
– (void)postRequestDidFailWithErrorNotification:(NSError *)error;
@end
@interface RKObjectLoader ()
@property (nonatomic, assign, readwrite, getter = isLoaded) BOOL loaded;
@property (nonatomic, assign, readwrite, getter = isLoading) BOOL loading;
@property (nonatomic, retain, readwrite) RKResponse *response;
@end
@implementation RKObjectLoader
@synthesize mappingProvider = _mappingProvider;
@synthesize targetObject = _targetObject;
@synthesize objectMapping = _objectMapping;
@synthesize result = _result;
@synthesize serializationMapping = _serializationMapping;
@synthesize serializationMIMEType = _serializationMIMEType;
@synthesize sourceObject = _sourceObject;
@synthesize mappingQueue = _mappingQueue;
@synthesize onDidFailWithError = _onDidFailWithError;
@synthesize onDidLoadObject = _onDidLoadObject;
@synthesize onDidLoadObjects = _onDidLoadObjects;
@synthesize onDidLoadObjectsDictionary = _onDidLoadObjectsDictionary;
@dynamic loaded;
@dynamic loading;
@dynamic response;
+ (id)loaderWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider {
return [[[self alloc] initWithURL:URL mappingProvider:mappingProvider] autorelease];
}
– (id)initWithURL:(RKURL *)URL mappingProvider:(RKObjectMappingProvider *)mappingProvider {
self = [super initWithURL:URL];
if (self) {
_mappingProvider = [mappingProvider retain];
_mappingQueue = [RKObjectManager defaultMappingQueue];
}
return self;
}
– (void)dealloc {
[_mappingProvider release];
_mappingProvider = nil;
[_sourceObject release];
_sourceObject = nil;
[_targetObject release];
_targetObject = nil;
[_objectMapping release];
_objectMapping = nil;
[_result release];
_result = nil;
[_serializationMIMEType release];
_serializationMIMEType = nil;
[_serializationMapping release];
_serializationMapping = nil;
[_onDidFailWithError release];
_onDidFailWithError = nil;
[_onDidLoadObject release];
_onDidLoadObject = nil;
[_onDidLoadObjects release];
_onDidLoadObjects = nil;
[_onDidLoadObjectsDictionary release];
_onDidLoadObjectsDictionary = nil;
[super dealloc];
}
– (void)reset {
[super reset];
[_result release];
_result = nil;
}
– (void)informDelegateOfError:(NSError *)error {
[(NSObject
if (self.onDidFailWithError) {
self.onDidFailWithError(error);
}
}
#pragma mark – Response Processing
// NOTE: This method is significant because the notifications posted are used by
// RKRequestQueue to remove requests from the queue. All requests need to be finalized.
– (void)finalizeLoad:(BOOL)successful {
self.loading = NO;
self.loaded = successful;
if ([self.delegate respondsToSelector:@selector(objectLoaderDidFinishLoading:)]) {
[(NSObject
withObject:self waitUntilDone:YES];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFinishLoadingNotification object:self];
}
// Invoked on the main thread. Inform the delegate.
– (void)informDelegateOfObjectLoadWithResultDictionary:(NSDictionary*)resultDictionary {
NSAssert([NSThread isMainThread], @”RKObjectLoaderDelegate callbacks must occur on the main thread”);
RKObjectMappingResult* result = [RKObjectMappingResult mappingResultWithDictionary:resultDictionary];
// Dictionary callback
if ([self.delegate respondsToSelector:@selector(objectLoader:didLoadObjectDictionary:)]) {
[(NSObject
}
if (self.onDidLoadObjectsDictionary) {
self.onDidLoadObjectsDictionary([result asDictionary]);
}
// Collection callback
if ([self.delegate respondsToSelector:@selector(objectLoader:didLoadObjects:)]) {
[(NSObject
}
if (self.onDidLoadObjects) {
self.onDidLoadObjects([result asCollection]);
}
// Singular object callback
if ([self.delegate respondsToSelector:@selector(objectLoader:didLoadObject:)]) {
[(NSObject
}
if (self.onDidLoadObject) {
self.onDidLoadObject([result asObject]);
}
[self finalizeLoad:YES];
}
#pragma mark – Subclass Hooks
/**
Overloaded by RKManagedObjectLoader to serialize/deserialize managed objects
at thread boundaries.
@protected
*/
– (void)processMappingResult:(RKObjectMappingResult*)result {
NSAssert(_sentSynchronously || ![NSThread isMainThread], @”Mapping result processing should occur on a background thread”);
[self performSelectorOnMainThread:@selector(informDelegateOfObjectLoadWithResultDictionary:) withObject:[result asDictionary] waitUntilDone:YES];
}
#pragma mark – Response Object Mapping
– (RKObjectMappingResult*)mapResponseWithMappingProvider:(RKObjectMappingProvider*)mappingProvider toObject:(id)targetObject inContext:(RKObjectMappingProviderContext)context error:(NSError**)error {
id
NSAssert1(parser, @”Cannot perform object load without a parser for MIME Type ‘%@'”, self.response.MIMEType);
// Check that there is actually content in the response body for mapping. It is possible to get back a 200 response
// with the appropriate MIME Type with no content (such as for a successful PUT or DELETE). Make sure we don’t generate an error
// in these cases
id bodyAsString = [self.response bodyAsString];
RKLogTrace(@”bodyAsString: %@”, bodyAsString);
if (bodyAsString == nil || [[bodyAsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
RKLogDebug(@”Mapping attempted on empty response body…”);
if (self.targetObject) {
return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionaryWithObject:self.targetObject forKey:@””]];
}
return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionary]];
}
id parsedData = [parser objectFromString:bodyAsString error:error];
if (parsedData == nil && error) {
return nil;
}
// Allow the delegate to manipulate the data
if ([self.delegate respondsToSelector:@selector(objectLoader:willMapData:)]) {
parsedData = [[parsedData mutableCopy] autorelease];
[(NSObject
}
RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider];
mapper.targetObject = targetObject;
mapper.delegate = self;
mapper.context = context;
RKObjectMappingResult* result = [mapper performMapping];
// Log any mapping errors
if (mapper.errorCount > 0) {
RKLogError(@”Encountered errors during mapping: %@”, [[mapper.errors valueForKey:@”localizedDescription”] componentsJoinedByString:@”, “]);
}
// The object mapper will return a nil result if mapping failed
if (nil == result) {
// TODO: Construct a composite error that wraps up all the other errors. Should probably make it performMapping:&error when we have this?
if (error) *error = [mapper.errors lastObject];
return nil;
}
return result;
}
– (RKObjectMappingDefinition *)configuredObjectMapping {
if (self.objectMapping) {
return self.objectMapping;
}
return [self.mappingProvider objectMappingForResourcePath:self.resourcePath];
}
– (RKObjectMappingResult*)performMapping:(NSError**)error {
NSAssert(_sentSynchronously || ![NSThread isMainThread], @”Mapping should occur on a background thread”);
RKObjectMappingProvider* mappingProvider;
RKObjectMappingDefinition *configuredObjectMapping = [self configuredObjectMapping];
if (configuredObjectMapping) {
mappingProvider = [RKObjectMappingProvider mappingProvider];
NSString *rootKeyPath = configuredObjectMapping.rootKeyPath ? configuredObjectMapping.rootKeyPath : @””;
[mappingProvider setMapping:configuredObjectMapping forKeyPath:rootKeyPath];
// Copy the error mapping from our configured mappingProvider
mappingProvider.errorMapping = self.mappingProvider.errorMapping;
} else {
RKLogDebug(@”No object mapping provider, using mapping provider from parent object manager to perform KVC mapping”);
mappingProvider = self.mappingProvider;
}
return [self mapResponseWithMappingProvider:mappingProvider toObject:self.targetObject inContext:RKObjectMappingProviderContextObjectsByKeyPath error:error];
}
– (void)performMappingInDispatchQueue {
NSAssert(self.mappingQueue, @”mappingQueue cannot be nil”);
dispatch_async(self.mappingQueue, ^{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
RKLogDebug(@”Beginning object mapping activities within GCD queue labeled: %s”, dispatch_queue_get_label(self.mappingQueue));
NSError *error = nil;
_result = [[self performMapping:&error] retain];
NSAssert(_result || error, @”Expected performMapping to return a mapping result or an error.”);
if (self.result) {
[self processMappingResult:self.result];
} else if (error) {
[self performSelectorOnMainThread:@selector(didFailLoadWithError:) withObject:error waitUntilDone:NO];
}
[pool drain];
});
}
– (BOOL)canParseMIMEType:(NSString*)MIMEType {
if ([[RKParserRegistry sharedRegistry] parserForMIMEType:self.response.MIMEType]) {
return YES;
}
RKLogWarning(@”Unable to find parser for MIME Type ‘%@'”, MIMEType);
return NO;
}
– (BOOL)isResponseMappable {
if ([self.response isServiceUnavailable]) {
[[NSNotificationCenter defaultCenter] postNotificationName:RKServiceDidBecomeUnavailableNotification object:self];
}
if ([self.response isFailure]) {
[self informDelegateOfError:self.response.failureError];
[self didFailLoadWithError:self.response.failureError];
return NO;
} else if ([self.response isNoContent]) {
// The No Content (204) response will never have a message body or a MIME Type.
id resultDictionary = nil;
if (self.targetObject) {
resultDictionary = [NSDictionary dictionaryWithObject:self.targetObject forKey:@””];
} else if (self.sourceObject) {
resultDictionary = [NSDictionary dictionaryWithObject:self.sourceObject forKey:@””];
} else {
resultDictionary = [NSDictionary dictionary];
}
[self informDelegateOfObjectLoadWithResultDictionary:resultDictionary];
return NO;
} else if (NO == [self canParseMIMEType:[self.response MIMEType]]) {
// We can’t parse the response, it’s unmappable regardless of the status code
RKLogWarning(@”Encountered unexpected response with status code: %ld (MIME Type: %@ -> URL: %@)”, (long) self.response.statusCode, self.response.MIMEType, self.URL);
NSError* error = [NSError errorWithDomain:RKErrorDomain code:RKObjectLoaderUnexpectedResponseError userInfo:nil];
if ([_delegate respondsToSelector:@selector(objectLoaderDidLoadUnexpectedResponse:)]) {
[(NSObject
} else {
[self informDelegateOfError:error];
}
// NOTE: We skip didFailLoadWithError: here so that we don’t send the delegate
// conflicting messages around unexpected response and failure with error
[self finalizeLoad:NO];
return NO;
} else if ([self.response isError]) {
// This is an error and we can map the MIME Type of the response
[self handleResponseError];
return NO;
}
return YES;
}
– (void)handleResponseError {
// Since we are mapping what we know to be an error response, we don’t want to map the result back onto our
// target object
NSError *error = nil;
RKObjectMappingResult *result = [self mapResponseWithMappingProvider:self.mappingProvider toObject:nil inContext:RKObjectMappingProviderContextErrors error:&error];
if (result) {
error = [result asError];
} else {
RKLogError(@”Encountered an error while attempting to map server side errors from payload: %@”, [error localizedDescription]);
}
[self informDelegateOfError:error];
[self finalizeLoad:NO];
}
#pragma mark – RKRequest & RKRequestDelegate methods
// Invoked just before request hits the network
– (BOOL)prepareURLRequest {
if ((self.sourceObject && self.params == nil) && (self.method == RKRequestMethodPOST || self.method == RKRequestMethodPUT)) {
NSAssert(self.serializationMapping, @”You must provide a serialization mapping for objects of type ‘%@'”, NSStringFromClass([self.sourceObject class]));
RKLogDebug(@”POST or PUT request for source object %@, serializing to MIME Type %@ for transport…”, self.sourceObject, self.serializationMIMEType);
RKObjectSerializer* serializer = [RKObjectSerializer serializerWithObject:self.sourceObject mapping:self.serializationMapping];
NSError* error = nil;
id params = [serializer serializationForMIMEType:self.serializationMIMEType error:&error];
if (error) {
RKLogError(@”Serializing failed for source object %@ to MIME Type %@: %@”, self.sourceObject, self.serializationMIMEType, [error localizedDescription]);
[self didFailLoadWithError:error];
return NO;
}
if ([self.delegate respondsToSelector:@selector(objectLoader:didSerializeSourceObject:toSerialization:)]) {
[self.delegate objectLoader:self didSerializeSourceObject:self.sourceObject toSerialization:¶ms];
}
self.params = params;
}
// TODO: This is an informal protocol ATM. Maybe its not obvious enough?
if (self.sourceObject) {
if ([self.sourceObject respondsToSelector:@selector(willSendWithObjectLoader:)]) {
[self.sourceObject performSelector:@selector(willSendWithObjectLoader:) withObject:self];
}
}
return [super prepareURLRequest];
}
– (void)didFailLoadWithError:(NSError *)error {
NSParameterAssert(error);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
if (_cachePolicy & RKRequestCachePolicyLoadOnError &&
[self.cache hasResponseForRequest:self]) {
[self didFinishLoad:[self.cache responseForRequest:self]];
} else {
if ([_delegate respondsToSelector:@selector(request:didFailLoadWithError:)]) {
[_delegate request:self didFailLoadWithError:error];
}
if (self.onDidFailLoadWithError) {
self.onDidFailLoadWithError(error);
}
// If we failed due to a transport error or before we have a response, the request itself failed
if (!self.response || [self.response isFailure]) {
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:error forKey:RKRequestDidFailWithErrorNotificationUserInfoErrorKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFailWithErrorNotification
object:self
userInfo:userInfo];
}
if (! self.isCancelled) {
[self informDelegateOfError:error];
}
[self finalizeLoad:NO];
}
[pool release];
}
// NOTE: We do NOT call super here. We are overloading the default behavior from RKRequest
– (void)didFinishLoad:(RKResponse*)response {
NSAssert([NSThread isMainThread], @”RKObjectLoaderDelegate callbacks must occur on the main thread”);
self.response = response;
if ((_cachePolicy & RKRequestCachePolicyEtag) && [response isNotModified]) {
self.response = [self.cache responseForRequest:self];
NSAssert(self.response, @”Unexpectedly loaded nil response from cache”);
[self updateInternalCacheDate];
}
if (![self.response wasLoadedFromCache] && [self.response isSuccessful] && (_cachePolicy != RKRequestCachePolicyNone)) {
[self.cache storeResponse:self.response forRequest:self];
}
if ([_delegate respondsToSelector:@selector(request:didLoadResponse:)]) {
[_delegate request:self didLoadResponse:self.response];
}
if (self.onDidLoadResponse) {
self.onDidLoadResponse(self.response);
}
// Post the notification
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:self.response
forKey:RKRequestDidLoadResponseNotificationUserInfoResponseKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidLoadResponseNotification
object:self
userInfo:userInfo];
if ([self isResponseMappable]) {
// Determine if we are synchronous here or not.
if (_sentSynchronously) {
NSError* error = nil;
_result = [[self performMapping:&error] retain];
if (self.result) {
[self processMappingResult:self.result];
} else {
[self performSelectorInBackground:@selector(didFailLoadWithError:) withObject:error];
}
} else {
[self performMappingInDispatchQueue];
}
}
}
– (void)setMappingQueue:(dispatch_queue_t)newMappingQueue {
if (_mappingQueue) {
dispatch_release(_mappingQueue);
_mappingQueue = nil;
}
if (newMappingQueue) {
dispatch_retain(newMappingQueue);
_mappingQueue = newMappingQueue;
}
}
// Proxy the delegate property back to our superclass implementation. The object loader should
// really not be a subclass of RKRequest.
– (void)setDelegate:(id
[super setDelegate:delegate];
}
– (id
return (id
}
@end
@implementation RKObjectLoader (Deprecations)
+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id
return [[[self alloc] initWithResourcePath:resourcePath objectManager:objectManager delegate:delegate] autorelease];
}
– (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id
if ((self = [self initWithURL:[objectManager.baseURL URLByAppendingResourcePath:resourcePath] mappingProvider:objectManager.mappingProvider])) {
[objectManager.client configureRequest:self];
_delegate = theDelegate;
}
return self;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectLoader.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectLoader_Internals.h
//
// RKObjectLoader_Internals.h
// RestKit
//
// Created by Blake Watters on 5/13/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@interface RKObjectLoader (Internals)
@property (nonatomic, readonly) RKClient* client;
– (void)handleTargetObject;
– (void)informDelegateOfObjectLoadWithResultDictionary:(NSDictionary*)dictionary;
– (void)performMappingOnBackgroundThread;
– (BOOL)isResponseMappable;
– (void)finalizeLoad:(BOOL)successful error:(NSError*)error;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectLoader_Internals.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectManager.h
//
// RKObjectManager.h
// RestKit
//
// Created by Jeremy Ellison on 8/14/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “Network.h”
#import “RKObjectLoader.h”
#import “RKObjectRouter.h”
#import “RKObjectMappingProvider.h”
#import “RKConfigurationDelegate.h”
#import “RKObjectPaginator.h”
@protocol RKParser;
/** Notifications */
/**
Posted when the object managed has transitioned to the offline state
*/
extern NSString* const RKObjectManagerDidBecomeOfflineNotification;
/**
Posted when the object managed has transitioned to the online state
*/
extern NSString* const RKObjectManagerDidBecomeOnlineNotification;
typedef enum {
RKObjectManagerNetworkStatusUnknown,
RKObjectManagerNetworkStatusOffline,
RKObjectManagerNetworkStatusOnline
} RKObjectManagerNetworkStatus;
@class RKManagedObjectStore;
/**
The object manager is the primary interface for interacting with RESTful resources via HTTP. It is
responsible for retrieving remote object representations via HTTP and transforming them into local
domain objects via the RKObjectMapper. It is also capable of serializing local objects and sending them
to a remote system for processing. The object manager strives to hide the developer from the details of
configuring an RKRequest, processing an RKResponse, parsing any data returned by the remote system, and
running the parsed data through the object mapper.
Shared Manager Instance
Multiple instances of RKObjectManager may be used in parallel, but the first instance initialized
is automatically configured as the sharedManager instance. The shared instance can be changed at runtime
if so desired. See sharedManager and setSharedManager for details.
Configuring the Object Manager
The object mapper must be configured before object can be loaded from or transmitted to your remote backend
system. Configuration consists of specifying the desired MIME types to be used during loads and serialization,
registering object mappings to use for mapping and serialization, registering routes, and optionally configuring
an instance of the managed object store (for Core Data).
MIME Types
MIME Types are used for two purposes within RestKit:
1. Content Negotiation. RestKit leverages the HTTP Accept header to specify the desired representation of content
when contacting a remote web service. You can specify the MIME Type to use via the acceptMIMEType method. The default
MIME Type is RKMIMETypeJSON (application/json). If the remote web service responds with content in a different MIME Type
than specified, RestKit will attempt to parse it by consulting the [parser registry][RKParserRegistry parserForMIMEType:].
Failure to find a parser for the returned content will result in an unexpected response invocation of
[RKObjectLoaderDelegate objectLoaderDidLoadUnexpectedResponse].
1. Serialization. RestKit can be used to transport local object representation back to the remote web server for processing
by serializing them into an RKRequestSerializable representation. The desired serialization format is configured by setting
the serializationMIMEType property. RestKit currently supports serialization to RKMIMETypeFormURLEncoded and RKMIMETypeJSON.
The serialization rules themselves are expressed via an instance of RKObjectMapping.
The Mapping Provider
RestKit determines how to map and serialize objects by consulting the mappingProvider. The mapping provider is responsible
for providing instances of RKObjectMapper with object mappings that should be used for transforming mappable data into object
representations. When you ask the object manager to load or send objects for you, the mappingProvider instance will be used
for the object mapping operations constructed for you. In this way, the mappingProvider is the central registry for the knowledge
about how objects in your application are mapped.
Mappings are registered by constructing instances of RKObjectMapping and registering them with the provider:
`
RKObjectManager* manager = [RKObjectManager managerWithBaseURL:myBaseURL];
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[mapping mapAttributes:@”title”, @”body”, @”publishedAt”, nil];
[manager.mappingProvider setObjectMapping:articleMapping forKeyPath:@”article”];
// Generate an inverse mapping for transforming Article -> NSMutableDictionary.
[manager.mappingProvider setSerializationMapping:[articleMapping inverseMapping] forClass:[Article class]];`
Configuring Routes
Routing is the process of transforming objects and actions (as defined by HTTP verbs) into resource paths. RestKit ships
Initializing a Core Data Object Store
Loading Remote Objects
Routing & Object Serialization
Default Error Mapping
When an instance of RKObjectManager is configured, the RKObjectMappingProvider
instance configured
*/
@interface RKObjectManager : NSObject
/// @name Configuring the Shared Manager Instance
/**
Return the shared instance of the object manager
*/
+ (RKObjectManager *)sharedManager;
/**
Set the shared instance of the object manager
*/
+ (void)setSharedManager:(RKObjectManager *)manager;
/** @name Object Mapping Dispatch Queue */
/**
Returns the global default Grand Central Dispatch queue used for object mapping
operations executed by RKObjectLoaders.
All object loaders perform their loading within a Grand Central Dispatch
queue. This provides control over the number of loaders that are performing
expensive operations such as JSON parsing, object mapping, and accessing Core
Data concurrently. The defaultMappingQueue is configured as the mappingQueue
for all RKObjectManager’s created by RestKit, but can be overridden on a per
manager and per object loader basis.
By default, the defaultMappingQueue is configured as serial GCD queue.
*/
+ (dispatch_queue_t)defaultMappingQueue;
/**
Sets a new global default Grand Central Dispatch queue for use in object mapping
operations executed by RKObjectLoaders.
*/
+ (void)setDefaultMappingQueue:(dispatch_queue_t)defaultMappingQueue;
/// @name Initializing an Object Manager
/**
Create and initialize a new object manager. If this is the first instance created
it will be set as the shared instance
*/
+ (id)managerWithBaseURLString:(NSString *)baseURLString;
+ (id)managerWithBaseURL:(NSURL *)baseURL;
/**
Initializes a newly created object manager with a specified baseURL.
@param baseURL A baseURL to initialize the underlying client instance with
@return The newly initialized RKObjectManager object
*/
– (id)initWithBaseURL:(RKURL *)baseURL;
/// @name Network Integration
/**
The underlying HTTP client for this manager
*/
@property (nonatomic, retain) RKClient *client;
/**
The base URL of the underlying RKClient instance. Object loader
and paginator instances built through the object manager are
relative to this URL.
@see RKClient
@return The baseURL of the client.
*/
@property (nonatomic, readonly) RKURL *baseURL;
/**
The request cache used to store and load responses for requests sent
through this object manager’s underlying client object
*/
@property (nonatomic, readonly) RKRequestCache *requestCache;
/**
The request queue used to dispatch asynchronous requests sent
through this object manager’s underlying client object
*/
@property (nonatomic, readonly) RKRequestQueue *requestQueue;
/**
Returns the current network status for this object manager as determined
by connectivity to the remote backend system
*/
@property (nonatomic, readonly) RKObjectManagerNetworkStatus networkStatus;
/**
Returns YES when we are in online mode
*/
@property (nonatomic, readonly) BOOL isOnline;
/**
Returns YES when we are in offline mode
*/
@property (nonatomic, readonly) BOOL isOffline;
/// @name Configuring Object Mapping
/**
The Mapping Provider responsible for returning mappings for various keyPaths.
*/
@property (nonatomic, retain) RKObjectMappingProvider *mappingProvider;
/**
Router object responsible for generating resource paths for
HTTP requests
*/
@property (nonatomic, retain) RKObjectRouter *router;
/**
A Core Data backed object store for persisting objects that have been fetched from the Web
*/
@property (nonatomic, retain) RKManagedObjectStore *objectStore;
/**
The Grand Dispatch Queue to use when performing expensive object mapping operations
within RKObjectLoader instances created through this object manager
*/
@property (nonatomic, assign) dispatch_queue_t mappingQueue;
/**
The Default MIME Type to be used in object serialization.
*/
@property (nonatomic, retain) NSString *serializationMIMEType;
/**
The value for the HTTP Accept header to specify the preferred format for retrieved data
*/
@property (nonatomic, assign) NSString *acceptMIMEType;
////////////////////////////////////////////////////////
/// @name Building Object Loaders
/**
Returns the class of object loader instances built through the manager. When Core Data has
been configured, instances of RKManagedObjectLoader will be emitted by the manager. Otherwise
RKObjectLoader is used.
@return RKObjectLoader OR RKManagedObjectLoader
*/
– (Class)objectLoaderClass;
/**
Creates and returns an RKObjectLoader or RKManagedObjectLoader instance targeting the specified resourcePath.
The object loader instantiated will be initialized with an RKURL built by appending the resourcePath to the baseURL of the client. The loader will then
be configured with object mapping configuration from the manager and request configuration from the client.
@param resourcePath A resource to use when building the URL to initialize the object loader instance.
@return The newly created object loader instance.
@see RKURL
@see RKClient
*/
– (id)loaderWithResourcePath:(NSString *)resourcePath;
/**
Creates and returns an RKObjectLoader or RKManagedObjectLoader instance targeting the specified URL.
The object loader instantiated will be initialized with URL and will then
be configured with object mapping configuration from the manager and request configuration from the client.
@param URL The URL with which to initialize the object loader.
@return The newly created object loader instance.
@see RKURL
@see RKClient
*/
– (id)loaderWithURL:(NSURL *)URL;
/**
Creates and returns an RKObjectLoader or RKManagedObjectLoader instance for an object instance.
The object loader instantiated will be initialized with a URL built by evaluating the object with the
router to construct a resource path and then appending that resource path to the baseURL of the client.
The loader will then be configured with object mapping configuration from the manager and request
configuration from the client. The specified object will be the target of the object loader and will
have any returned content mapped back onto the instance.
@param object The object with which to initialize the object loader.
@return The newly created object loader instance.
@see RKObjectLoader
@see RKObjectRouter
*/
– (id)loaderForObject:(id
/**
Creates and returns an RKObjectPaginator instance targeting the specified resource path pattern.
The paginator instantiated will be initialized with an RKURL built by appending the resourcePathPattern to the
baseURL of the client.
@return The newly created paginator instance.
@see RKObjectMappingProvider
@see RKObjectPaginator
*/
– (RKObjectPaginator *)paginatorWithResourcePathPattern:(NSString *)resourcePathPattern;
////////////////////////////////////////////////////////
/// @name Registered Object Loaders
/**
These methods are suitable for loading remote payloads that encode type information into the payload. This enables
the mapping of complex payloads spanning multiple types (i.e. a search operation returning Articles & Comments in
one payload). Ruby on Rails JSON serialization is an example of such a conformant system.
*/
/**
Create and send an asynchronous GET request to load the objects at the resource path and call back the delegate
with the loaded objects. Remote objects will be mapped to local objects by consulting the keyPath registrations
set on the mapping provider.
*/
– (void)loadObjectsAtResourcePath:(NSString *)resourcePath delegate:(id
////////////////////////////////////////////////////////
/// @name Mappable Object Loaders
/**
Fetch the data for a mappable object by performing an HTTP GET.
*/
– (void)getObject:(id
/**
Create a remote mappable model by POSTing the attributes to the remote resource and loading the resulting objects from the payload
*/
– (void)postObject:(id
/**
Update a remote mappable model by PUTing the attributes to the remote resource and loading the resulting objects from the payload
*/
– (void)putObject:(id
/**
Delete the remote instance of a mappable model by performing an HTTP DELETE on the remote resource
*/
– (void)deleteObject:(id
////////////////////////////////////////////////////////
/// @name Block Configured Object Loaders
#if NS_BLOCKS_AVAILABLE
/**
Load the objects at the specified resource path and perform object mapping on the response payload. Prior to sending the object loader, the
block will be invoked to allow you to configure the object loader as you see fit. This can be used to change the response type, set custom
parameters, choose an object mapping, etc.
For example:
– (void)loadObjectUsingBlockExample {
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/monkeys.json” usingBlock:^(RKObjectLoader* loader) {
loader.objectMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Monkey class]];
}];
}
*/
– (void)loadObjectsAtResourcePath:(NSString *)resourcePath usingBlock:(RKObjectLoaderBlock)block;
/*
Configure and send an object loader after yielding it to a block for configuration. This allows for very succinct on-the-fly
configuration of the request without obtaining an object reference via objectLoaderForObject: and then sending it yourself.
For example:
– (BOOL)changePassword:(NSString*)newPassword error:(NSError**)error {
if ([self validatePassword:newPassword error:error]) {
self.password = newPassword;
[[RKObjectManager sharedManager] sendObject:self toResourcePath:@”/some/path” usingBlock:^(RKObjectLoader* loader) {
loader.delegate = self;
loader.method = RKRequestMethodPOST;
loader.serializationMIMEType = RKMIMETypeJSON; // We want to send this request as JSON
loader.targetObject = nil; // Map the results back onto a new object instead of self
// Set up a custom serialization mapping to handle this request
loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping* mapping) {
[mapping mapAttributes:@”password”, nil];
}];
}];
}
}
*/
– (void)sendObject:(id
/**
GET a remote object instance and yield the object loader to the block before sending
@see sendObject:method:delegate:block
*/
– (void)getObject:(id
/**
POST a remote object instance and yield the object loader to the block before sending
@see sendObject:method:delegate:block
*/
– (void)postObject:(id
/**
PUT a remote object instance and yield the object loader to the block before sending
@see sendObject:method:delegate:block
*/
– (void)putObject:(id
/**
DELETE a remote object instance and yield the object loader to the block before sending
@see sendObject:method:delegate:block
*/
– (void)deleteObject:(id
#endif
//////
// Deprecations
+ (RKObjectManager *)objectManagerWithBaseURLString:(NSString *)baseURLString;
+ (RKObjectManager *)objectManagerWithBaseURL:(NSURL *)baseURL;
– (void)loadObjectsAtResourcePath:(NSString*)resourcePath objectMapping:(RKObjectMapping*)objectMapping delegate:(id
– (RKObjectLoader *)objectLoaderWithResourcePath:(NSString*)resourcePath delegate:(id
– (RKObjectLoader *)objectLoaderForObject:(id
/*
NOTE:
The mapResponseWith: family of methods have been deprecated by the support for object mapping selection
using resourcePath’s
*/
/*- (RKObjectLoader*)objectLoaderForObject:(id
/*- (RKObjectLoader *)objectLoaderForObject:(id
– (void)getObject:(id
– (void)postObject:(id
– (void)putObject:(id
– (void)deleteObject:(id
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectManager.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectManager.m
//
// RKObjectManager.m
// RestKit
//
// Created by Jeremy Ellison on 8/14/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectManager.h”
#import “RKObjectSerializer.h”
#import “RKManagedObjectStore.h”
#import “RKManagedObjectLoader.h”
#import “Support.h”
#import “RKErrorMessage.h”
NSString* const RKObjectManagerDidBecomeOfflineNotification = @”RKDidEnterOfflineModeNotification”;
NSString* const RKObjectManagerDidBecomeOnlineNotification = @”RKDidEnterOnlineModeNotification”;
//////////////////////////////////
// Shared Instances
static RKObjectManager *sharedManager = nil;
static dispatch_queue_t defaultMappingQueue = nil;
///////////////////////////////////
@interface RKObjectManager ()
@property (nonatomic, assign, readwrite) RKObjectManagerNetworkStatus networkStatus;
@end
@implementation RKObjectManager
@synthesize client = _client;
@synthesize objectStore = _objectStore;
@synthesize router = _router;
@synthesize mappingProvider = _mappingProvider;
@synthesize serializationMIMEType = _serializationMIMEType;
@synthesize networkStatus = _networkStatus;
@synthesize mappingQueue = _mappingQueue;
+ (dispatch_queue_t)defaultMappingQueue {
if (! defaultMappingQueue) {
defaultMappingQueue = dispatch_queue_create(“org.restkit.ObjectMapping”, DISPATCH_QUEUE_SERIAL);
}
return defaultMappingQueue;
}
+ (void)setDefaultMappingQueue:(dispatch_queue_t)newDefaultMappingQueue {
if (defaultMappingQueue) {
dispatch_release(defaultMappingQueue);
defaultMappingQueue = nil;
}
if (newDefaultMappingQueue) {
dispatch_retain(newDefaultMappingQueue);
defaultMappingQueue = newDefaultMappingQueue;
}
}
– (id)init {
self = [super init];
if (self) {
_mappingProvider = [RKObjectMappingProvider new];
_router = [RKObjectRouter new];
_networkStatus = RKObjectManagerNetworkStatusUnknown;
self.serializationMIMEType = RKMIMETypeFormURLEncoded;
self.mappingQueue = [RKObjectManager defaultMappingQueue];
// Setup default error message mappings
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
errorMapping.rootKeyPath = @”errors”;
[errorMapping mapKeyPath:@”” toAttribute:@”errorMessage”];
_mappingProvider.errorMapping = errorMapping;
[self addObserver:self
forKeyPath:@”client.reachabilityObserver”
options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
context:nil];
// Set shared manager if nil
if (nil == sharedManager) {
[RKObjectManager setSharedManager:self];
}
}
return self;
}
– (id)initWithBaseURL:(RKURL *)baseURL {
self = [self init];
if (self) {
self.client = [RKClient clientWithBaseURL:baseURL];
self.acceptMIMEType = RKMIMETypeJSON;
}
return self;
}
+ (RKObjectManager *)sharedManager {
return sharedManager;
}
+ (void)setSharedManager:(RKObjectManager *)manager {
[manager retain];
[sharedManager release];
sharedManager = manager;
}
+ (RKObjectManager *)managerWithBaseURLString:(NSString *)baseURLString {
return [self managerWithBaseURL:[RKURL URLWithString:baseURLString]];
}
+ (RKObjectManager *)managerWithBaseURL:(NSURL *)baseURL {
RKObjectManager *manager = [[[self alloc] initWithBaseURL:baseURL] autorelease];
return manager;
}
– (void)dealloc {
[self removeObserver:self forKeyPath:@”client.reachabilityObserver”];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_router release];
_router = nil;
self.client = nil;
[_objectStore release];
_objectStore = nil;
[_serializationMIMEType release];
_serializationMIMEType = nil;
[_mappingProvider release];
_mappingProvider = nil;
[super dealloc];
}
– (BOOL)isOnline {
return (_networkStatus == RKObjectManagerNetworkStatusOnline);
}
– (BOOL)isOffline {
return (_networkStatus == RKObjectManagerNetworkStatusOffline);
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@”client.reachabilityObserver”]) {
[self reachabilityObserverDidChange:change];
}
}
– (void)reachabilityObserverDidChange:(NSDictionary *)change {
RKReachabilityObserver *oldReachabilityObserver = [change objectForKey:NSKeyValueChangeOldKey];
RKReachabilityObserver *newReachabilityObserver = [change objectForKey:NSKeyValueChangeNewKey];
if (! [oldReachabilityObserver isEqual:[NSNull null]]) {
RKLogDebug(@”Reachability observer changed for RKClient %@ of RKObjectManager %@, stopping observing reachability changes”, self.client, self);
[[NSNotificationCenter defaultCenter] removeObserver:self name:RKReachabilityDidChangeNotification object:oldReachabilityObserver];
}
if (! [newReachabilityObserver isEqual:[NSNull null]]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:RKReachabilityDidChangeNotification
object:newReachabilityObserver];
RKLogDebug(@”Reachability observer changed for client %@ of object manager %@, starting observing reachability changes”, self.client, self);
}
// Initialize current Network Status
if ([self.client.reachabilityObserver isReachabilityDetermined]) {
BOOL isNetworkReachable = [self.client.reachabilityObserver isNetworkReachable];
self.networkStatus = isNetworkReachable ? RKObjectManagerNetworkStatusOnline : RKObjectManagerNetworkStatusOffline;
} else {
self.networkStatus = RKObjectManagerNetworkStatusUnknown;
}
}
– (void)reachabilityChanged:(NSNotification *)notification {
BOOL isHostReachable = [self.client.reachabilityObserver isNetworkReachable];
_networkStatus = isHostReachable ? RKObjectManagerNetworkStatusOnline : RKObjectManagerNetworkStatusOffline;
if (isHostReachable) {
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOnlineNotification object:self];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:self];
}
}
– (void)setAcceptMIMEType:(NSString *)MIMEType {
[_client setValue:MIMEType forHTTPHeaderField:@”Accept”];
}
– (NSString *)acceptMIMEType {
return [self.client.HTTPHeaders valueForKey:@”Accept”];
}
/////////////////////////////////////////////////////////////
#pragma mark – Object Collection Loaders
– (Class)objectLoaderClass {
Class managedObjectLoaderClass = NSClassFromString(@”RKManagedObjectLoader”);
if (self.objectStore && managedObjectLoaderClass) {
return managedObjectLoaderClass;
}
return [RKObjectLoader class];
}
– (id)loaderWithResourcePath:(NSString *)resourcePath {
RKURL *URL = [self.baseURL URLByAppendingResourcePath:resourcePath];
return [self loaderWithURL:URL];
}
– (id)loaderWithURL:(RKURL *)URL {
RKObjectLoader *loader = [[self objectLoaderClass] loaderWithURL:URL mappingProvider:self.mappingProvider];
loader.configurationDelegate = self;
if ([loader isKindOfClass:[RKManagedObjectLoader class]]) {
[(RKManagedObjectLoader *)loader setObjectStore:self.objectStore];
}
[self configureObjectLoader:loader];
return loader;
}
– (NSURL *)baseURL {
return self.client.baseURL;
}
– (RKObjectPaginator *)paginatorWithResourcePathPattern:(NSString *)resourcePathPattern {
RKURL *patternURL = [[self baseURL] URLByAppendingResourcePath:resourcePathPattern];
RKObjectPaginator *paginator = [RKObjectPaginator paginatorWithPatternURL:patternURL
mappingProvider:self.mappingProvider];
paginator.configurationDelegate = self;
return paginator;
}
– (id)loaderForObject:(id
NSString* resourcePath = (method == RKRequestMethodInvalid) ? nil : [self.router resourcePathForObject:object method:method];
RKObjectLoader *loader = [self loaderWithResourcePath:resourcePath];
loader.method = method;
loader.sourceObject = object;
loader.serializationMIMEType = self.serializationMIMEType;
loader.serializationMapping = [self.mappingProvider serializationMappingForClass:[object class]];
RKObjectMappingDefinition *objectMapping = resourcePath ? [self.mappingProvider objectMappingForResourcePath:resourcePath] : nil;
if (objectMapping == nil || ([objectMapping isKindOfClass:[RKObjectMapping class]] && [object isMemberOfClass:[(RKObjectMapping *)objectMapping objectClass]])) {
loader.targetObject = object;
} else {
loader.targetObject = nil;
}
return loader;
}
– (void)loadObjectsAtResourcePath:(NSString *)resourcePath delegate:(id
RKObjectLoader *loader = [self loaderWithResourcePath:resourcePath];
loader.delegate = delegate;
loader.method = RKRequestMethodGET;
[loader send];
}
/////////////////////////////////////////////////////////////
#pragma mark – Object Instance Loaders
– (void)getObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:RKRequestMethodGET];
loader.delegate = delegate;
[loader send];
}
– (void)postObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:RKRequestMethodPOST];
loader.delegate = delegate;
[loader send];
}
– (void)putObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:RKRequestMethodPUT];
loader.delegate = delegate;
[loader send];
}
– (void)deleteObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:RKRequestMethodDELETE];
loader.delegate = delegate;
[loader send];
}
#if NS_BLOCKS_AVAILABLE
#pragma mark – Block Configured Object Loaders
– (void)loadObjectsAtResourcePath:(NSString*)resourcePath usingBlock:(void(^)(RKObjectLoader *))block {
RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath];
loader.method = RKRequestMethodGET;
// Yield to the block for setup
block(loader);
[loader send];
}
– (void)sendObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:RKRequestMethodInvalid];
loader.URL = [self.baseURL URLByAppendingResourcePath:resourcePath];
// Yield to the block for setup
block(loader);
[loader send];
}
– (void)sendObject:(id
NSString *resourcePath = [self.router resourcePathForObject:object method:method];
[self sendObject:object toResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader) {
loader.method = method;
block(loader);
}];
}
– (void)getObject:(id
[self sendObject:object method:RKRequestMethodGET usingBlock:block];
}
– (void)postObject:(id
[self sendObject:object method:RKRequestMethodPOST usingBlock:block];
}
– (void)putObject:(id
[self sendObject:object method:RKRequestMethodPUT usingBlock:block];
}
– (void)deleteObject:(id
[self sendObject:object method:RKRequestMethodDELETE usingBlock:block];
}
#endif // NS_BLOCKS_AVAILABLE
#pragma mark – Object Instance Loaders for Non-nested JSON
– (void)getObject:(id
[self sendObject:object method:RKRequestMethodGET usingBlock:^(RKObjectLoader *loader) {
loader.delegate = delegate;
loader.objectMapping = objectMapping;
}];
}
– (void)postObject:(id
[self sendObject:object method:RKRequestMethodPOST usingBlock:^(RKObjectLoader *loader) {
loader.delegate = delegate;
loader.objectMapping = objectMapping;
}];
}
– (void)putObject:(id
[self sendObject:object method:RKRequestMethodPUT usingBlock:^(RKObjectLoader *loader) {
loader.delegate = delegate;
loader.objectMapping = objectMapping;
}];
}
– (void)deleteObject:(id
[self sendObject:object method:RKRequestMethodDELETE usingBlock:^(RKObjectLoader *loader) {
loader.delegate = delegate;
loader.objectMapping = objectMapping;
}];
}
– (RKRequestCache *)requestCache {
return self.client.requestCache;
}
– (RKRequestQueue *)requestQueue {
return self.client.requestQueue;
}
– (void)setMappingQueue:(dispatch_queue_t)newMappingQueue {
if (_mappingQueue) {
dispatch_release(_mappingQueue);
_mappingQueue = nil;
}
if (newMappingQueue) {
dispatch_retain(newMappingQueue);
_mappingQueue = newMappingQueue;
}
}
#pragma mark – RKConfigrationDelegate
– (void)configureRequest:(RKRequest *)request {
[self.client configureRequest:request];
}
– (void)configureObjectLoader:(RKObjectLoader *)objectLoader {
objectLoader.serializationMIMEType = self.serializationMIMEType;
[self configureRequest:objectLoader];
}
#pragma mark – Deprecations
+ (RKObjectManager *)objectManagerWithBaseURLString:(NSString *)baseURLString {
return [self managerWithBaseURLString:baseURLString];
}
+ (RKObjectManager *)objectManagerWithBaseURL:(NSURL *)baseURL {
return [self managerWithBaseURL:baseURL];
}
– (RKObjectLoader *)objectLoaderWithResourcePath:(NSString *)resourcePath delegate:(id
RKObjectLoader* loader = [self loaderWithResourcePath:resourcePath];
loader.delegate = delegate;
return loader;
}
– (RKObjectLoader*)objectLoaderForObject:(id
RKObjectLoader *loader = [self loaderForObject:object method:method];
loader.delegate = delegate;
return loader;
}
– (void)loadObjectsAtResourcePath:(NSString *)resourcePath objectMapping:(RKObjectMapping *)objectMapping delegate:(id
RKObjectLoader *loader = [self loaderWithResourcePath:resourcePath];
loader.delegate = delegate;
loader.method = RKRequestMethodGET;
loader.objectMapping = objectMapping;
[loader send];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectManager.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapper.h
//
// RKObjectMapper.h
// RestKit
//
// Created by Blake Watters on 5/6/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMapping.h”
#import “RKObjectMappingOperation.h”
#import “RKObjectMappingResult.h”
#import “RKObjectMappingProvider.h”
#import “RKMappingOperationQueue.h”
#import “Support.h”
@class RKObjectMapper;
@protocol RKObjectMapperDelegate
@optional
– (void)objectMapperWillBeginMapping:(RKObjectMapper*)objectMapper;
– (void)objectMapperDidFinishMapping:(RKObjectMapper*)objectMapper;
– (void)objectMapper:(RKObjectMapper*)objectMapper didAddError:(NSError*)error;
– (void)objectMapper:(RKObjectMapper*)objectMapper didFindMappableObject:(id)object atKeyPath:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)mapping;
– (void)objectMapper:(RKObjectMapper*)objectMapper didNotFindMappableObjectAtKeyPath:(NSString*)keyPath;
– (void)objectMapper:(RKObjectMapper*)objectMapper willMapFromObject:(id)sourceObject toObject:(id)destinationObject atKeyPath:(NSString*)keyPath usingMapping:(RKObjectMappingDefinition *)objectMapping;
– (void)objectMapper:(RKObjectMapper*)objectMapper didMapFromObject:(id)sourceObject toObject:(id)destinationObject atKeyPath:(NSString*)keyPath usingMapping:(RKObjectMappingDefinition *)objectMapping;
– (void)objectMapper:(RKObjectMapper*)objectMapper didFailMappingFromObject:(id)sourceObject toObject:(id)destinationObject withError:(NSError*)error atKeyPath:(NSString*)keyPath usingMapping:(RKObjectMappingDefinition *)objectMapping;
@end
/**
*/
@interface RKObjectMapper : NSObject {
@protected
RKMappingOperationQueue *operationQueue;
NSMutableArray* errors;
}
@property (nonatomic, readonly) id sourceObject;
@property (nonatomic, assign) id targetObject;
@property (nonatomic, readonly) RKObjectMappingProvider* mappingProvider;
@property (nonatomic, assign) RKObjectMappingProviderContext context;
@property (nonatomic, assign) id
@property (nonatomic, readonly) NSArray* errors;
+ (id)mapperWithObject:(id)object mappingProvider:(RKObjectMappingProvider*)mappingProvider;
– (id)initWithObject:(id)object mappingProvider:(RKObjectMappingProvider*)mappingProvider;
// Primary entry point for the mapper. Examines the type of object and processes it appropriately…
– (RKObjectMappingResult*)performMapping;
– (NSUInteger)errorCount;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapper.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapper.m
//
// RKObjectMapper.m
// RestKit
//
// Created by Blake Watters on 5/6/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMapper.h”
#import “RKObjectMapperError.h”
#import “RKObjectMapper_Private.h”
#import “RKObjectMappingProvider+Contexts.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
@implementation RKObjectMapper
@synthesize sourceObject;
@synthesize targetObject;
@synthesize delegate;
@synthesize mappingProvider;
@synthesize errors;
@synthesize context;
+ (id)mapperWithObject:(id)object mappingProvider:(RKObjectMappingProvider *)theMappingProvider {
return [[[self alloc] initWithObject:object mappingProvider:theMappingProvider] autorelease];
}
– (id)initWithObject:(id)object mappingProvider:(RKObjectMappingProvider *)theMappingProvider {
self = [super init];
if (self) {
sourceObject = [object retain];
mappingProvider = theMappingProvider;
errors = [NSMutableArray new];
operationQueue = [RKMappingOperationQueue new];
context = RKObjectMappingProviderContextObjectsByKeyPath;
}
return self;
}
– (void)dealloc {
[sourceObject release];
[errors release];
[operationQueue release];
[super dealloc];
}
#pragma mark – Errors
– (NSArray *)errors {
return [NSArray arrayWithArray:errors];
}
– (NSUInteger)errorCount {
return [self.errors count];
}
– (void)addError:(NSError *)error {
NSAssert(error, @”Cannot add a nil error”);
[errors addObject:error];
if ([self.delegate respondsToSelector:@selector(objectMapper:didAddError:)]) {
[self.delegate objectMapper:self didAddError:error];
}
RKLogWarning(@”Adding mapping error: %@”, [error localizedDescription]);
}
– (void)addErrorWithCode:(RKObjectMapperErrorCode)errorCode message:(NSString *)errorMessage keyPath:(NSString *)keyPath userInfo:(NSDictionary *)otherInfo {
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
errorMessage, NSLocalizedDescriptionKey,
@”RKObjectMapperKeyPath”, keyPath ? keyPath : (NSString *) [NSNull null],
nil];
[userInfo addEntriesFromDictionary:otherInfo];
NSError* error = [NSError errorWithDomain:RKErrorDomain code:errorCode userInfo:userInfo];
[self addError:error];
}
– (void)addErrorForUnmappableKeyPath:(NSString *)keyPath {
NSString *errorMessage = [NSString stringWithFormat:@”Could not find an object mapping for keyPath: ‘%@'”, keyPath];
[self addErrorWithCode:RKObjectMapperErrorObjectMappingNotFound message:errorMessage keyPath:keyPath userInfo:nil];
}
– (BOOL)isNullCollection:(id)object {
// The purpose of this method is to guard against the case where we perform valueForKeyPath: on an array
// and it returns NSNull for each element in the array.
// We consider an empty array/dictionary mappable, but a collection that contains only NSNull
// values is unmappable
if ([object respondsToSelector:@selector(objectForKey:)]) {
return NO;
}
if ([object respondsToSelector:@selector(countForObject:)] && [object count] > 0) {
if ([object countForObject:[NSNull null]] == [object count]) {
RKLogDebug(@”Found a collection containing only NSNull values, considering the collection unmappable…”);
return YES;
}
}
return NO;
}
#pragma mark – Mapping Primitives
– (id)mapObject:(id)mappableObject atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping {
NSAssert([mappableObject respondsToSelector:@selector(setValue:forKeyPath:)], @”Expected self.object to be KVC compliant”);
id destinationObject = nil;
if (self.targetObject) {
destinationObject = self.targetObject;
RKObjectMapping *objectMapping = nil;
if ([mapping isKindOfClass:[RKDynamicObjectMapping class]]) {
objectMapping = [(RKDynamicObjectMapping *)mapping objectMappingForDictionary:mappableObject];
} else if ([mapping isKindOfClass:[RKObjectMapping class]]) {
objectMapping = (RKObjectMapping *)mapping;
} else {
NSAssert(objectMapping, @”Encountered unknown mapping type ‘%@'”, NSStringFromClass([mapping class]));
}
if (NO == [[self.targetObject class] isSubclassOfClass:objectMapping.objectClass]) {
NSString *errorMessage = [NSString stringWithFormat:
@”Expected an object mapping for class of type ‘%@’, provider returned one for ‘%@'”,
NSStringFromClass([self.targetObject class]), NSStringFromClass(objectMapping.objectClass)];
[self addErrorWithCode:RKObjectMapperErrorObjectMappingTypeMismatch message:errorMessage keyPath:keyPath userInfo:nil];
return nil;
}
} else {
destinationObject = [self objectWithMapping:mapping andData:mappableObject];
}
if (mapping && destinationObject) {
BOOL success = [self mapFromObject:mappableObject toObject:destinationObject atKeyPath:keyPath usingMapping:mapping];
if (success) {
return destinationObject;
}
} else {
// Attempted to map an object but couldn’t find a mapping for the keyPath
[self addErrorForUnmappableKeyPath:keyPath];
return nil;
}
return nil;
}
– (NSArray *)mapCollection:(NSArray *)mappableObjects atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping {
NSAssert(mappableObjects != nil, @”Cannot map without an collection of mappable objects”);
NSAssert(mapping != nil, @”Cannot map without a mapping to consult”);
NSArray *objectsToMap = mappableObjects;
if (mapping.forceCollectionMapping) {
// If we have forced mapping of a dictionary, map each subdictionary
if ([mappableObjects isKindOfClass:[NSDictionary class]]) {
RKLogDebug(@”Collection mapping forced for NSDictionary, mapping each key/value independently…”);
objectsToMap = [NSMutableArray arrayWithCapacity:[mappableObjects count]];
for (id key in mappableObjects) {
NSDictionary *dictionaryToMap = [NSDictionary dictionaryWithObject:[mappableObjects valueForKey:key] forKey:key];
[(NSMutableArray *)objectsToMap addObject:dictionaryToMap];
}
} else {
RKLogWarning(@”Collection mapping forced but mappable objects is of type ‘%@’ rather than NSDictionary”, NSStringFromClass([mappableObjects class]));
}
}
// Ensure we are mapping onto a mutable collection if there is a target
NSMutableArray *mappedObjects = self.targetObject ? self.targetObject : [NSMutableArray arrayWithCapacity:[mappableObjects count]];
if (NO == [mappedObjects respondsToSelector:@selector(addObject:)]) {
NSString *errorMessage = [NSString stringWithFormat:
@”Cannot map a collection of objects onto a non-mutable collection. Unexpected destination object type ‘%@'”,
NSStringFromClass([mappedObjects class])];
[self addErrorWithCode:RKObjectMapperErrorObjectMappingTypeMismatch message:errorMessage keyPath:keyPath userInfo:nil];
return nil;
}
for (id mappableObject in objectsToMap) {
id destinationObject = [self objectWithMapping:mapping andData:mappableObject];
if (! destinationObject) {
continue;
}
BOOL success = [self mapFromObject:mappableObject toObject:destinationObject atKeyPath:keyPath usingMapping:mapping];
if (success) {
[mappedObjects addObject:destinationObject];
}
}
return mappedObjects;
}
// The workhorse of this entire process. Emits object loading operations
– (BOOL)mapFromObject:(id)mappableObject toObject:(id)destinationObject atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping {
NSAssert(destinationObject != nil, @”Cannot map without a target object to assign the results to”);
NSAssert(mappableObject != nil, @”Cannot map without a collection of attributes”);
NSAssert(mapping != nil, @”Cannot map without an mapping”);
RKLogDebug(@”Asked to map source object %@ with mapping %@”, mappableObject, mapping);
if ([self.delegate respondsToSelector:@selector(objectMapper:willMapFromObject:toObject:atKeyPath:usingMapping:)]) {
[self.delegate objectMapper:self willMapFromObject:mappableObject toObject:destinationObject atKeyPath:keyPath usingMapping:mapping];
}
NSError *error = nil;
RKObjectMappingOperation *operation = [RKObjectMappingOperation mappingOperationFromObject:mappableObject
toObject:destinationObject
withMapping:mapping];
operation.queue = operationQueue;
BOOL success = [operation performMapping:&error];
if (success) {
if ([self.delegate respondsToSelector:@selector(objectMapper:didMapFromObject:toObject:atKeyPath:usingMapping:)]) {
[self.delegate objectMapper:self didMapFromObject:mappableObject toObject:destinationObject atKeyPath:keyPath usingMapping:mapping];
}
} else if (error) {
if ([self.delegate respondsToSelector:@selector(objectMapper:didFailMappingFromObject:toObject:withError:atKeyPath:usingMapping:)]) {
[self.delegate objectMapper:self didFailMappingFromObject:mappableObject toObject:destinationObject withError:error atKeyPath:keyPath usingMapping:mapping];
}
[self addError:error];
}
return success;
}
– (id)objectWithMapping:(RKObjectMappingDefinition *)mapping andData:(id)mappableData {
NSAssert([mapping isKindOfClass:[RKObjectMappingDefinition class]], @”Expected an RKObjectMappingDefinition object”);
RKObjectMapping *objectMapping = nil;
if ([mapping isKindOfClass:[RKDynamicObjectMapping class]]) {
objectMapping = [(RKDynamicObjectMapping *)mapping objectMappingForDictionary:mappableData];
if (! objectMapping) {
RKLogDebug(@”Mapping %@ declined mapping for data %@: returned nil objectMapping”, mapping, mappableData);
}
} else if ([mapping isKindOfClass:[RKObjectMapping class]]) {
objectMapping = (RKObjectMapping *)mapping;
} else {
NSAssert(objectMapping, @”Encountered unknown mapping type ‘%@'”, NSStringFromClass([mapping class]));
}
if (objectMapping) {
return [objectMapping mappableObjectForData:mappableData];
}
return nil;
}
– (id)performMappingForObject:(id)mappableValue atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping {
id mappingResult;
if (mapping.forceCollectionMapping || [mappableValue isKindOfClass:[NSArray class]] || [mappableValue isKindOfClass:[NSSet class]]) {
RKLogDebug(@”Found mappable collection at keyPath ‘%@’: %@”, keyPath, mappableValue);
mappingResult = [self mapCollection:mappableValue atKeyPath:keyPath usingMapping:mapping];
} else {
RKLogDebug(@”Found mappable data at keyPath ‘%@’: %@”, keyPath, mappableValue);
mappingResult = [self mapObject:mappableValue atKeyPath:keyPath usingMapping:mapping];
}
return mappingResult;
}
– (NSMutableDictionary *)performKeyPathMappingUsingMappingDictionary:(NSDictionary *)mappingsByKeyPath {
BOOL foundMappable = NO;
NSMutableDictionary *results = [NSMutableDictionary dictionary];
for (NSString *keyPath in mappingsByKeyPath) {
id mappingResult = nil;
id mappableValue = nil;
RKLogTrace(@”Examining keyPath ‘%@’ for mappable content…”, keyPath);
if ([keyPath isEqualToString:@””]) {
mappableValue = self.sourceObject;
} else {
mappableValue = [self.sourceObject valueForKeyPath:keyPath];
}
// Not found…
if (mappableValue == nil || mappableValue == [NSNull null] || [self isNullCollection:mappableValue]) {
RKLogDebug(@”Found unmappable value at keyPath: %@”, keyPath);
if ([self.delegate respondsToSelector:@selector(objectMapper:didNotFindMappableObjectAtKeyPath:)]) {
[self.delegate objectMapper:self didNotFindMappableObjectAtKeyPath:keyPath];
}
continue;
}
// Found something to map
foundMappable = YES;
RKObjectMappingDefinition * mapping = [mappingsByKeyPath objectForKey:keyPath];
if ([self.delegate respondsToSelector:@selector(objectMapper:didFindMappableObject:atKeyPath:withMapping:)]) {
[self.delegate objectMapper:self didFindMappableObject:mappableValue atKeyPath:keyPath withMapping:mapping];
}
mappingResult = [self performMappingForObject:mappableValue atKeyPath:keyPath usingMapping:mapping];
if (mappingResult) {
[results setObject:mappingResult forKey:keyPath];
}
}
if (NO == foundMappable) return nil;
return results;
}
// Primary entry point for the mapper.
– (RKObjectMappingResult *)performMapping {
NSAssert(self.sourceObject != nil, @”Cannot perform object mapping without a source object to map from”);
NSAssert(self.mappingProvider != nil, @”Cannot perform object mapping without an object mapping provider”);
RKLogDebug(@”Performing object mapping sourceObject: %@\n and targetObject: %@”, self.sourceObject, self.targetObject);
if ([self.delegate respondsToSelector:@selector(objectMapperWillBeginMapping:)]) {
[self.delegate objectMapperWillBeginMapping:self];
}
// Perform the mapping
BOOL foundMappable = NO;
NSMutableDictionary *results = nil;
// Handle mapping selection for context
id mappingsForContext = [self.mappingProvider valueForContext:context];
if ([mappingsForContext isKindOfClass:[NSDictionary class]]) {
results = [self performKeyPathMappingUsingMappingDictionary:mappingsForContext];
foundMappable = (results != nil);
} else if ([mappingsForContext isKindOfClass:[RKObjectMappingDefinition class]]) {
id mappableData = self.sourceObject;
if ([mappingsForContext rootKeyPath] != nil) {
NSString* rootKeyPath = [mappingsForContext rootKeyPath];
mappableData = [self.sourceObject valueForKeyPath:rootKeyPath];
RKLogDebug(@”Selected object mapping has rootKeyPath. Apply valueForKeyPath to mappable data: %@”, rootKeyPath);
}
if (mappableData) {
id mappingResult = [self performMappingForObject:mappableData atKeyPath:@”” usingMapping:mappingsForContext];
foundMappable = YES;
results = [NSDictionary dictionaryWithObject:mappingResult forKey:@””];
}
}
// Allow any queued operations to complete
RKLogDebug(@”The following operations are in the queue: %@”, operationQueue.operations);
[operationQueue waitUntilAllOperationsAreFinished];
if ([self.delegate respondsToSelector:@selector(objectMapperDidFinishMapping:)]) {
[self.delegate objectMapperDidFinishMapping:self];
}
// If we found nothing eligible for mapping in the content, add an unmappable key path error and fail mapping
// If the content is empty, we don’t consider it an error
BOOL isEmpty = [self.sourceObject respondsToSelector:@selector(count)] && ([self.sourceObject count] == 0);
if (foundMappable == NO && !isEmpty) {
[self addErrorForUnmappableKeyPath:@””];
return nil;
}
RKLogDebug(@”Finished performing object mapping. Results: %@”, results);
return [RKObjectMappingResult mappingResultWithDictionary:results];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapper.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapper_Private.h
//
// RKObjectMapper_Private.h
// RestKit
//
// Created by Blake Watters on 5/9/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
@interface RKObjectMapper (Private)
– (id)mapObject:(id)mappableObject atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping;
– (NSArray*)mapCollection:(NSArray*)mappableObjects atKeyPath:(NSString*)keyPath usingMapping:(RKObjectMappingDefinition *)mapping;
– (BOOL)mapFromObject:(id)mappableObject toObject:(id)destinationObject atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMappingDefinition *)mapping;
– (id)objectWithMapping:(RKObjectMappingDefinition *)objectMapping andData:(id)mappableData;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapper_Private.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapperError.h
//
// RKObjectMapperError.h
// RestKit
//
// Created by Blake Watters on 5/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKErrors.h”
typedef enum {
RKObjectMapperErrorObjectMappingNotFound = 1001, // No mapping found
RKObjectMapperErrorObjectMappingTypeMismatch = 1002, // Target class and object mapping are in disagreement
RKObjectMapperErrorUnmappableContent = 1003, // No mappable attributes or relationships were found
RKObjectMapperErrorFromMappingResult = 1004, // The error was returned from the mapping result
RKObjectMapperErrorValidationFailure = 1005 // Generic error code for use when constructing validation errors
} RKObjectMapperErrorCode;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapperError.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapping.h
//
// RKObjectMapping.h
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMappingDefinition.h”
#import “RKObjectAttributeMapping.h”
#import “RKObjectRelationshipMapping.h”
/**
An object mapping defines the rules for transforming a key-value coding
compliant object into another representation. The mapping is defined in terms
of a source object class and a collection of rules defining how keyPaths should
be transformed into target attributes and relationships.
There are two types of transformations possible:
1. keyPath to attribute. Defines that the value found at the keyPath should be
transformed and assigned to the property specified by the attribute. The transformation
to be performed is determined by inspecting the type of the target property at runtime.
1. keyPath to relationship. Defines that the value found at the keyPath should be
transformed into another object instance and assigned to the property specified by the
relationship. Relationships are processed using an object mapping as well.
Through the use of relationship mappings, an arbitrarily complex object graph can be mapped for you.
Instances of RKObjectMapping are used to configure RKObjectMappingOperation instances, which actually
perform the mapping work. Both object loading and serialization are defined in terms of object mappings.
*/
@interface RKObjectMapping : RKObjectMappingDefinition
Class _objectClass;
NSMutableArray* _mappings;
NSString* _rootKeyPath;
BOOL _setDefaultValueForMissingAttributes;
BOOL _setNilForMissingRelationships;
BOOL _performKeyValueValidation;
NSArray *_dateFormatters;
NSFormatter *_preferredDateFormatter;
}
/**
The target class this object mapping is defining rules for
*/
@property (nonatomic, assign) Class objectClass;
/**
The name of the target class the receiver defines a mapping for.
@see objectClass
*/
@property (nonatomic, copy) NSString *objectClassName;
/**
The aggregate collection of attribute and relationship mappings within this object mapping
*/
@property (nonatomic, readonly) NSArray *mappings;
/**
The collection of attribute mappings within this object mapping
*/
@property (nonatomic, readonly) NSArray *attributeMappings;
/**
The collection of relationship mappings within this object mapping
*/
@property (nonatomic, readonly) NSArray *relationshipMappings;
/**
The collection of mappable keyPaths that are defined within this object mapping. These
keyPaths refer to keys within the source object being mapped (i.e. the parsed JSON payload).
*/
@property (nonatomic, readonly) NSArray *mappedKeyPaths;
/**
When YES, any attributes that have mappings defined but are not present within the source
object will be set to nil, clearing any existing value.
*/
@property (nonatomic, assign, getter = shouldSetDefaultValueForMissingAttributes) BOOL setDefaultValueForMissingAttributes;
/**
When YES, any relationships that have mappings defined but are not present within the source
object will be set to nil, clearing any existing value.
*/
@property (nonatomic, assign) BOOL setNilForMissingRelationships;
/**
When YES, RestKit will invoke key-value validation at object mapping time.
**Default**: YES
@see validateValue:forKey:error:
*/
@property (nonatomic, assign) BOOL performKeyValueValidation;
/**
When YES, RestKit will check that the object being mapped is key-value coding
compliant for the mapped key. If it is not, the attribute/relationship mapping will
be ignored and mapping will continue. When NO, unknown keyPath mappings will generate
NSUnknownKeyException errors for the unknown keyPath.
Defaults to NO to help the developer catch incorrect mapping configurations during
development.
**Default**: NO
*/
@property (nonatomic, assign) BOOL ignoreUnknownKeyPaths;
/**
An array of NSDateFormatter objects to use when mapping string values
into NSDate attributes on the target objectClass. Each date formatter
will be invoked with the string value being mapped until one of the date
formatters does not return nil.
Defaults to the application-wide collection of date formatters configured via:
[RKObjectMapping setDefaultDateFormatters:]
@see [RKObjectMapping defaultDateFormatters]
*/
@property (nonatomic, retain) NSArray *dateFormatters;
/**
The NSFormatter object for your application’s preferred date
and time configuration. This date formatter will be used when generating
string representations of NSDate attributes (i.e. during serialization to
URL form encoded or JSON format).
Defaults to the application-wide preferred date formatter configured via:
[RKObjectMapping setPreferredDateFormatter:]
@see [RKObjectMapping preferredDateFormatter]
*/
@property (nonatomic, retain) NSFormatter *preferredDateFormatter;
#pragma mark – Mapping Instantiation
/**
Returns an object mapping for the specified class that is ready for configuration
*/
+ (id)mappingForClass:(Class)objectClass;
/**
Creates and returns an object mapping for the class with the given name
@param objectClassName The name of the class the mapping is for.
@return A new object mapping with for the class with given name.
*/
+ (id)mappingForClassWithName:(NSString *)objectClassName;
/**
Returns an object mapping useful for configuring a serialization mapping. The object
class is configured as NSMutableDictionary
*/
+ (id)serializationMapping;
#if NS_BLOCKS_AVAILABLE
/**
Returns an object mapping targeting the specified class. The RKObjectMapping instance will
be yieled to the block so that you can perform on the fly configuration without having to
obtain a reference variable for the mapping.
For example, consider we have a one-off request that will load a few attributes for our object.
Using blocks, this is very succinct:
[[RKObjectManager sharedManager] postObject:self usingBlock:^(RKObjectLoader* loader) {
loader.objectMapping = [RKObjectMapping mappingForClass:[Person class] usingBlock:^(RKObjectMapping* mapping) {
[mapping mapAttributes:@”email”, @”first_name”, nil];
}];
}];
*/
+ (id)mappingForClass:(Class)objectClass usingBlock:(void (^)(RKObjectMapping *mapping))block;
/**
Returns serialization mapping for encoding a local object to a dictionary for transport. The RKObjectMapping instance will
be yieled to the block so that you can perform on the fly configuration without having to
obtain a reference variable for the mapping.
For example, consider we have a one-off request within which we want to post a subset of our object
data. Using blocks, this is very succinct:
– (BOOL)changePassword:(NSString*)newPassword error:(NSError**)error {
if ([self validatePassword:newPassword error:error]) {
self.password = newPassword;
[[RKObjectManager sharedManager] putObject:self delegate:self block:^(RKObjectLoader* loader) {
loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping* mapping) {
[mapping mapAttributes:@”password”, nil];
}];
}];
}
}
Using the block forms we are able to quickly configure and send this request on the fly.
*/
+ (id)serializationMappingUsingBlock:(void (^)(RKObjectMapping *serializationMapping))block;
#endif
/**
Add a configured attribute mapping to this object mapping
@see RKObjectAttributeMapping
*/
– (void)addAttributeMapping:(RKObjectAttributeMapping*)mapping;
/**
Add a configured attribute mapping to this object mapping
@see RKObjectRelationshipMapping
*/
– (void)addRelationshipMapping:(RKObjectRelationshipMapping*)mapping;
#pragma mark – Retrieving Mappings
/**
Returns the attribute or relationship mapping for the given source keyPath.
@param sourceKeyPath A keyPath within the mappable source object that is mapped to an
attribute or relationship in this object mapping.
*/
– (id)mappingForKeyPath:(NSString*)sourceKeyPath;
/**
Returns the attribute or relationship mapping for the given source keyPath.
@param sourceKeyPath A keyPath within the mappable source object that is mapped to an
attribute or relationship in this object mapping.
*/
– (id)mappingForSourceKeyPath:(NSString*)sourceKeyPath;
/**
Returns the attribute or relationship mapping for the given destination keyPath.
@param destinationKeyPath A keyPath on the destination object that is currently
*/
– (id)mappingForDestinationKeyPath:(NSString *)destinationKeyPath;
/**
Returns the attribute mapping targeting the specified attribute on the destination object
@param attributeKey The name of the attribute we want to retrieve the mapping for
*/
– (RKObjectAttributeMapping *)mappingForAttribute:(NSString *)attributeKey;
/**
Returns the relationship mapping targeting the specified relationship on the destination object
@param relationshipKey The name of the relationship we want to retrieve the mapping for
*/
– (RKObjectRelationshipMapping*)mappingForRelationship:(NSString*)relationshipKey;
#pragma mark – Attribute & Relationship Mapping
/**
Define an attribute mapping for one or more keyPaths where the source keyPath and destination attribute property
have the same name.
For example, given the transformation from a JSON dictionary:
{“name”: “My Name”, “age”: 28}
To a Person class with corresponding name & age properties, we could configure the attribute mappings via:
[mapping mapAttributes:@”name”, @”age”, nil];
@param attributeKey A key-value coding key corresponding to a value in the mappable source object and an attribute
on the destination class that have the same name.
*/
– (void)mapAttributes:(NSString *)attributeKey, … NS_REQUIRES_NIL_TERMINATION;
/**
Defines an attribute mapping for each string attribute in the collection where the source keyPath and the
destination attribute property have the same name.
For example, given the transformation from a JSON dictionary:
{“name”: “My Name”, “age”: 28}
To a Person class with corresponding name & age properties, we could configure the attribute mappings via:
[mapping mapAttributesFromSet:[NSSet setWithObjects:@”name”, @”age”, nil]];
@param set A set of string attribute keyPaths to deifne mappings for
*/
– (void)mapAttributesFromSet:(NSSet *)set;
/**
Defines an attribute mapping for each string attribute in the collection where the source keyPath and the
destination attribute property have the same name.
For example, given the transformation from a JSON dictionary:
{“name”: “My Name”, “age”: 28}
To a Person class with corresponding name & age properties, we could configure the attribute mappings via:
[mapping mapAttributesFromSet:[NSArray arrayWithObjects:@”name”, @”age”, nil]];
@param array An array of string attribute keyPaths to deifne mappings for
*/
– (void)mapAttributesFromArray:(NSArray *)set;
/**
Defines a relationship mapping for a key where the source keyPath and the destination relationship property
have the same name.
For example, given the transformation from a JSON dictionary:
{“name”: “My Name”, “age”: 28, “cat”: { “name”: “Asia” } }
To a Person class with corresponding ‘cat’ relationship property, we could configure the mappings via:
RKObjectMapping* catMapping = [RKObjectMapping mappingForClass:[Cat class]];
[personMapping mapRelationship:@”cat” withObjectMapping:catMapping];
@param relationshipKey A key-value coding key corresponding to a value in the mappable source object and a property
on the destination class that have the same name.
@param objectOrDynamicMapping An RKObjectMapping or RKObjectDynamic mapping to apply when mapping the relationship
*/
– (void)mapRelationship:(NSString*)relationshipKey withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping;
/**
Syntactic sugar to improve readability when defining a relationship mapping. Implies that the mapping
targets a one-to-many relationship nested within the source data.
@see mapRelationship:withObjectMapping:
*/
– (void)hasMany:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping;
/**
Syntactic sugar to improve readability when defining a relationship mapping. Implies that the mapping
targets a one-to-one relationship nested within the source data.
@see mapRelationship:withObjectMapping:
*/
– (void)hasOne:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping;
/**
Instantiate and add an RKObjectAttributeMapping instance targeting a keyPath within the mappable
source data to an attribute on the target object.
Used to quickly define mappings where the source value is deeply nested in the mappable data or
the source and destination do not have corresponding names.
Examples:
// We want to transform the name to something Cocoa-esque
[mapping mapKeyPath:@”created_at” toAttribute:@”createdAt”];
// We want to extract nested data and map it to a property
[mapping mapKeyPath:@”results.metadata.generated_on” toAttribute:@”generationTimestamp”];
@param sourceKeyPath A key-value coding keyPath to fetch the mappable value from
@param destinationAttribute The attribute name to assign the mapped value to
@see RKObjectAttributeMapping
*/
– (void)mapKeyPath:(NSString*)sourceKeyPath toAttribute:(NSString*)destinationAttribute;
/**
Instantiate and add an RKObjectRelationshipMapping instance targeting a keyPath within the mappable
source data to a relationship property on the target object.
Used to quickly define mappings where the source value is deeply nested in the mappable data or
the source and destination do not have corresponding names.
Examples:
// We want to transform the name to something Cocoa-esque
[mapping mapKeyPath:@”best_friend” toRelationship:@”bestFriend” withObjectMapping:friendMapping];
// We want to extract nested data and map it to a property
[mapping mapKeyPath:@”best_friend.favorite_cat” toRelationship:@”bestFriendsFavoriteCat” withObjectMapping:catMapping];
@param sourceKeyPath A key-value coding keyPath to fetch the mappable value from
@param destinationRelationship The relationship name to assign the mapped value to
@param objectMapping An object mapping to use when processing the nested objects
@see RKObjectRelationshipMapping
*/
– (void)mapKeyPath:(NSString *)sourceKeyPath toRelationship:(NSString*)destinationRelationship withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping;
/**
Instantiate and add an RKObjectRelationshipMapping instance targeting a keyPath within the mappable
source data to a relationship property on the target object.
Used to indicate whether the relationship should be included in serialization.
@param sourceKeyPath A key-value coding keyPath to fetch the mappable value from
@param destinationRelationship The relationship name to assign the mapped value to
@param objectMapping An object mapping to use when processing the nested objects
@param serialize A boolean value indicating whether to include this relationship in serialization
@see mapKeyPath:toRelationship:withObjectMapping:
*/
– (void)mapKeyPath:(NSString *)relationshipKeyPath toRelationship:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping serialize:(BOOL)serialize;
/**
Quickly define a group of attribute mappings using alternating keyPath and attribute names. You must provide
an equal number of keyPath and attribute pairs or an exception will be generated.
For example:
[personMapping mapKeyPathsToAttributes:@”name”, @”name”, @”createdAt”, @”createdAt”, @”street_address”, @”streetAddress”, nil];
@param sourceKeyPath A key-value coding key path to fetch a mappable value from
@param … A nil-terminated sequence of strings alternating between source key paths and destination attributes
*/
– (void)mapKeyPathsToAttributes:(NSString*)sourceKeyPath, … NS_REQUIRES_NIL_TERMINATION;
/**
Configures a sub-key mapping for cases where JSON has been nested underneath a key named after an attribute.
For example, consider the following JSON:
{ “users”:
{
“blake”: { “id”: 1234, “email”: “blake@restkit.org” },
“rachit”: { “id”: 5678″, “email”: “rachit@restkit.org” }
}
}
We can configure our mappings to handle this in the following form:
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[User class]];
mapping.forceCollectionMapping = YES; // RestKit cannot infer this is a collection, so we force it
[mapping mapKeyOfNestedDictionaryToAttribute:@”firstName”];
[mapping mapFromKeyPath:@”(firstName).id” toAttribute:”userID”];
[mapping mapFromKeyPath:@”(firstName).email” toAttribute:”email”];
[[RKObjectManager sharedManager].mappingProvider setObjectMapping:mapping forKeyPath:@”users”];
*/
– (void)mapKeyOfNestedDictionaryToAttribute:(NSString *)attributeName;
/**
Returns the attribute mapping targeting the key of a nested dictionary in the source JSON.
This attribute mapping corresponds to the attributeName configured via mapKeyOfNestedDictionaryToAttribute:
@see mapKeyOfNestedDictionaryToAttribute:
@returns An attribute mapping for the key of a nested dictionary being mapped or nil
*/
– (RKObjectAttributeMapping *)attributeMappingForKeyOfNestedDictionary;
/**
Removes all currently configured attribute and relationship mappings from the object mapping
*/
– (void)removeAllMappings;
/**
Removes an instance of an attribute or relationship mapping from the object mapping
@param attributeOrRelationshipMapping The attribute or relationship mapping to remove
*/
– (void)removeMapping:(RKObjectAttributeMapping*)attributeOrRelationshipMapping;
/**
Remove the attribute or relationship mapping for the specified source keyPath
@param sourceKeyPath A key-value coding key path to remove the mappings for
*/
– (void)removeMappingForKeyPath:(NSString*)sourceKeyPath;
#pragma mark – Inverse Mappings
/**
Generates an inverse mapping for the rules specified within this object mapping. This can be used to
quickly generate a corresponding serialization mapping from a configured object mapping. The inverse
mapping will have the source and destination keyPaths swapped for all attribute and relationship mappings.
*/
– (RKObjectMapping*)inverseMapping;
/**
Returns the default value to be assigned to the specified attribute when it is missing from a
mappable payload.
The default implementation returns nil for transient object mappings. On managed object mappings, the
default value returned from the Entity definition will be used.
@see [RKManagedObjectMapping defaultValueForMissingAttribute:]
*/
– (id)defaultValueForMissingAttribute:(NSString*)attributeName;
/**
Returns an auto-released object that can be used to apply this object mapping
given a set of mappable data. For transient objects, this generally returns an
instance of the objectClass. For Core Data backed persistent objects, mappableData
will be inspected to search for primary key data to lookup existing object instances.
*/
/*- (id)mappableObjectForData:(id)mappableData;*/
/**
Returns the class of the attribute or relationship property of the target objectClass
Given the name of a string property, this will return an NSString, etc.
@param propertyName The name of the property we would like to retrieve the type of
*/
– (Class)classForProperty:(NSString*)propertyName;
/**
Returns an auto-released object that can be used to apply this object mapping
given a set of mappable data. For transient objects, this generally returns an
instance of the objectClass. For Core Data backed persistent objects, mappableData
will be inspected to search for primary key data to lookup existing object instances.
*/
– (id)mappableObjectForData:(id)mappableData;
// Deprecations
+ (id)mappingForClass:(Class)objectClass withBlock:(void (^)(RKObjectMapping*))block DEPRECATED_ATTRIBUTE;
+ (id)mappingForClass:(Class)objectClass block:(void (^)(RKObjectMapping*))block DEPRECATED_ATTRIBUTE;
+ (id)serializationMappingWithBlock:(void (^)(RKObjectMapping*))block DEPRECATED_ATTRIBUTE;
@end
/////////////////////////////////////////////////////////////////////////////
/**
Defines the inteface for configuring time and date formatting handling within RestKit
object mappings. For performance reasons, RestKit reuses a pool of date formatters rather
than constructing them at mapping time. This collection of date formatters can be configured
on a per-object mapping or application-wide basis using the static methods exposed in this
category.
*/
@interface RKObjectMapping (DateAndTimeFormatting)
/**
Returns the collection of default date formatters that will be used for all object mappings
that have not been configured specifically.
Out of the box, RestKit initializes the following default date formatters for you in the
UTC time zone:
* yyyy-MM-dd’T’HH:mm:ss’Z’
* MM/dd/yyyy
@return An array of NSFormatter objects used when mapping strings into NSDate attributes
*/
+ (NSArray *)defaultDateFormatters;
/**
Sets the collection of default date formatters to the specified array. The array should
contain configured instances of NSDateFormatter in the order in which you want them applied
during object mapping operations.
@param dateFormatters An array of date formatters to replace the existing defaults
@see defaultDateFormatters
*/
+ (void)setDefaultDateFormatters:(NSArray *)dateFormatters;
/**
Adds a date formatter instance to the default collection
@param dateFormatter An NSFormatter object to append to the end of the default formatters collection
@see defaultDateFormatters
*/
+ (void)addDefaultDateFormatter:(NSFormatter *)dateFormatter;
/**
Convenience method for quickly constructing a date formatter and adding it to the collection of default
date formatters. The locale is auto-configured to en_US_POSIX
@param dateFormatString The dateFormat string to assign to the newly constructed NSDateFormatter instance
@param nilOrTimeZone The NSTimeZone object to configure on the NSDateFormatter instance. Defaults to UTC time.
@result A new NSDateFormatter will be appended to the defaultDateFormatters with the specified date format and time zone
@see NSDateFormatter
*/
+ (void)addDefaultDateFormatterForString:(NSString *)dateFormatString inTimeZone:(NSTimeZone *)nilOrTimeZone;
/**
Returns the preferred date formatter to use when generating NSString representations from NSDate attributes.
This type of transformation occurs when RestKit is mapping local objects into JSON or form encoded serializations
that do not have a native time construct.
Defaults to a date formatter configured for the UTC Time Zone with a format string of “yyyy-MM-dd HH:mm:ss Z”
@return The preferred NSFormatter object to use when serializing dates into strings
*/
+ (NSFormatter *)preferredDateFormatter;
/**
Sets the preferred date formatter to use when generating NSString representations from NSDate attributes.
This type of transformation occurs when RestKit is mapping local objects into JSON or form encoded serializations
that do not have a native time construct.
@param dateFormatter The NSFormatter object to designate as the new preferred instance
*/
+ (void)setPreferredDateFormatter:(NSFormatter *)dateFormatter;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMapping.m
//
// RKObjectMapping.m
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMapping.h”
#import “RKObjectRelationshipMapping.h”
#import “RKObjectPropertyInspector.h”
#import “RKLog.h”
#import “RKISO8601DateFormatter.h”
// Constants
NSString* const RKObjectMappingNestingAttributeKeyName = @”
@implementation RKObjectMapping
@synthesize objectClass = _objectClass;
@synthesize mappings = _mappings;
@synthesize dateFormatters = _dateFormatters;
@synthesize preferredDateFormatter = _preferredDateFormatter;
@synthesize rootKeyPath = _rootKeyPath;
@synthesize setDefaultValueForMissingAttributes = _setDefaultValueForMissingAttributes;
@synthesize setNilForMissingRelationships = _setNilForMissingRelationships;
@synthesize performKeyValueValidation = _performKeyValueValidation;
@synthesize ignoreUnknownKeyPaths = _ignoreUnknownKeyPaths;
+ (id)mappingForClass:(Class)objectClass {
RKObjectMapping* mapping = [self new];
mapping.objectClass = objectClass;
return [mapping autorelease];
}
+ (id)mappingForClassWithName:(NSString *)objectClassName {
return [self mappingForClass:NSClassFromString(objectClassName)];
}
+ (id)serializationMapping {
return [self mappingForClass:[NSMutableDictionary class]];
}
#if NS_BLOCKS_AVAILABLE
+ (id)mappingForClass:(Class)objectClass usingBlock:(void (^)(RKObjectMapping*))block {
RKObjectMapping* mapping = [self mappingForClass:objectClass];
block(mapping);
return mapping;
}
+ (id)serializationMappingUsingBlock:(void (^)(RKObjectMapping*))block {
RKObjectMapping* mapping = [self serializationMapping];
block(mapping);
return mapping;
}
// Deprecated… Move to category or bottom…
+ (id)mappingForClass:(Class)objectClass withBlock:(void (^)(RKObjectMapping*))block {
return [self mappingForClass:objectClass usingBlock:block];
}
+ (id)mappingForClass:(Class)objectClass block:(void (^)(RKObjectMapping*))block {
return [self mappingForClass:objectClass usingBlock:block];
}
+ (id)serializationMappingWithBlock:(void (^)(RKObjectMapping*))block {
RKObjectMapping* mapping = [self serializationMapping];
block(mapping);
return mapping;
}
#endif // NS_BLOCKS_AVAILABLE
– (id)init {
self = [super init];
if (self) {
_mappings = [NSMutableArray new];
self.setDefaultValueForMissingAttributes = NO;
self.setNilForMissingRelationships = NO;
self.forceCollectionMapping = NO;
self.performKeyValueValidation = YES;
self.ignoreUnknownKeyPaths = NO;
}
return self;
}
– (id)copyWithZone:(NSZone *)zone {
RKObjectMapping *copy = [[[self class] allocWithZone:zone] init];
copy.objectClass = self.objectClass;
copy.rootKeyPath = self.rootKeyPath;
copy.setDefaultValueForMissingAttributes = self.setDefaultValueForMissingAttributes;
copy.setNilForMissingRelationships = self.setNilForMissingRelationships;
copy.forceCollectionMapping = self.forceCollectionMapping;
copy.performKeyValueValidation = self.performKeyValueValidation;
copy.dateFormatters = self.dateFormatters;
copy.preferredDateFormatter = self.preferredDateFormatter;
for (RKObjectAttributeMapping *mapping in self.mappings) {
[copy addAttributeMapping:mapping];
}
return copy;
}
– (void)dealloc {
[_rootKeyPath release];
[_mappings release];
[_dateFormatters release];
[_preferredDateFormatter release];
[super dealloc];
}
– (NSString *)objectClassName {
return NSStringFromClass(self.objectClass);
}
– (void)setObjectClassName:(NSString *)objectClassName {
self.objectClass = NSClassFromString(objectClassName);
}
– (NSArray *)mappedKeyPaths {
return [_mappings valueForKey:@”destinationKeyPath”];
}
– (NSArray *)attributeMappings {
NSMutableArray* mappings = [NSMutableArray array];
for (RKObjectAttributeMapping* mapping in self.mappings) {
if ([mapping isMemberOfClass:[RKObjectAttributeMapping class]]) {
[mappings addObject:mapping];
}
}
return mappings;
}
– (NSArray *)relationshipMappings {
NSMutableArray* mappings = [NSMutableArray array];
for (RKObjectAttributeMapping* mapping in self.mappings) {
if ([mapping isMemberOfClass:[RKObjectRelationshipMapping class]]) {
[mappings addObject:mapping];
}
}
return mappings;
}
– (void)addAttributeMapping:(RKObjectAttributeMapping*)mapping {
NSAssert1([[self mappedKeyPaths] containsObject:mapping.destinationKeyPath] == NO, @”Unable to add mapping for keyPath %@, one already exists…”, mapping.destinationKeyPath);
[_mappings addObject:mapping];
}
– (void)addRelationshipMapping:(RKObjectRelationshipMapping*)mapping {
[self addAttributeMapping:mapping];
}
– (NSString *)description {
return [NSString stringWithFormat:@”<%@:%p objectClass=%@ keyPath mappings => %@>”, NSStringFromClass([self class]), self, NSStringFromClass(self.objectClass), _mappings];
}
– (id)mappingForKeyPath:(NSString *)keyPath {
return [self mappingForSourceKeyPath:keyPath];
}
– (id)mappingForSourceKeyPath:(NSString *)sourceKeyPath {
for (RKObjectAttributeMapping* mapping in _mappings) {
if ([mapping.sourceKeyPath isEqualToString:sourceKeyPath]) {
return mapping;
}
}
return nil;
}
– (id)mappingForDestinationKeyPath:(NSString *)destinationKeyPath {
for (RKObjectAttributeMapping* mapping in _mappings) {
if ([mapping.destinationKeyPath isEqualToString:destinationKeyPath]) {
return mapping;
}
}
return nil;
}
– (void)mapAttributesCollection:(id
for (NSString* attributeKeyPath in attributes) {
[self addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:attributeKeyPath toKeyPath:attributeKeyPath]];
}
}
– (void)mapAttributes:(NSString*)attributeKeyPath, … {
va_list args;
va_start(args, attributeKeyPath);
NSMutableSet* attributeKeyPaths = [NSMutableSet set];
for (NSString* keyPath = attributeKeyPath; keyPath != nil; keyPath = va_arg(args, NSString*)) {
[attributeKeyPaths addObject:keyPath];
}
va_end(args);
[self mapAttributesCollection:attributeKeyPaths];
}
– (void)mapAttributesFromSet:(NSSet *)set {
[self mapAttributesCollection:set];
}
– (void)mapAttributesFromArray:(NSArray *)array {
[self mapAttributesCollection:[NSSet setWithArray:array]];
}
– (void)mapKeyPath:(NSString *)relationshipKeyPath toRelationship:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping serialize:(BOOL)serialize {
RKObjectRelationshipMapping* mapping = [RKObjectRelationshipMapping mappingFromKeyPath:relationshipKeyPath toKeyPath:keyPath withMapping:objectOrDynamicMapping reversible:serialize];
[self addRelationshipMapping:mapping];
}
– (void)mapKeyPath:(NSString *)relationshipKeyPath toRelationship:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping {
[self mapKeyPath:relationshipKeyPath toRelationship:keyPath withMapping:objectOrDynamicMapping serialize:YES];
}
– (void)mapRelationship:(NSString*)relationshipKeyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping {
[self mapKeyPath:relationshipKeyPath toRelationship:relationshipKeyPath withMapping:objectOrDynamicMapping];
}
– (void)mapKeyPath:(NSString*)sourceKeyPath toAttribute:(NSString*)destinationKeyPath {
RKObjectAttributeMapping* mapping = [RKObjectAttributeMapping mappingFromKeyPath:sourceKeyPath toKeyPath:destinationKeyPath];
[self addAttributeMapping:mapping];
}
– (void)hasMany:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping {
[self mapRelationship:keyPath withMapping:objectOrDynamicMapping];
}
– (void)hasOne:(NSString*)keyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping {
[self mapRelationship:keyPath withMapping:objectOrDynamicMapping];
}
– (void)removeAllMappings {
[_mappings removeAllObjects];
}
– (void)removeMapping:(RKObjectAttributeMapping*)attributeOrRelationshipMapping {
[_mappings removeObject:attributeOrRelationshipMapping];
}
– (void)removeMappingForKeyPath:(NSString*)keyPath {
RKObjectAttributeMapping* mapping = [self mappingForKeyPath:keyPath];
[self removeMapping:mapping];
}
#ifndef MAX_INVERSE_MAPPING_RECURSION_DEPTH
#define MAX_INVERSE_MAPPING_RECURSION_DEPTH (100)
#endif
– (RKObjectMapping*)inverseMappingAtDepth:(NSInteger)depth {
NSAssert(depth < MAX_INVERSE_MAPPING_RECURSION_DEPTH, @"Exceeded max recursion level in inverseMapping. This is likely due to a loop in the serialization graph. To break this loop, specify one-way relationships by setting serialize to NO in mapKeyPath:toRelationship:withObjectMapping:serialize:");
RKObjectMapping* inverseMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
for (RKObjectAttributeMapping* attributeMapping in self.attributeMappings) {
[inverseMapping mapKeyPath:attributeMapping.destinationKeyPath toAttribute:attributeMapping.sourceKeyPath];
}
for (RKObjectRelationshipMapping* relationshipMapping in self.relationshipMappings) {
if (relationshipMapping.reversible) {
RKObjectMappingDefinition * mapping = relationshipMapping.mapping;
if (! [mapping isKindOfClass:[RKObjectMapping class]]) {
RKLogWarning(@"Unable to generate inverse mapping for relationship '%@': %@ relationships cannot be inversed.", relationshipMapping.sourceKeyPath, NSStringFromClass([mapping class]));
continue;
}
[inverseMapping mapKeyPath:relationshipMapping.destinationKeyPath toRelationship:relationshipMapping.sourceKeyPath withMapping:[(RKObjectMapping*)mapping inverseMappingAtDepth:depth+1]];
}
}
return inverseMapping;
}
- (RKObjectMapping*)inverseMapping {
return [self inverseMappingAtDepth:0];
}
- (void)mapKeyPathsToAttributes:(NSString*)firstKeyPath, ... {
va_list args;
va_start(args, firstKeyPath);
for (NSString* keyPath = firstKeyPath; keyPath != nil; keyPath = va_arg(args, NSString*)) {
NSString* attributeKeyPath = va_arg(args, NSString*);
NSAssert(attributeKeyPath != nil, @"Cannot map a keyPath without a destination attribute keyPath");
[self mapKeyPath:keyPath toAttribute:attributeKeyPath];
// TODO: Raise proper exception here, argument error...
}
va_end(args);
}
- (void)mapKeyOfNestedDictionaryToAttribute:(NSString*)attributeName {
[self mapKeyPath:RKObjectMappingNestingAttributeKeyName toAttribute:attributeName];
}
- (RKObjectAttributeMapping *)attributeMappingForKeyOfNestedDictionary {
return [self mappingForKeyPath:RKObjectMappingNestingAttributeKeyName];
}
- (RKObjectAttributeMapping*)mappingForAttribute:(NSString*)attributeKey {
for (RKObjectAttributeMapping* mapping in [self attributeMappings]) {
if ([mapping.destinationKeyPath isEqualToString:attributeKey]) {
return mapping;
}
}
return nil;
}
- (RKObjectRelationshipMapping*)mappingForRelationship:(NSString*)relationshipKey {
for (RKObjectRelationshipMapping* mapping in [self relationshipMappings]) {
if ([mapping.destinationKeyPath isEqualToString:relationshipKey]) {
return mapping;
}
}
return nil;
}
- (id)defaultValueForMissingAttribute:(NSString*)attributeName {
return nil;
}
- (id)mappableObjectForData:(id)mappableData {
return [[self.objectClass new] autorelease];
}
- (Class)classForProperty:(NSString*)propertyName {
return [[RKObjectPropertyInspector sharedInspector] typeForProperty:propertyName ofClass:self.objectClass];
}
#pragma mark - Date and Time
- (NSFormatter *)preferredDateFormatter {
return _preferredDateFormatter ? _preferredDateFormatter : [RKObjectMapping preferredDateFormatter];
}
- (NSArray *)dateFormatters {
return _dateFormatters ? _dateFormatters : [RKObjectMapping defaultDateFormatters];
}
@end
/////////////////////////////////////////////////////////////////////////////
static NSMutableArray *defaultDateFormatters = nil;
static NSDateFormatter *preferredDateFormatter = nil;
@implementation RKObjectMapping (DateAndTimeFormatting)
+ (NSArray *)defaultDateFormatters {
if (!defaultDateFormatters) {
defaultDateFormatters = [[NSMutableArray alloc] initWithCapacity:2];
// Setup the default formatters
RKISO8601DateFormatter *isoFormatter = [[RKISO8601DateFormatter alloc] init];
[self addDefaultDateFormatter:isoFormatter];
[isoFormatter release];
[self addDefaultDateFormatterForString:@"MM/dd/yyyy" inTimeZone:nil];
[self addDefaultDateFormatterForString:@"yyyy-MM-dd'T'HH:mm:ss'Z'" inTimeZone:nil];
}
return defaultDateFormatters;
}
+ (void)setDefaultDateFormatters:(NSArray *)dateFormatters {
[defaultDateFormatters release];
defaultDateFormatters = nil;
if (dateFormatters) {
defaultDateFormatters = [[NSMutableArray alloc] initWithArray:dateFormatters];
}
}
+ (void)addDefaultDateFormatter:(id)dateFormatter {
[self defaultDateFormatters];
[defaultDateFormatters insertObject:dateFormatter atIndex:0];
}
+ (void)addDefaultDateFormatterForString:(NSString *)dateFormatString inTimeZone:(NSTimeZone *)nilOrTimeZone {
NSDateFormatter *dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat = dateFormatString;
dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
if (nilOrTimeZone) {
dateFormatter.timeZone = nilOrTimeZone;
} else {
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
}
[self addDefaultDateFormatter:dateFormatter];
[dateFormatter release];
}
+ (NSFormatter *)preferredDateFormatter {
if (!preferredDateFormatter) {
// A date formatter that matches the output of [NSDate description]
preferredDateFormatter = [NSDateFormatter new];
[preferredDateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
preferredDateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
preferredDateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
}
return preferredDateFormatter;
}
+ (void)setPreferredDateFormatter:(NSDateFormatter *)dateFormatter {
[dateFormatter retain];
[preferredDateFormatter release];
preferredDateFormatter = dateFormatter;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingDefinition.h
//
// RKObjectMappingDefinition.h
// RestKit
//
// Created by Blake Watters on 7/31/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
RKObjectMappingDefinition is an abstract class for objects defining RestKit object mappings.
Its interface is common to all object mapping classes, including its concrete subclasses
RKObjectMapping and RKDynamicObjectMapping.
*/
@interface RKObjectMappingDefinition : NSObject
/**
The root key path for the receiver.
Root key paths are handled differently depending on the context in which the mapping is
being used. If the receiver is used for object mapping, the rootKeyPath specifies a nested
root dictionary that all attribute and relationship mappings will be considered relative to. When
the mapping is used in a serialization context, the rootKeyPath specifies that the serialized content
should be stored in a dictionary nested with the rootKeyPath as the key.
@see RKObjectSerializer
*/
@property (nonatomic, copy) NSString *rootKeyPath;
/**
Forces the mapper to treat the mapped keyPath as a collection even if it does not
return an array or a set of objects. This permits mapping where a dictionary identifies
a collection of objects.
When enabled, each key/value pair in the resolved dictionary will be mapped as a separate
entity. This is useful when you have a JSON structure similar to:
{ "users":
{
"blake": { "id": 1234, "email": "blake@restkit.org" },
"rachit": { "id": 5678", "email": "rachit@restkit.org" }
}
}
By enabling forceCollectionMapping, RestKit will map "blake" => attributes and
“rachit” => attributes as independent objects. This can be combined with
mapKeyOfNestedDictionaryToAttribute: to properly map these sorts of structures.
@default NO
@see mapKeyOfNestedDictionaryToAttribute
*/
@property (nonatomic, assign) BOOL forceCollectionMapping;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingDefinition.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingDefinition.m
//
// RKObjectMappingDefinition.m
// RestKit
//
// Created by Blake Watters on 2/15/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectMappingDefinition.h”
@implementation RKObjectMappingDefinition
@synthesize rootKeyPath;
@synthesize forceCollectionMapping;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingDefinition.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingOperation.h
//
// RKObjectMappingOperation.h
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMapping.h”
#import “RKObjectAttributeMapping.h”
@class RKObjectMappingOperation;
@class RKMappingOperationQueue;
/**
Objects acting as the delegate for RKObjectMappingOperation objects must adopt the
RKObjectMappingOperationDelegate protocol. These methods enable the delegate to be
notified of events such as the application of attribute and relationship mappings
during a mapping operation.
*/
@protocol RKObjectMappingOperationDelegate
@optional
/**
Tells the delegate that an attribute or relationship mapping was found for a given key
path within the data being mapped.
@param operation The object mapping operation being performed.
@param mapping The RKObjectAttributeMapping or RKObjectRelationshipMapping found for the key path.
@param keyPath The key path in the source object for which the mapping is to be applied.
*/
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didFindMapping:(RKObjectAttributeMapping *)mapping forKeyPath:(NSString *)keyPath;
/**
Tells the delegate that no attribute or relationships mapping was found for a given key
path within the data being mapped.
@param operation The object mapping operation being performed.
@param keyPath The key path in the source object for which no mapping was found.
*/
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didNotFindMappingForKeyPath:(NSString *)keyPath;
/**
Tells the delegate that the mapping operation has set a value for a given key path with
an attribute or relationship mapping.
@param operation The object mapping operation being performed.
@param value A new value that was set on the destination object.
@param keyPath The key path in the destination object for which a new value has been set.
@param mapping The RKObjectAttributeMapping or RKObjectRelationshipMapping found for the key path.
*/
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didSetValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKObjectAttributeMapping *)mapping;
/**
Tells the delegate that the mapping operation has declined to set a value for a given
key path because the value has not changed.
@param operation The object mapping operation being performed.
@param value A unchanged value for the key path in the destination object.
@param keyPath The key path in the destination object for which a unchanged value was not set.
@param mapping The RKObjectAttributeMapping or RKObjectRelationshipMapping found for the key path.
*/
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didNotSetUnchangedValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKObjectAttributeMapping *)mapping;
/**
Tells the delegate that the object mapping operation has failed due to an error.
@param operation The object mapping operation that has failed.
@param error An error object indicating the reason for the failure.
*/
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didFailWithError:(NSError *)error;
@end
/**
Instances of RKObjectMappingOperation perform transformation between object
representations according to the rules express in RKObjectMapping objects. Mapping
operations provide the foundation for the RestKit object mapping engine and
perform the work of inspecting the attributes and relationships of a source object
and determining how to map them into new representations on a destination object.
*/
@interface RKObjectMappingOperation : NSObject
/**
A dictionary of mappable elements containing simple values or nested object structures.
*/
@property (nonatomic, readonly) id sourceObject;
/**
The target object for this operation. Mappable values in elements will be applied to object
using key-value coding.
*/
@property (nonatomic, readonly) id destinationObject;
/**
The object mapping defining how values contained in the source object should be transformed to the destination object via key-value coding
*/
@property (nonatomic, readonly) RKObjectMapping *objectMapping;
/**
The delegate to inform of interesting events during the mapping operation
*/
@property (nonatomic, assign) id
/**
An operation queue for deferring portions of the mapping process until later
Defaults to nil. If this mapping operation was configured by an instance of RKObjectMapper, then
an instance of the operation queue will be configured and assigned for use. If the queue is nil,
the mapping operation will perform all its operations within the body of performMapping. If a queue
is present, it may elect to defer portions of the mapping operation using the queue.
*/
@property (nonatomic, retain) RKMappingOperationQueue *queue;
/**
Creates and returns a new mapping operation configured to transform the object representation
in a source object to a new destination object according to an object mapping definition.
Note that if Core Data support is available, an instance of RKManagedObjectMappingOperation may be returned.
@param sourceObject The source object to be mapped. Cannot be nil.
@param destinationObject The destination object the results are to be mapped onto. May be nil,
in which case a new object will be constructed during the mapping.
@param mapping An instance of RKObjectMapping or RKDynamicObjectMapping defining how the
mapping is to be performed.
@return An instance of RKObjectMappingOperation or RKManagedObjectMappingOperation for performing the mapping.
*/
+ (id)mappingOperationFromObject:(id)sourceObject toObject:(id)destinationObject withMapping:(RKObjectMappingDefinition *)mapping;
/**
Initializes the receiver with a source and destination objects and an object mapping
definition for performing a mapping.
@param sourceObject The source object to be mapped. Cannot be nil.
@param destinationObject The destination object the results are to be mapped onto. May be nil,
in which case a new object will be constructed during the mapping.
@param mapping An instance of RKObjectMapping or RKDynamicObjectMapping defining how the
mapping is to be performed.
@return The receiver, initialized with a source object, a destination object, and a mapping.
*/
– (id)initWithSourceObject:(id)sourceObject destinationObject:(id)destinationObject mapping:(RKObjectMappingDefinition *)mapping;
/**
Process all mappable values from the mappable dictionary and assign them to the target object
according to the rules expressed in the object mapping definition
@param error A pointer to an NSError reference to capture any error that occurs during the mapping. May be nil.
@return A Boolean value indicating if the mapping operation was successful.
*/
– (BOOL)performMapping:(NSError **)error;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingOperation.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingOperation.m
//
// RKObjectMappingOperation.m
// RestKit
//
// Created by Blake Watters on 4/30/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMappingOperation.h”
#import “RKObjectMapperError.h”
#import “RKObjectPropertyInspector.h”
#import “RKObjectRelationshipMapping.h”
#import “RKObjectMapper.h”
#import “RKErrors.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
// Temporary home for object equivalancy tests
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
NSCAssert(sourceValue, @”Expected sourceValue not to be nil”);
NSCAssert(destinationValue, @”Expected destinationValue not to be nil”);
SEL comparisonSelector;
if ([sourceValue isKindOfClass:[NSString class]] && [destinationValue isKindOfClass:[NSString class]]) {
comparisonSelector = @selector(isEqualToString:);
} else if ([sourceValue isKindOfClass:[NSNumber class]] && [destinationValue isKindOfClass:[NSNumber class]]) {
comparisonSelector = @selector(isEqualToNumber:);
} else if ([sourceValue isKindOfClass:[NSDate class]] && [destinationValue isKindOfClass:[NSDate class]]) {
comparisonSelector = @selector(isEqualToDate:);
} else if ([sourceValue isKindOfClass:[NSArray class]] && [destinationValue isKindOfClass:[NSArray class]]) {
comparisonSelector = @selector(isEqualToArray:);
} else if ([sourceValue isKindOfClass:[NSDictionary class]] && [destinationValue isKindOfClass:[NSDictionary class]]) {
comparisonSelector = @selector(isEqualToDictionary:);
} else if ([sourceValue isKindOfClass:[NSSet class]] && [destinationValue isKindOfClass:[NSSet class]]) {
comparisonSelector = @selector(isEqualToSet:);
} else {
comparisonSelector = @selector(isEqual:);
}
// Comparison magic using function pointers. See this page for details: http://www.red-sweater.com/blog/320/abusing-objective-c-with-class
// Original code courtesy of Greg Parker
// This is necessary because isEqualToNumber will return negative integer values that aren’t coercable directly to BOOL’s without help [sbw]
BOOL (*ComparisonSender)(id, SEL, id) = (BOOL (*)(id, SEL, id)) objc_msgSend;
return ComparisonSender(sourceValue, comparisonSelector, destinationValue);
}
@interface RKObjectMappingOperation ()
@property (nonatomic, retain) NSDictionary *nestedAttributeSubstitution;
@property (nonatomic, retain) NSError *validationError;
@end
@implementation RKObjectMappingOperation
@synthesize sourceObject = _sourceObject;
@synthesize destinationObject = _destinationObject;
@synthesize objectMapping = _objectMapping;
@synthesize delegate = _delegate;
@synthesize queue = _queue;
@synthesize nestedAttributeSubstitution = _nestedAttributeSubstitution;
@synthesize validationError = _validationError;
+ (id)mappingOperationFromObject:(id)sourceObject toObject:(id)destinationObject withMapping:(RKObjectMappingDefinition *)objectMapping {
// Check for availability of ManagedObjectMappingOperation. Better approach for handling?
Class targetClass = NSClassFromString(@”RKManagedObjectMappingOperation”);
if (targetClass == nil) targetClass = [RKObjectMappingOperation class];
return [[[targetClass alloc] initWithSourceObject:sourceObject destinationObject:destinationObject mapping:objectMapping] autorelease];
}
– (id)initWithSourceObject:(id)sourceObject destinationObject:(id)destinationObject mapping:(RKObjectMappingDefinition *)objectMapping {
NSAssert(sourceObject != nil, @”Cannot perform a mapping operation without a sourceObject object”);
NSAssert(destinationObject != nil, @”Cannot perform a mapping operation without a destinationObject”);
NSAssert(objectMapping != nil, @”Cannot perform a mapping operation without a mapping”);
self = [super init];
if (self) {
_sourceObject = [sourceObject retain];
_destinationObject = [destinationObject retain];
if ([objectMapping isKindOfClass:[RKDynamicObjectMapping class]]) {
_objectMapping = [[(RKDynamicObjectMapping*)objectMapping objectMappingForDictionary:_sourceObject] retain];
RKLogDebug(@”RKObjectMappingOperation was initialized with a dynamic mapping. Determined concrete mapping = %@”, _objectMapping);
} else if ([objectMapping isKindOfClass:[RKObjectMapping class]]) {
_objectMapping = (RKObjectMapping*)[objectMapping retain];
}
NSAssert(_objectMapping, @”Cannot perform a mapping operation with an object mapping”);
}
return self;
}
– (void)dealloc {
[_sourceObject release];
[_destinationObject release];
[_objectMapping release];
[_nestedAttributeSubstitution release];
[_queue release];
[super dealloc];
}
– (NSDate*)parseDateFromString:(NSString*)string {
RKLogTrace(@”Transforming string value ‘%@’ to NSDate…”, string);
NSDate* date = nil;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *numeric = [numberFormatter numberFromString:string];
[numberFormatter release];
if (numeric) {
date = [NSDate dateWithTimeIntervalSince1970:[numeric doubleValue]];
} else if(![string isEqualToString:@””]) {
for (NSFormatter *dateFormatter in self.objectMapping.dateFormatters) {
BOOL success;
@synchronized(dateFormatter) {
if ([dateFormatter isKindOfClass:[NSDateFormatter class]]) {
RKLogTrace(@”Attempting to parse string ‘%@’ with format string ‘%@’ and time zone ‘%@'”, string, [(NSDateFormatter *)dateFormatter dateFormat], [(NSDateFormatter *)dateFormatter timeZone]);
}
NSString *errorDescription = nil;
success = [dateFormatter getObjectValue:&date forString:string errorDescription:&errorDescription];
}
if (success && date) {
if ([dateFormatter isKindOfClass:[NSDateFormatter class]]) {
RKLogTrace(@”Successfully parsed string ‘%@’ with format string ‘%@’ and time zone ‘%@’ and turned into date ‘%@'”,
string, [(NSDateFormatter *)dateFormatter dateFormat], [(NSDateFormatter *)dateFormatter timeZone], date);
}
break;
}
}
}
return date;
}
– (id)transformValue:(id)value atKeyPath:(NSString *)keyPath toType:(Class)destinationType {
RKLogTrace(@”Found transformable value at keyPath ‘%@’. Transforming from type ‘%@’ to ‘%@'”, keyPath, NSStringFromClass([value class]), NSStringFromClass(destinationType));
Class sourceType = [value class];
Class orderedSetClass = NSClassFromString(@”NSOrderedSet”);
if ([sourceType isSubclassOfClass:[NSString class]]) {
if ([destinationType isSubclassOfClass:[NSDate class]]) {
// String -> Date
return [self parseDateFromString:(NSString*)value];
} else if ([destinationType isSubclassOfClass:[NSURL class]]) {
// String -> URL
return [NSURL URLWithString:(NSString*)value];
} else if ([destinationType isSubclassOfClass:[NSDecimalNumber class]]) {
// String -> Decimal Number
return [NSDecimalNumber decimalNumberWithString:(NSString*)value];
} else if ([destinationType isSubclassOfClass:[NSNumber class]]) {
// String -> Number
NSString* lowercasedString = [(NSString*)value lowercaseString];
NSSet* trueStrings = [NSSet setWithObjects:@”true”, @”t”, @”yes”, nil];
NSSet* booleanStrings = [trueStrings setByAddingObjectsFromSet:[NSSet setWithObjects:@”false”, @”f”, @”no”, nil]];
if ([booleanStrings containsObject:lowercasedString]) {
// Handle booleans encoded as Strings
return [NSNumber numberWithBool:[trueStrings containsObject:lowercasedString]];
} else {
return [NSNumber numberWithDouble:[(NSString*)value doubleValue]];
}
}
} else if (value == [NSNull null] || [value isEqual:[NSNull null]]) {
// Transform NSNull -> nil for simplicity
return nil;
} else if ([sourceType isSubclassOfClass:[NSSet class]]) {
// Set -> Array
if ([destinationType isSubclassOfClass:[NSArray class]]) {
return [(NSSet*)value allObjects];
}
} else if (orderedSetClass && [sourceType isSubclassOfClass:orderedSetClass]) {
// OrderedSet -> Array
if ([destinationType isSubclassOfClass:[NSArray class]]) {
return [value array];
}
} else if ([sourceType isSubclassOfClass:[NSArray class]]) {
// Array -> Set
if ([destinationType isSubclassOfClass:[NSSet class]]) {
return [NSSet setWithArray:value];
}
// Array -> OrderedSet
if (orderedSetClass && [destinationType isSubclassOfClass:orderedSetClass]) {
return [orderedSetClass orderedSetWithArray:value];
}
} else if ([sourceType isSubclassOfClass:[NSNumber class]] && [destinationType isSubclassOfClass:[NSDate class]]) {
// Number -> Date
if ([destinationType isSubclassOfClass:[NSDate class]]) {
return [NSDate dateWithTimeIntervalSince1970:[(NSNumber*)value intValue]];
} else if ([sourceType isSubclassOfClass:NSClassFromString(@”__NSCFBoolean”)] && [destinationType isSubclassOfClass:[NSString class]]) {
return ([value boolValue] ? @”true” : @”false”);
}
return [NSDate dateWithTimeIntervalSince1970:[(NSNumber*)value doubleValue]];
} else if ([sourceType isSubclassOfClass:[NSNumber class]] && [destinationType isSubclassOfClass:[NSDecimalNumber class]]) {
// Number -> Decimal Number
return [NSDecimalNumber decimalNumberWithDecimal:[value decimalValue]];
} else if ( ([sourceType isSubclassOfClass:NSClassFromString(@”__NSCFBoolean”)] ||
[sourceType isSubclassOfClass:NSClassFromString(@”NSCFBoolean”)] ) &&
[destinationType isSubclassOfClass:[NSString class]]) {
return ([value boolValue] ? @”true” : @”false”);
if ([destinationType isSubclassOfClass:[NSDate class]]) {
return [NSDate dateWithTimeIntervalSince1970:[(NSNumber*)value intValue]];
} else if (([sourceType isSubclassOfClass:NSClassFromString(@”__NSCFBoolean”)] || [sourceType isSubclassOfClass:NSClassFromString(@”NSCFBoolean”)]) && [destinationType isSubclassOfClass:[NSString class]]) {
return ([value boolValue] ? @”true” : @”false”);
}
} else if ([destinationType isSubclassOfClass:[NSString class]] && [value respondsToSelector:@selector(stringValue)]) {
return [value stringValue];
} else if ([destinationType isSubclassOfClass:[NSString class]] && [value isKindOfClass:[NSDate class]]) {
// NSDate -> NSString
// Transform using the preferred date formatter
NSString* dateString = nil;
@synchronized(self.objectMapping.preferredDateFormatter) {
dateString = [self.objectMapping.preferredDateFormatter stringForObjectValue:value];
}
return dateString;
}
RKLogWarning(@”Failed transformation of value at keyPath ‘%@’. No strategy for transforming from ‘%@’ to ‘%@'”, keyPath, NSStringFromClass([value class]), NSStringFromClass(destinationType));
return nil;
}
– (BOOL)isValue:(id)sourceValue equalToValue:(id)destinationValue {
return RKObjectIsValueEqualToValue(sourceValue, destinationValue);
}
– (BOOL)validateValue:(id *)value atKeyPath:(NSString*)keyPath {
BOOL success = YES;
if (self.objectMapping.performKeyValueValidation && [self.destinationObject respondsToSelector:@selector(validateValue:forKeyPath:error:)]) {
success = [self.destinationObject validateValue:value forKeyPath:keyPath error:&_validationError];
if (!success) {
if (_validationError) {
RKLogError(@”Validation failed while mapping attribute at key path ‘%@’ to value %@. Error: %@”, keyPath, *value, [_validationError localizedDescription]);
RKLogValidationError(_validationError);
} else {
RKLogWarning(@”Destination object %@ rejected attribute value %@ for keyPath %@. Skipping…”, self.destinationObject, *value, keyPath);
}
}
}
return success;
}
– (BOOL)shouldSetValue:(id *)value atKeyPath:(NSString*)keyPath {
id currentValue = [self.destinationObject valueForKeyPath:keyPath];
if (currentValue == [NSNull null] || [currentValue isEqual:[NSNull null]]) {
currentValue = nil;
}
/*
WTF – This workaround should not be necessary, but I have been unable to replicate
the circumstances that trigger it in a unit test to fix elsewhere. The proper place
to handle it is in transformValue:atKeyPath:toType:
See issue & pull request: https://github.com/RestKit/RestKit/pull/436
*/
if (*value == [NSNull null] || [*value isEqual:[NSNull null]]) {
RKLogWarning(@”Coercing NSNull value to nil in shouldSetValue:atKeyPath: — should be fixed.”);
*value = nil;
}
if (nil == currentValue && nil == *value) {
// Both are nil
return NO;
} else if (nil == *value || nil == currentValue) {
// One is nil and the other is not
return [self validateValue:value atKeyPath:keyPath];
}
if (! [self isValue:*value equalToValue:currentValue]) {
// Validate value for key
return [self validateValue:value atKeyPath:keyPath];
}
return NO;
}
– (NSArray*)applyNestingToMappings:(NSArray*)mappings {
if (_nestedAttributeSubstitution) {
NSString* searchString = [NSString stringWithFormat:@”(%@)”, [[_nestedAttributeSubstitution allKeys] lastObject]];
NSString* replacementString = [[_nestedAttributeSubstitution allValues] lastObject];
NSMutableArray* array = [NSMutableArray arrayWithCapacity:[self.objectMapping.attributeMappings count]];
for (RKObjectAttributeMapping* mapping in mappings) {
RKObjectAttributeMapping* nestedMapping = [mapping copy];
nestedMapping.sourceKeyPath = [nestedMapping.sourceKeyPath stringByReplacingOccurrencesOfString:searchString withString:replacementString];
nestedMapping.destinationKeyPath = [nestedMapping.destinationKeyPath stringByReplacingOccurrencesOfString:searchString withString:replacementString];
[array addObject:nestedMapping];
[nestedMapping release];
}
return array;
}
return mappings;
}
– (NSArray*)attributeMappings {
return [self applyNestingToMappings:self.objectMapping.attributeMappings];
}
– (NSArray*)relationshipMappings {
return [self applyNestingToMappings:self.objectMapping.relationshipMappings];
}
– (void)applyAttributeMapping:(RKObjectAttributeMapping*)attributeMapping withValue:(id)value {
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didFindMapping:forKeyPath:)]) {
[self.delegate objectMappingOperation:self didFindMapping:attributeMapping forKeyPath:attributeMapping.sourceKeyPath];
}
RKLogTrace(@”Mapping attribute value keyPath ‘%@’ to ‘%@'”, attributeMapping.sourceKeyPath, attributeMapping.destinationKeyPath);
// Inspect the property type to handle any value transformations
Class type = [self.objectMapping classForProperty:attributeMapping.destinationKeyPath];
if (type && NO == [[value class] isSubclassOfClass:type]) {
value = [self transformValue:value atKeyPath:attributeMapping.sourceKeyPath toType:type];
}
// Ensure that the value is different
if ([self shouldSetValue:&value atKeyPath:attributeMapping.destinationKeyPath]) {
RKLogTrace(@”Mapped attribute value from keyPath ‘%@’ to ‘%@’. Value: %@”, attributeMapping.sourceKeyPath, attributeMapping.destinationKeyPath, value);
[self.destinationObject setValue:value forKeyPath:attributeMapping.destinationKeyPath];
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didSetValue:forKeyPath:usingMapping:)]) {
[self.delegate objectMappingOperation:self didSetValue:value forKeyPath:attributeMapping.destinationKeyPath usingMapping:attributeMapping];
}
} else {
RKLogTrace(@”Skipped mapping of attribute value from keyPath ‘%@ to keyPath ‘%@’ — value is unchanged (%@)”, attributeMapping.sourceKeyPath, attributeMapping.destinationKeyPath, value);
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didNotSetUnchangedValue:forKeyPath:usingMapping:)]) {
[self.delegate objectMappingOperation:self didNotSetUnchangedValue:value forKeyPath:attributeMapping.destinationKeyPath usingMapping:attributeMapping];
}
}
}
// Return YES if we mapped any attributes
– (BOOL)applyAttributeMappings {
// If we have a nesting substitution value, we have alread
BOOL appliedMappings = (_nestedAttributeSubstitution != nil);
if (!self.objectMapping.performKeyValueValidation) {
RKLogDebug(@”Key-value validation is disabled for mapping, skipping…”);
}
for (RKObjectAttributeMapping* attributeMapping in [self attributeMappings]) {
if ([attributeMapping isMappingForKeyOfNestedDictionary]) {
RKLogTrace(@”Skipping attribute mapping for special keyPath ‘%@'”, attributeMapping.sourceKeyPath);
continue;
}
if (self.objectMapping.ignoreUnknownKeyPaths && ![self.sourceObject respondsToSelector:NSSelectorFromString(attributeMapping.sourceKeyPath)]) {
RKLogDebug(@”Source object is not key-value coding compliant for the keyPath ‘%@’, skipping…”, attributeMapping.sourceKeyPath);
continue;
}
id value = nil;
@try {
if ([attributeMapping.sourceKeyPath isEqualToString:@””]) {
value = self.sourceObject;
} else {
value = [self.sourceObject valueForKeyPath:attributeMapping.sourceKeyPath];
}
}
@catch (NSException *exception) {
if ([[exception name] isEqualToString:NSUndefinedKeyException] && self.objectMapping.ignoreUnknownKeyPaths) {
RKLogWarning(@”Encountered an undefined attribute mapping for keyPath ‘%@’ that generated NSUndefinedKeyException exception. Skipping due to objectMapping.ignoreUnknownKeyPaths = YES”,
attributeMapping.sourceKeyPath);
continue;
}
@throw;
}
if (value) {
appliedMappings = YES;
[self applyAttributeMapping:attributeMapping withValue:value];
} else {
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didNotFindMappingForKeyPath:)]) {
[self.delegate objectMappingOperation:self didNotFindMappingForKeyPath:attributeMapping.sourceKeyPath];
}
RKLogTrace(@”Did not find mappable attribute value keyPath ‘%@'”, attributeMapping.sourceKeyPath);
// Optionally set the default value for missing values
if ([self.objectMapping shouldSetDefaultValueForMissingAttributes]) {
[self.destinationObject setValue:[self.objectMapping defaultValueForMissingAttribute:attributeMapping.destinationKeyPath]
forKeyPath:attributeMapping.destinationKeyPath];
RKLogTrace(@”Setting nil for missing attribute value at keyPath ‘%@'”, attributeMapping.sourceKeyPath);
}
}
// Fail out if an error has occurred
if (_validationError) {
return NO;
}
}
return appliedMappings;
}
– (BOOL)isTypeACollection:(Class)type {
Class orderedSetClass = NSClassFromString(@”NSOrderedSet”);
return (type && ([type isSubclassOfClass:[NSSet class]] ||
[type isSubclassOfClass:[NSArray class]] ||
(orderedSetClass && [type isSubclassOfClass:orderedSetClass])));
}
– (BOOL)isValueACollection:(id)value {
return [self isTypeACollection:[value class]];
}
– (BOOL)mapNestedObject:(id)anObject toObject:(id)anotherObject withRealtionshipMapping:(RKObjectRelationshipMapping*)relationshipMapping {
NSAssert(anObject, @”Cannot map nested object without a nested source object”);
NSAssert(anotherObject, @”Cannot map nested object without a destination object”);
NSAssert(relationshipMapping, @”Cannot map a nested object relationship without a relationship mapping”);
NSError* error = nil;
RKLogTrace(@”Performing nested object mapping using mapping %@ for data: %@”, relationshipMapping, anObject);
RKObjectMappingOperation* subOperation = [RKObjectMappingOperation mappingOperationFromObject:anObject toObject:anotherObject withMapping:relationshipMapping.mapping];
subOperation.delegate = self.delegate;
subOperation.queue = self.queue;
if (NO == [subOperation performMapping:&error]) {
RKLogWarning(@”WARNING: Failed mapping nested object: %@”, [error localizedDescription]);
}
return YES;
}
– (BOOL)applyRelationshipMappings {
BOOL appliedMappings = NO;
id destinationObject = nil;
for (RKObjectRelationshipMapping* relationshipMapping in [self relationshipMappings]) {
id value = nil;
@try {
value = [self.sourceObject valueForKeyPath:relationshipMapping.sourceKeyPath];
}
@catch (NSException *exception) {
if ([[exception name] isEqualToString:NSUndefinedKeyException] && self.objectMapping.ignoreUnknownKeyPaths) {
RKLogWarning(@”Encountered an undefined relationship mapping for keyPath ‘%@’ that generated NSUndefinedKeyException exception. Skipping due to objectMapping.ignoreUnknownKeyPaths = YES”,
relationshipMapping.sourceKeyPath);
continue;
}
@throw;
}
if (value == nil || value == [NSNull null] || [value isEqual:[NSNull null]]) {
RKLogDebug(@”Did not find mappable relationship value keyPath ‘%@'”, relationshipMapping.sourceKeyPath);
// Optionally nil out the property
id nilReference = nil;
if ([self.objectMapping setNilForMissingRelationships] && [self shouldSetValue:&nilReference atKeyPath:relationshipMapping.destinationKeyPath]) {
RKLogTrace(@”Setting nil for missing relationship value at keyPath ‘%@'”, relationshipMapping.sourceKeyPath);
[self.destinationObject setValue:nil forKeyPath:relationshipMapping.destinationKeyPath];
}
continue;
}
// Handle case where incoming content is collection represented by a dictionary
if (relationshipMapping.mapping.forceCollectionMapping) {
// If we have forced mapping of a dictionary, map each subdictionary
if ([value isKindOfClass:[NSDictionary class]]) {
RKLogDebug(@”Collection mapping forced for NSDictionary, mapping each key/value independently…”);
NSArray* objectsToMap = [NSMutableArray arrayWithCapacity:[value count]];
for (id key in value) {
NSDictionary* dictionaryToMap = [NSDictionary dictionaryWithObject:[value valueForKey:key] forKey:key];
[(NSMutableArray*)objectsToMap addObject:dictionaryToMap];
}
value = objectsToMap;
} else {
RKLogWarning(@”Collection mapping forced but mappable objects is of type ‘%@’ rather than NSDictionary”, NSStringFromClass([value class]));
}
}
// Handle case where incoming content is a single object, but we want a collection
Class relationshipType = [self.objectMapping classForProperty:relationshipMapping.destinationKeyPath];
BOOL mappingToCollection = [self isTypeACollection:relationshipType];
if (mappingToCollection && ![self isValueACollection:value]) {
Class orderedSetClass = NSClassFromString(@”NSOrderedSet”);
RKLogDebug(@”Asked to map a single object into a collection relationship. Transforming to an instance of: %@”, NSStringFromClass(relationshipType));
if ([relationshipType isSubclassOfClass:[NSArray class]]) {
value = [relationshipType arrayWithObject:value];
} else if ([relationshipType isSubclassOfClass:[NSSet class]]) {
value = [relationshipType setWithObject:value];
} else if (orderedSetClass && [relationshipType isSubclassOfClass:orderedSetClass]) {
value = [relationshipType orderedSetWithObject:value];
} else {
RKLogWarning(@”Failed to transform single object”);
}
}
if ([self isValueACollection:value]) {
// One to many relationship
RKLogDebug(@”Mapping one to many relationship value at keyPath ‘%@’ to ‘%@'”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath);
appliedMappings = YES;
destinationObject = [NSMutableArray arrayWithCapacity:[value count]];
id collectionSanityCheckObject = nil;
if ([value respondsToSelector:@selector(anyObject)]) collectionSanityCheckObject = [value anyObject];
if ([value respondsToSelector:@selector(lastObject)]) collectionSanityCheckObject = [value lastObject];
if ([self isValueACollection:collectionSanityCheckObject]) {
RKLogWarning(@”WARNING: Detected a relationship mapping for a collection containing another collection. This is probably not what you want. Consider using a KVC collection operator (such as @unionOfArrays) to flatten your mappable collection.”);
RKLogWarning(@”Key path ‘%@’ yielded collection containing another collection rather than a collection of objects: %@”, relationshipMapping.sourceKeyPath, value);
}
for (id nestedObject in value) {
RKObjectMappingDefinition * mapping = relationshipMapping.mapping;
RKObjectMapping* objectMapping = nil;
if ([mapping isKindOfClass:[RKDynamicObjectMapping class]]) {
objectMapping = [(RKDynamicObjectMapping*)mapping objectMappingForDictionary:nestedObject];
if (! objectMapping) {
RKLogDebug(@”Mapping %@ declined mapping for data %@: returned nil objectMapping”, mapping, nestedObject);
continue;
}
} else if ([mapping isKindOfClass:[RKObjectMapping class]]) {
objectMapping = (RKObjectMapping*)mapping;
} else {
NSAssert(objectMapping, @”Encountered unknown mapping type ‘%@'”, NSStringFromClass([mapping class]));
}
id mappedObject = [objectMapping mappableObjectForData:nestedObject];
if ([self mapNestedObject:nestedObject toObject:mappedObject withRealtionshipMapping:relationshipMapping]) {
[destinationObject addObject:mappedObject];
}
}
// Transform from NSSet <-> NSArray if necessary
Class type = [self.objectMapping classForProperty:relationshipMapping.destinationKeyPath];
if (type && NO == [[destinationObject class] isSubclassOfClass:type]) {
destinationObject = [self transformValue:destinationObject atKeyPath:relationshipMapping.sourceKeyPath toType:type];
}
// If the relationship has changed, set it
if ([self shouldSetValue:&destinationObject atKeyPath:relationshipMapping.destinationKeyPath]) {
Class managedObjectClass = NSClassFromString(@”NSManagedObject”);
Class nsOrderedSetClass = NSClassFromString(@”NSOrderedSet”);
if (managedObjectClass && [self.destinationObject isKindOfClass:managedObjectClass]) {
RKLogTrace(@”Found a managedObject collection. About to apply value via mutable[Set|Array]ValueForKey”);
if ([destinationObject isKindOfClass:[NSSet class]]) {
RKLogTrace(@”Mapped NSSet relationship object from keyPath ‘%@’ to ‘%@’. Value: %@”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
NSMutableSet* destinationSet = [self.destinationObject mutableSetValueForKey:relationshipMapping.destinationKeyPath];
[destinationSet setSet:destinationObject];
} else if ([destinationObject isKindOfClass:[NSArray class]]) {
RKLogTrace(@”Mapped NSArray relationship object from keyPath ‘%@’ to ‘%@’. Value: %@”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
NSMutableArray* destinationArray = [self.destinationObject mutableArrayValueForKey:relationshipMapping.destinationKeyPath];
[destinationArray setArray:destinationObject];
} else if (nsOrderedSetClass && [destinationObject isKindOfClass:nsOrderedSetClass]) {
RKLogTrace(@”Mapped NSOrderedSet relationship object from keyPath ‘%@’ to ‘%@’. Value: %@”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
[self.destinationObject setValue:destinationObject forKey:relationshipMapping.destinationKeyPath];
}
} else {
RKLogTrace(@”Mapped relationship object from keyPath ‘%@’ to ‘%@’. Value: %@”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
[self.destinationObject setValue:destinationObject forKeyPath:relationshipMapping.destinationKeyPath];
}
} else {
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didNotSetUnchangedValue:forKeyPath:usingMapping:)]) {
[self.delegate objectMappingOperation:self didNotSetUnchangedValue:destinationObject forKeyPath:relationshipMapping.destinationKeyPath usingMapping:relationshipMapping];
}
}
} else {
// One to one relationship
RKLogDebug(@”Mapping one to one relationship value at keyPath ‘%@’ to ‘%@'”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath);
RKObjectMappingDefinition * mapping = relationshipMapping.mapping;
RKObjectMapping* objectMapping = nil;
if ([mapping isKindOfClass:[RKDynamicObjectMapping class]]) {
objectMapping = [(RKDynamicObjectMapping*)mapping objectMappingForDictionary:value];
} else if ([mapping isKindOfClass:[RKObjectMapping class]]) {
objectMapping = (RKObjectMapping*)mapping;
}
NSAssert(objectMapping, @”Encountered unknown mapping type ‘%@'”, NSStringFromClass([mapping class]));
destinationObject = [objectMapping mappableObjectForData:value];
if ([self mapNestedObject:value toObject:destinationObject withRealtionshipMapping:relationshipMapping]) {
appliedMappings = YES;
}
// If the relationship has changed, set it
if ([self shouldSetValue:&destinationObject atKeyPath:relationshipMapping.destinationKeyPath]) {
appliedMappings = YES;
RKLogTrace(@”Mapped relationship object from keyPath ‘%@’ to ‘%@’. Value: %@”, relationshipMapping.sourceKeyPath, relationshipMapping.destinationKeyPath, destinationObject);
[self.destinationObject setValue:destinationObject forKey:relationshipMapping.destinationKeyPath];
} else {
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didNotSetUnchangedValue:forKeyPath:usingMapping:)]) {
[self.delegate objectMappingOperation:self didNotSetUnchangedValue:destinationObject forKeyPath:relationshipMapping.destinationKeyPath usingMapping:relationshipMapping];
}
}
}
// Notify the delegate
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didSetValue:forKeyPath:usingMapping:)]) {
[self.delegate objectMappingOperation:self didSetValue:destinationObject forKeyPath:relationshipMapping.destinationKeyPath usingMapping:relationshipMapping];
}
// Fail out if a validation error has occurred
if (_validationError) {
return NO;
}
}
return appliedMappings;
}
– (void)applyNestedMappings {
RKObjectAttributeMapping* attributeMapping = [self.objectMapping attributeMappingForKeyOfNestedDictionary];
if (attributeMapping) {
RKLogDebug(@”Found nested mapping definition to attribute ‘%@'”, attributeMapping.destinationKeyPath);
id attributeValue = [[self.sourceObject allKeys] lastObject];
if (attributeValue) {
RKLogDebug(@”Found nesting value of ‘%@’ for attribute ‘%@'”, attributeValue, attributeMapping.destinationKeyPath);
_nestedAttributeSubstitution = [[NSDictionary alloc] initWithObjectsAndKeys:attributeValue, attributeMapping.destinationKeyPath, nil];
[self applyAttributeMapping:attributeMapping withValue:attributeValue];
} else {
RKLogWarning(@”Unable to find nesting value for attribute ‘%@'”, attributeMapping.destinationKeyPath);
}
}
}
– (BOOL)performMapping:(NSError**)error {
RKLogDebug(@”Starting mapping operation…”);
RKLogTrace(@”Performing mapping operation: %@”, self);
[self applyNestedMappings];
BOOL mappedAttributes = [self applyAttributeMappings];
BOOL mappedRelationships = [self applyRelationshipMappings];
if ((mappedAttributes || mappedRelationships) && _validationError == nil) {
RKLogDebug(@”Finished mapping operation successfully…”);
return YES;
}
if (_validationError) {
// We failed out due to validation
if (error) *error = _validationError;
if ([self.delegate respondsToSelector:@selector(objectMappingOperation:didFailWithError:)]) {
[self.delegate objectMappingOperation:self didFailWithError:_validationError];
}
RKLogError(@”Failed mapping operation: %@”, [_validationError localizedDescription]);
} else {
// We did not find anything to do
RKLogDebug(@”Mapping operation did not find any mappable content”);
}
return NO;
}
– (NSString*)description {
return [NSString stringWithFormat:@”RKObjectMappingOperation for ‘%@’ object. Mapping values from object %@ to object %@ with object mapping %@”,
NSStringFromClass([self.destinationObject class]), self.sourceObject, self.destinationObject, self.objectMapping];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingOperation.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingProvider+Contexts.h
//
// RKObjectMappingProvider.m
// RestKit
//
// Created by Blake Watters on 1/17/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingProvider.h”
// Contexts provide primitives for managing collections of object mappings namespaced
// within a single mapping provider. This enables easy reuse and extension via categories.
@interface RKObjectMappingProvider (Contexts)
– (void)initializeContext:(RKObjectMappingProviderContext)context withValue:(id)value;
– (id)valueForContext:(RKObjectMappingProviderContext)context;
– (void)setValue:(id)value forContext:(RKObjectMappingProviderContext)context;
– (RKObjectMappingDefinition *)mappingForContext:(RKObjectMappingProviderContext)context;
/**
Stores a single object mapping for a given context. Useful when a component needs to enable
configuration via one (and only one) object mapping.
*/
– (void)setMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context;
– (NSArray *)mappingsForContext:(RKObjectMappingProviderContext)context;
– (void)addMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context;
– (void)removeMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context;
– (RKObjectMappingDefinition *)mappingForKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context;
– (void)setMapping:(RKObjectMappingDefinition *)mapping forKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context;
– (void)removeMappingForKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context;
– (void)setMapping:(RKObjectMappingDefinition *)mapping forPattern:(NSString *)pattern atIndex:(NSUInteger)index context:(RKObjectMappingProviderContext)context;
– (void)setMapping:(RKObjectMappingDefinition *)mapping forPattern:(NSString *)pattern context:(RKObjectMappingProviderContext)context;
– (RKObjectMappingDefinition *)mappingForPatternMatchingString:(NSString *)string context:(RKObjectMappingProviderContext)context;
– (void)setEntry:(RKObjectMappingProviderContextEntry *)entry forPattern:(NSString *)pattern context:(RKObjectMappingProviderContext)context;
– (RKObjectMappingProviderContextEntry *)entryForPatternMatchingString:(NSString *)string context:(RKObjectMappingProviderContext)context;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingProvider+Contexts.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingProvider.h
//
// RKObjectMappingProvider.h
// RestKit
//
// Created by Jeremy Ellison on 5/6/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMapping.h”
#import “RKDynamicObjectMapping.h”
#import “RKObjectMappingProviderContextEntry.h”
// Internal framework contexts
// @see RKObjectMappingProvider+Contexts.h
typedef enum {
RKObjectMappingProviderContextObjectsByKeyPath = 1000,
RKObjectMappingProviderContextObjectsByType,
RKObjectMappingProviderContextObjectsByResourcePathPattern,
RKObjectMappingProviderContextSerialization,
RKObjectMappingProviderContextErrors,
RKObjectMappingProviderContextPagination
} RKObjectMappingProviderContext;
/**
The mapping provider is a repository of registered object mappings for use by instances
of RKObjectManager and RKObjectMapper. It provides for the storage and retrieval of object
mappings by keyPath and type.
The mapping provider is responsible for:
1. Providing instances of RKObjectMapper with keyPaths and object mappings for use
when attempting to map a parsed payload into objects. Each keyPath is examined using
valueForKeyPath: to determine if any mappable data exists within the payload. If data is
found, the RKObjectMapper will instantiate an RKObjectMappingOperation to perform the mapping
using the RKObjectMapping or RKDynamicObjectMapping associated with the keyPath.
1. Providing the appropriate serialization mapping to instances of RKObjectManager when an object
is to be sent to the remote server using [RKObjectManager postObject:delegate:] or
[RKObjectManager postObject:delegate]. This mapping is used to serialize the object into a
format suitable for encoding into a URL form encoded or JSON representation.
1. Providing convenient storage of RKObjectMapping references for users who are not using keyPath
based mapping. Mappings can be added to the provider and retrieved by the [RKObjectMapping objectClass]
that they target.
*/
@interface RKObjectMappingProvider : NSObject {
NSMutableDictionary *mappingContexts;
}
/**
Creates and returns an autoreleased RKObjectMappingProvider instance.
@return A new autoreleased object mapping provider instance.
*/
+ (id)mappingProvider;
/**
Instantiate and return a new auto-released object mapping provider after
yielding it to the specified block for configuration
*/
+ (id)mappingProviderUsingBlock:(void (^)(RKObjectMappingProvider *))block;
/**
Configures the mapping provider to use the RKObjectMapping or RKDynamicObjectMapping provided when
content is encountered at the specified keyPath.
When an RKObjectMapper is performing its work, each registered keyPath within the mapping provider will
be searched for content in the parsed payload. If mappable content is found, the object mapping configured
for the keyPath will be used to perform an RKObjectMappingOperation.
@param objectOrDynamicMapping An RKObjectMapping or RKDynamicObjectMapping to register for keyPath based mapping.
@param keyPath The keyPath to register the mapping as being responsible for mapping.
@see RKObjectMapper
@see RKObjectMappingOperation
*/
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping forKeyPath:(NSString *)keyPath;
/**
Returns the RKObjectMapping or RKObjectDynamic mapping configured for use
when mappable content is encountered at keyPath
@param keyPath A registered keyPath to retrieve the object mapping for
@return The RKObjectMapping or RKDynamicObjectMapping for the specified keyPath or nil if none is registered.
*/
– (RKObjectMappingDefinition *)objectMappingForKeyPath:(NSString *)keyPath;
/**
Removes the RKObjectMapping or RKDynamicObjectMapping registered at the specified keyPath
from the provider.
@param keyPath The keyPath to remove the corresponding mapping for
*/
– (void)removeObjectMappingForKeyPath:(NSString *)keyPath;
/**
Returns a dictionary where the keys are mappable keyPaths and the values are the RKObjectMapping
or RKDynamicObjectMapping to use for mappable data that appears at the keyPath.
@warning The returned dictionary can contain RKDynamicObjectMapping instances. Check the type if
you are using dynamic mapping.
@return A dictionary of all registered keyPaths and their corresponding object mapping instances
*/
– (NSDictionary *)objectMappingsByKeyPath;
/**
Registers an object mapping as being rooted at a specific keyPath. The keyPath will be registered
and an inverse mapping for the object will be generated and used for serialization.
This is a shortcut for configuring a pair of object mappings that model a simple resource the same
way when going to and from the server.
For example, if we have a simple resource called ‘person’ that returns JSON in the following
format:
{ “person”: { “first_name”: “Blake”, “last_name”: “Watters” } }
We might configure a mapping like so:
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[Person class]];
[mapping mapAttributes:@”first_name”, @”last_name”, nil];
If we want to parse the above JSON and serialize it such that using postObject: or putObject: use the same format,
we can auto-generate the serialization mapping and set the whole thing up in one shot:
[[RKObjectManager sharedManager].mappingProvider registerMapping:mapping withRootKeyPath:@”person”];
This will call setMapping:forKeyPath: for you, then generate a serialization mapping and set the root
keyPath as well.
If you want to manipulate the serialization mapping yourself, you can work with the mapping directly:
RKObjectMapping* serializationMappingForPerson = [personMapping inverseMapping];
// NOTE: Serialization mapping default to a nil root keyPath and will serialize to a flat dictionary
[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:serializationMappingForPerson forClass:[Person class]];
@param objectMapping An object mapping we wish to register on the provider
@param keyPath The keyPath we wish to register for the mapping and use as the rootKeyPath for serialization
*/
– (void)registerObjectMapping:(RKObjectMapping *)objectMapping withRootKeyPath:(NSString *)keyPath;
/**
Adds an object mapping to the provider for later retrieval. The mapping is not bound to a particular keyPath and
must be explicitly set on an instance of RKObjectLoader or RKObjectMappingOperation to be applied. This is useful
in cases where the remote system does not namespace resources in a keyPath that can be used for disambiguation.
You can retrieve mappings added to the provider by invoking objectMappingsForClass: and objectMappingForClass:
@param objectMapping An object mapping instance we wish to register with the provider.
@see objectMappingsForClass:
@see objectMappingForClass:
*/
– (void)addObjectMapping:(RKObjectMapping *)objectMapping;
/**
Returns all object mappings registered for a particular class on the provider. The collection of mappings is assembled
by searching for all mappings added via addObjctMapping: and then consulting those registered via objectMappingForKeyPath:
@param objectClass The class we want to retrieve the mappings for
@return An array of all object mappings matching the objectClass. Can be empty.
*/
– (NSArray *)objectMappingsForClass:(Class)objectClass;
/**
Returns the first object mapping for a objectClass registered in the provider.
The objectClass is the class for a model you use to represent data retrieved in
XML or JSON format. For example, if we were developing a Twitter application we
might have an objectClass of RKTweet for storing Tweet data. We could retrieve
the object mapping for this model by invoking
`[mappingProvider objectMappingForClass:[RKTweet class]];`
Mappings registered via addObjectMapping: take precedence over those registered
via setObjectMapping:forKeyPath:.
@param objectClass The class that we want to return mappings for
@return An RKObjectMapping matching objectClass or nil
*/
– (RKObjectMapping *)objectMappingForClass:(Class)objectClass;
/**
Registers an object mapping for use when serializing instances of objectClass for transport
over HTTP. Used by the object manager during postObject: and putObject:.
Serialization mappings are simply instances of RKObjectMapping that target NSMutableDictionary
as the target object class. After the object is mapped into an NSMutableDictionary, it can be
encoded to form encoded string, JSON, XML, etc.
@param objectMapping The serialization mapping to register for use when serializing objectClass
@param objectClass The class of the object type we are registering a serialization for
@see [RKObjectMapping serializationMapping]
*/
– (void)setSerializationMapping:(RKObjectMapping *)objectMapping forClass:(Class)objectClass;
/**
Returns the serialization mapping for a specific object class
which has been previously registered.
@param objectClass The class we wish to obtain the serialization mapping for
@return The RKObjectMapping instance used for mapping instances of objectClass for transport
@see setSerializationMapping:forClass:
*/
– (RKObjectMapping *)serializationMappingForClass:(Class)objectClass;
/**
Configures an object mapping to be used when during a load event where the resourcePath of
the RKObjectLoader instance matches resourcePathPattern.
The resourcePathPattern is a SOCKit pattern matching property names preceded by colons within
a path. For example, if a collection of reviews for a product were loaded from a remote system
at the resourcePath @”/products/1234/reviews”, object mapping could be configured to handle
this request with a resourcePathPattern of @”/products/:productID/reviews”.
**NOTE** that care must be taken when configuring patterns within the provider. The patterns
will be evaluated in the order they are added to the provider, so more specific patterns must
precede more general patterns where either would generate a match.
@param objectMapping The object mapping to use when the resourcePath matches the specified
resourcePathPattern.
@param resourcePathPattern A pattern to be evaluated using an RKPathMatcher against a resourcePath
to determine if objectMapping is the appropriate mapping.
@see RKPathMatcher
@see RKURL
@see RKObjectLoader
*/
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectMapping forResourcePathPattern:(NSString *)resourcePathPattern;
/**
Returns the first objectMapping configured in the provider with a resourcePathPattern matching
the specified resourcePath.
@param resourcePath A resource path to retrieve the first RKObjectMapping or RKDynamicObjectMapping
configured with a matching pattern.
@return An RKObjectMapping or RKDynamicObjectMapping for a resource path pattern matching resourcePath
or nil if no match was found.
*/
– (RKObjectMappingDefinition *)objectMappingForResourcePath:(NSString *)resourcePath;
– (void)setEntry:(RKObjectMappingProviderContextEntry *)entry forResourcePathPattern:(NSString *)resourcePath;
– (RKObjectMappingProviderContextEntry *)entryForResourcePath:(NSString *)resourcePath;
/**
An object mapping used when the remote system returns an error status code
and a payload with a MIME Type that RestKit is capable of parsing.
@see RKObjectLoader
@see RKParserRegistry
*/
@property (nonatomic, retain) RKObjectMapping *errorMapping;
/**
An object mapping used when mapping pagination metadata (current page, object count, etc)
during a paginated object loading operation. The objectClass of the paginationMapping must
be RKObjectPaginator.
For example, if using the popular will_paginate plugin with Ruby on Rails, we would configure
our pagination mapping like so:
// Assumes the JSON format of http://stackoverflow.com/questions/4699182/will-paginate-json-support
RKObjectMapping *paginationMapping = [RKObjectMapping mappingForClass:[RKObjectPaginator class]];
[paginationMapping mapKeyPath:@”current_page” toAttribute:@”currentPage”];
[paginationMapping mapKeyPath:@”per_page” toAttribute:@”perPage”];
[paginationMapping mapKeyPath:@”total_entries” toAttribute:@”objectCount”];
@see RKObjectPaginator
*/
@property (nonatomic, retain) RKObjectMapping *paginationMapping;
@end
// Method signatures being phased out
@interface RKObjectMappingProvider (CompatibilityAliases)
+ (RKObjectMappingProvider *)objectMappingProvider;
– (void)registerMapping:(RKObjectMapping *)objectMapping withRootKeyPath:(NSString *)keyPath;
– (void)setMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping forKeyPath:(NSString *)keyPath;
– (RKObjectMappingDefinition *)mappingForKeyPath:(NSString *)keyPath;
– (NSDictionary *)mappingsByKeyPath;
– (void)removeMappingForKeyPath:(NSString *)keyPath;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingProvider.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingProvider.m
//
// RKObjectMappingProvider.m
// RestKit
//
// Created by Jeremy Ellison on 5/6/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingProvider.h”
#import “RKObjectMappingProvider+Contexts.h”
#import “RKOrderedDictionary.h”
#import “RKPathMatcher.h”
#import “RKObjectMappingProviderContextEntry.h”
@implementation RKObjectMappingProvider
+ (RKObjectMappingProvider *)mappingProvider {
return [[self new] autorelease];
}
+ (RKObjectMappingProvider *)mappingProviderUsingBlock:(void (^)(RKObjectMappingProvider *mappingProvider))block {
RKObjectMappingProvider* mappingProvider = [self mappingProvider];
block(mappingProvider);
return mappingProvider;
}
– (id)init {
self = [super init];
if (self) {
mappingContexts = [NSMutableDictionary new];
[self initializeContext:RKObjectMappingProviderContextObjectsByKeyPath withValue:[NSMutableDictionary dictionary]];
[self initializeContext:RKObjectMappingProviderContextObjectsByType withValue:[NSMutableArray array]];
[self initializeContext:RKObjectMappingProviderContextObjectsByResourcePathPattern withValue:[RKOrderedDictionary dictionary]];
[self initializeContext:RKObjectMappingProviderContextSerialization withValue:[NSMutableDictionary dictionary]];
[self initializeContext:RKObjectMappingProviderContextErrors withValue:[NSNull null]];
}
return self;
}
– (void)dealloc {
[mappingContexts release];
[super dealloc];
}
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping forKeyPath:(NSString *)keyPath {
[self setMapping:objectOrDynamicMapping forKeyPath:keyPath context:RKObjectMappingProviderContextObjectsByKeyPath];
}
– (void)removeObjectMappingForKeyPath:(NSString *)keyPath {
[self removeMappingForKeyPath:keyPath context:RKObjectMappingProviderContextObjectsByKeyPath];
}
– (RKObjectMappingDefinition *)objectMappingForKeyPath:(NSString *)keyPath {
return [self mappingForKeyPath:keyPath context:RKObjectMappingProviderContextObjectsByKeyPath];
}
– (void)setSerializationMapping:(RKObjectMapping *)mapping forClass:(Class)objectClass {
[self setMapping:mapping forKeyPath:NSStringFromClass(objectClass) context:RKObjectMappingProviderContextSerialization];
}
– (RKObjectMapping *)serializationMappingForClass:(Class)objectClass {
return (RKObjectMapping *) [self mappingForKeyPath:NSStringFromClass(objectClass) context:RKObjectMappingProviderContextSerialization];
}
– (NSDictionary*)objectMappingsByKeyPath {
return [NSDictionary dictionaryWithDictionary:(NSDictionary *) [self valueForContext:RKObjectMappingProviderContextObjectsByKeyPath]];
}
– (void)registerObjectMapping:(RKObjectMapping *)objectMapping withRootKeyPath:(NSString *)keyPath {
// TODO: Should generate logs
objectMapping.rootKeyPath = keyPath;
[self setMapping:objectMapping forKeyPath:keyPath];
RKObjectMapping* inverseMapping = [objectMapping inverseMapping];
inverseMapping.rootKeyPath = keyPath;
[self setSerializationMapping:inverseMapping forClass:objectMapping.objectClass];
}
– (void)addObjectMapping:(RKObjectMapping *)objectMapping {
[self addMapping:objectMapping context:RKObjectMappingProviderContextObjectsByType];
}
– (NSArray *)objectMappingsForClass:(Class)theClass {
NSMutableArray *mappings = [NSMutableArray array];
NSArray *mappingByType = [self valueForContext:RKObjectMappingProviderContextObjectsByType];
NSArray *mappingByKeyPath = [[self valueForContext:RKObjectMappingProviderContextObjectsByKeyPath] allValues];
NSArray *mappingsToSearch = [[NSArray arrayWithArray:mappingByType] arrayByAddingObjectsFromArray:mappingByKeyPath];
for (RKObjectMappingDefinition *candidateMapping in mappingsToSearch) {
if ( ![candidateMapping respondsToSelector:@selector(objectClass)] || [mappings containsObject:candidateMapping])
continue;
Class mappedClass = [candidateMapping performSelector:@selector(objectClass)];
if (mappedClass && [NSStringFromClass(mappedClass) isEqualToString:NSStringFromClass(theClass)]) {
[mappings addObject:candidateMapping];
}
}
return [NSArray arrayWithArray:mappings];
}
– (RKObjectMapping *)objectMappingForClass:(Class)theClass {
NSArray* objectMappings = [self objectMappingsForClass:theClass];
return ([objectMappings count] > 0) ? [objectMappings objectAtIndex:0] : nil;
}
#pragma mark – Error Mappings
– (RKObjectMapping *)errorMapping {
return (RKObjectMapping *) [self mappingForContext:RKObjectMappingProviderContextErrors];
}
– (void)setErrorMapping:(RKObjectMapping *)errorMapping {
if (errorMapping) {
[self setMapping:errorMapping context:RKObjectMappingProviderContextErrors];
}
}
#pragma mark – Pagination Mapping
– (RKObjectMapping *)paginationMapping {
return (RKObjectMapping *) [self mappingForContext:RKObjectMappingProviderContextPagination];
}
– (void)setPaginationMapping:(RKObjectMapping *)paginationMapping {
[self setMapping:paginationMapping context:RKObjectMappingProviderContextPagination];
}
– (void)setObjectMapping:(RKObjectMappingDefinition *)objectMapping forResourcePathPattern:(NSString *)resourcePath {
[self setMapping:objectMapping forPattern:resourcePath context:RKObjectMappingProviderContextObjectsByResourcePathPattern];
}
– (RKObjectMappingDefinition *)objectMappingForResourcePath:(NSString *)resourcePath {
return [self mappingForPatternMatchingString:resourcePath context:RKObjectMappingProviderContextObjectsByResourcePathPattern];
}
– (void)setEntry:(RKObjectMappingProviderContextEntry *)entry forResourcePathPattern:(NSString *)resourcePath {
[self setEntry:entry forPattern:resourcePath context:RKObjectMappingProviderContextObjectsByResourcePathPattern];
}
– (RKObjectMappingProviderContextEntry *)entryForResourcePath:(NSString *)resourcePath {
return [self entryForPatternMatchingString:resourcePath context:RKObjectMappingProviderContextObjectsByResourcePathPattern];
}
#pragma mark – Mapping Context Primitives
– (void)initializeContext:(RKObjectMappingProviderContext)context withValue:(id)value {
NSAssert([self valueForContext:context] == nil, @”Attempt to reinitialized an existing mapping provider context.”);
[self setValue:value forContext:context];
}
– (id)valueForContext:(RKObjectMappingProviderContext)context {
NSNumber *contextNumber = [NSNumber numberWithInteger:context];
return [mappingContexts objectForKey:contextNumber];
}
– (void)setValue:(id)value forContext:(RKObjectMappingProviderContext)context {
NSNumber *contextNumber = [NSNumber numberWithInteger:context];
[mappingContexts setObject:value forKey:contextNumber];
}
– (void)assertStorageForContext:(RKObjectMappingProviderContext)context isKindOfClass:(Class)theClass {
id contextValue = [self valueForContext:context];
NSAssert([contextValue isKindOfClass:theClass], @”Storage type mismatch for context %d: expected a %@, got %@.”, context, theClass, [contextValue class]);
}
– (void)setMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context {
NSNumber *contextNumber = [NSNumber numberWithInteger:context];
[mappingContexts setObject:mapping forKey:contextNumber];
}
– (RKObjectMappingDefinition *)mappingForContext:(RKObjectMappingProviderContext)context {
id contextValue = [self valueForContext:context];
if ([contextValue isEqual:[NSNull null]]) return nil;
Class class = [RKObjectMappingDefinition class];
NSAssert([contextValue isKindOfClass:class], @”Storage type mismatch for context %d: expected a %@, got %@.”, context, class, [contextValue class]);
return contextValue;
}
– (NSArray *)mappingsForContext:(RKObjectMappingProviderContext)context {
id contextValue = [self valueForContext:context];
if (contextValue == nil) return [NSArray array];
[self assertStorageForContext:context isKindOfClass:[NSArray class]];
return [NSArray arrayWithArray:contextValue];
}
– (void)addMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context {
NSMutableArray *contextValue = [self valueForContext:context];
if (contextValue == nil) {
contextValue = [NSMutableArray arrayWithCapacity:1];
[self setValue:contextValue forContext:context];
}
[self assertStorageForContext:context isKindOfClass:[NSArray class]];
[contextValue addObject:mapping];
}
– (void)removeMapping:(RKObjectMappingDefinition *)mapping context:(RKObjectMappingProviderContext)context {
NSMutableArray *contextValue = [self valueForContext:context];
NSAssert(contextValue, @”Attempted to remove mapping from undefined context: %d”, context);
[self assertStorageForContext:context isKindOfClass:[NSArray class]];
NSAssert([contextValue containsObject:mapping], @”Attempted to remove mapping from collection that does not include it for context: %d”, context);
[contextValue removeObject:mapping];
}
– (RKObjectMappingDefinition *)mappingForKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context {
NSMutableDictionary *contextValue = [self valueForContext:context];
NSAssert(contextValue, @”Attempted to retrieve mapping from undefined context: %d”, context);
[self assertStorageForContext:context isKindOfClass:[NSDictionary class]];
return [contextValue valueForKey:keyPath];
}
– (void)setMapping:(RKObjectMappingDefinition *)mapping forKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context {
NSMutableDictionary *contextValue = [self valueForContext:context];
if (contextValue == nil) {
contextValue = [NSMutableDictionary dictionary];
[self setValue:contextValue forContext:context];
}
[self assertStorageForContext:context isKindOfClass:[NSDictionary class]];
[contextValue setValue:mapping forKey:keyPath];
}
– (void)removeMappingForKeyPath:(NSString *)keyPath context:(RKObjectMappingProviderContext)context {
NSMutableDictionary *contextValue = [self valueForContext:context];
[self assertStorageForContext:context isKindOfClass:[NSDictionary class]];
[contextValue removeObjectForKey:keyPath];
}
– (void)setMapping:(RKObjectMappingDefinition *)mapping forPattern:(NSString *)pattern atIndex:(NSUInteger)index context:(RKObjectMappingProviderContext)context {
RKOrderedDictionary *contextValue = [self valueForContext:context];
if (contextValue == nil) {
contextValue = [RKOrderedDictionary dictionary];
[self setValue:contextValue forContext:context];
}
[self assertStorageForContext:context isKindOfClass:[RKOrderedDictionary class]];
[contextValue insertObject:[RKObjectMappingProviderContextEntry contextEntryWithMapping:mapping]
forKey:pattern
atIndex:index];
}
– (void)setMapping:(RKObjectMappingDefinition *)mapping forPattern:(NSString *)pattern context:(RKObjectMappingProviderContext)context {
RKOrderedDictionary *contextValue = [self valueForContext:context];
if (contextValue == nil) {
contextValue = [RKOrderedDictionary dictionary];
[self setValue:contextValue forContext:context];
}
[self assertStorageForContext:context isKindOfClass:[RKOrderedDictionary class]];
[contextValue setObject:[RKObjectMappingProviderContextEntry contextEntryWithMapping:mapping]
forKey:pattern];
}
– (RKObjectMappingDefinition *)mappingForPatternMatchingString:(NSString *)string context:(RKObjectMappingProviderContext)context {
NSAssert(string, @”Cannot look up mapping matching nil pattern string.”);
RKOrderedDictionary *contextValue = [self valueForContext:context];
NSAssert(contextValue, @”Attempted to retrieve mapping from undefined context: %d”, context);
for (NSString *pattern in contextValue) {
RKPathMatcher *pathMatcher = [RKPathMatcher matcherWithPattern:pattern];
if ([pathMatcher matchesPath:string tokenizeQueryStrings:NO parsedArguments:nil]) {
RKObjectMappingProviderContextEntry *entry = [contextValue objectForKey:pattern];
return entry.mapping;
}
}
return nil;
}
– (void)setEntry:(RKObjectMappingProviderContextEntry *)entry forPattern:(NSString *)pattern context:(RKObjectMappingProviderContext)context {
RKOrderedDictionary *contextValue = [self valueForContext:context];
if (contextValue == nil) {
contextValue = [RKOrderedDictionary dictionary];
[self setValue:contextValue forContext:context];
}
[self assertStorageForContext:context isKindOfClass:[RKOrderedDictionary class]];
[contextValue setObject:entry
forKey:pattern];
}
– (RKObjectMappingProviderContextEntry *)entryForPatternMatchingString:(NSString *)string context:(RKObjectMappingProviderContext)context {
RKOrderedDictionary *contextValue = [self valueForContext:context];
NSAssert(contextValue, @”Attempted to retrieve mapping from undefined context: %d”, context);
for (NSString *pattern in contextValue) {
RKPathMatcher *pathMatcher = [RKPathMatcher matcherWithPattern:pattern];
if ([pathMatcher matchesPath:string tokenizeQueryStrings:NO parsedArguments:nil]) {
return [contextValue objectForKey:pattern];
}
}
return nil;
}
#pragma mark – Aliases
+ (RKObjectMappingProvider *)objectMappingProvider {
return [self mappingProvider];
}
– (RKObjectMapping *)mappingForKeyPath:(NSString *)keyPath {
return (RKObjectMapping *) [self objectMappingForKeyPath:keyPath];
}
– (void)setMapping:(RKObjectMapping *)mapping forKeyPath:(NSString *)keyPath {
[self setObjectMapping:mapping forKeyPath:keyPath];
}
– (NSDictionary *)mappingsByKeyPath {
return [self objectMappingsByKeyPath];
}
– (void)registerMapping:(RKObjectMapping *)objectMapping withRootKeyPath:(NSString *)keyPath {
return [self registerObjectMapping:objectMapping withRootKeyPath:keyPath];
}
– (void)removeMappingForKeyPath:(NSString *)keyPath {
[self removeObjectMappingForKeyPath:keyPath];
}
// Deprecated
+ (id)mappingProviderWithBlock:(void (^)(RKObjectMappingProvider*))block {
return [self mappingProviderUsingBlock:block];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingProvider.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingProviderContextEntry.h
//
// RKObjectMappingProviderContextEntry.h
// RestKit
//
// Created by Jeff Arena on 1/26/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectMappingDefinition.h”
@interface RKObjectMappingProviderContextEntry : NSObject
+ (RKObjectMappingProviderContextEntry *)contextEntryWithMapping:(RKObjectMappingDefinition *)mapping;
+ (RKObjectMappingProviderContextEntry *)contextEntryWithMapping:(RKObjectMappingDefinition *)mapping userData:(id)userData;
@property (nonatomic, retain) RKObjectMappingDefinition *mapping;
@property (nonatomic, retain) id userData;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingProviderContextEntry.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingProviderContextEntry.m
//
// RKObjectMappingProviderContextEntry.m
// RestKit
//
// Created by Jeff Arena on 1/26/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectMappingProviderContextEntry.h”
@implementation RKObjectMappingProviderContextEntry
@synthesize mapping = _mapping;
@synthesize userData = _userData;
– (id)init {
self = [super init];
if (self) {
_mapping = nil;
_userData = nil;
}
return self;
}
– (void)dealloc {
[_mapping release];
_mapping = nil;
[_userData release];
_userData = nil;
[super dealloc];
}
– (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[RKObjectMappingProviderContextEntry class]]) {
RKObjectMappingProviderContextEntry *entry = (RKObjectMappingProviderContextEntry *)object;
return ([self.mapping isEqual:entry.mapping] && (self.userData == entry.userData));
}
return NO;
}
– (NSUInteger)hash {
int prime = 31;
int result = 1;
result = prime * [self.userData hash]? [self.mapping hash] : [self.userData hash];
return result;
}
+ (RKObjectMappingProviderContextEntry *)contextEntryWithMapping:(RKObjectMappingDefinition *)mapping {
RKObjectMappingProviderContextEntry *contextEntry = [[[RKObjectMappingProviderContextEntry alloc] init] autorelease];
contextEntry.mapping = mapping;
return contextEntry;
}
+ (RKObjectMappingProviderContextEntry *)contextEntryWithMapping:(RKObjectMappingDefinition *)mapping userData:(id)userData {
RKObjectMappingProviderContextEntry *contextEntry = [RKObjectMappingProviderContextEntry contextEntryWithMapping:mapping];
contextEntry.userData = userData;
return contextEntry;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingProviderContextEntry.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingResult.h
//
// RKObjectMappingResult.h
// RestKit
//
// Created by Blake Watters on 5/7/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@interface RKObjectMappingResult : NSObject {
id _keyPathToMappedObjects;
}
– (id)initWithDictionary:(id)dictionary;
+ (RKObjectMappingResult*)mappingResultWithDictionary:(NSDictionary*)keyPathToMappedObjects;
/**
Return the mapping result as a dictionary
*/
– (NSDictionary*)asDictionary;
– (id)asObject;
– (NSArray*)asCollection;
– (NSError*)asError;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingResult.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectMappingResult.m
//
// RKObjectMappingResult.m
// RestKit
//
// Created by Blake Watters on 5/7/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingResult.h”
#import “RKObjectMapperError.h”
#import “RKLog.h”
@implementation RKObjectMappingResult
– (id)initWithDictionary:(id)dictionary {
self = [self init];
if (self) {
_keyPathToMappedObjects = [dictionary retain];
}
return self;
}
– (void)dealloc {
[_keyPathToMappedObjects release];
[super dealloc];
}
+ (RKObjectMappingResult*)mappingResultWithDictionary:(NSDictionary*)keyPathToMappedObjects {
return [[[self alloc] initWithDictionary:keyPathToMappedObjects] autorelease];
}
– (NSDictionary*)asDictionary {
return _keyPathToMappedObjects;
}
– (NSArray*)asCollection {
// Flatten results down into a single array
NSMutableArray* collection = [NSMutableArray array];
for (id object in [_keyPathToMappedObjects allValues]) {
// We don’t want to strip the keys off of a mapped dictionary result
if (NO == [object isKindOfClass:[NSDictionary class]] && [object respondsToSelector:@selector(allObjects)]) {
[collection addObjectsFromArray:[object allObjects]];
} else {
[collection addObject:object];
}
}
return collection;
}
– (id)asObject {
NSArray* collection = [self asCollection];
NSUInteger count = [collection count];
if (count == 0) {
return nil;
}
if (count > 1) RKLogWarning(@”Coerced object mapping result containing %lu objects into singular result.”, (unsigned long) count);
return [collection objectAtIndex:0];
}
– (NSError*)asError {
NSArray* collection = [self asCollection];
NSString* description = nil;
if ([collection count] > 0) {
description = [[collection valueForKeyPath:@”description”] componentsJoinedByString:@”, “];
} else {
RKLogWarning(@”Expected mapping result to contain at least one object to construct an error”);
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:collection, RKObjectMapperErrorObjectsKey,
description, NSLocalizedDescriptionKey, nil];
NSError* error = [NSError errorWithDomain:RKErrorDomain code:RKObjectMapperErrorFromMappingResult userInfo:userInfo];
return error;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectMappingResult.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectPaginator.h
//
// RKObjectPaginator.h
// RestKit
//
// Created by Blake Watters on 12/29/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMappingProvider.h”
#import “RKManagedObjectStore.h”
#import “RKObjectLoader.h”
#import “RKConfigurationDelegate.h”
@protocol RKObjectPaginatorDelegate;
typedef void(^RKObjectPaginatorDidLoadObjectsForPageBlock)(NSArray *objects, NSUInteger page);
typedef void(^RKObjectPaginatorDidFailWithErrorBlock)(NSError *error, RKObjectLoader *loader);
/**
Instances of RKObjectPaginator retrieve paginated collections of mappable data
from remote systems via HTTP. Paginators perform GET requests and use a patterned
URL to construct a full URL reflecting the state of the paginator. Paginators rely
on an instance of RKObjectMappingProvider to determine how to perform object mapping
on the retrieved data. Paginators can load Core Data backed models provided that an
instance of RKManagedObjectStore is assigned to the paginator.
*/
@interface RKObjectPaginator : NSObject
/**
Creates and returns a RKObjectPaginator object with the a provided patternURL and mappingProvider.
@param patternURL A RKURL containing a dynamic pattern for constructing a URL to the paginated
resource collection.
@param mappingProvider An RKObjectMappingProvider containing object mapping configurations for mapping the
paginated resource collection.
@see patternURL
@return A paginator object initialized with patterned URL and mapping provider.
*/
+ (id)paginatorWithPatternURL:(RKURL *)patternURL mappingProvider:(RKObjectMappingProvider *)mappingProvider;
/**
Initializes a RKObjectPaginator object with the a provided patternURL and mappingProvider.
@param patternURL A RKURL containing a dynamic pattern for constructing a URL to the paginated
resource collection.
@param mappingProvider An RKObjectMappingProvider containing object mapping configurations for mapping the
paginated resource collection.
@see patternURL
@return The receiver, initialized with patterned URL and mapping provider.
*/
– (id)initWithPatternURL:(RKURL *)patternURL mappingProvider:(RKObjectMappingProvider *)mappingProvider;
/**
A RKURL with a resource path pattern for building a complete URL from
which to load the paginated resource collection. The patterned resource
path will be evaluated against the state of the paginator object itself.
For example, given a paginated collection of data at the /articles resource path,
the patterned resource path may look like:
/articles?per_page=:perPage&page_number=:currentPage
When the pattern is evaluated against the state of the paginator, this will
yield a complete resource path that can be used to load the specified page. Given
a paginator configured with 100 objects per page and a current page number of 3,
the resource path of the pagination URL would become:
/articles?per_page=100&page_number=3
@see [RKURL URLByInterpolatingResourcePathWithObject:]
*/
@property (nonatomic, copy) RKURL *patternURL;
/**
Returns a complete RKURL to the paginated resource collection by interpolating
the state of the paginator object against the resource
*/
@property (nonatomic, readonly) RKURL *URL;
/**
The object that acts as the delegate of the receiving paginator.
*/
@property (nonatomic, assign) id
/**
The block to invoke when the paginator has loaded a page of objects from the collection.
@see [RKObjectPaginatorDelegate paginator:didLoadObjects:forPage]
*/
@property (nonatomic, copy) RKObjectPaginatorDidLoadObjectsForPageBlock onDidLoadObjectsForPage;
/**
The block to invoke when the paginator has failed loading due to an error.
@see [RKObjectPaginatorDelegate paginator:didFailWithError:objectLoader:]
*/
@property (nonatomic, copy) RKObjectPaginatorDidFailWithErrorBlock onDidFailWithError;
/**
The object that acts as the configuration delegate for RKObjectLoader instances built
and utilized by the paginator.
**Default**: nil
@see RKClient
@see RKObjectManager
*/
@property (nonatomic, assign) id
/** @name Object Mapping Configuration */
/**
The mapping provider to use when performing object mapping on the data
loaded from the remote system. The provider will be assigned to the RKObjectLoader
instance built to retrieve the paginated resource collection.
*/
@property (nonatomic, retain) RKObjectMappingProvider *mappingProvider;
/**
An object store for accessing Core Data. Required if the objects being paginated
are stored into Core Data.
*/
@property (nonatomic, retain) RKManagedObjectStore *objectStore;
/** @name Pagination Metadata */
/**
The number of objects to load per page
*/
@property (nonatomic, assign) NSUInteger perPage;
/**
A Boolean value indicating if the paginator has loaded a page of objects
@returns YES when the paginator has loaded a page of objects
*/
@property (nonatomic, readonly, getter = isLoaded) BOOL loaded;
/**
Returns the page number for the most recently loaded page of objects.
@return The page number for the current page of objects.
@exception NSInternalInconsistencyException Raised if isLoaded is NO.
*/
@property (nonatomic, readonly) NSUInteger currentPage;
/**
Returns the number of pages in the total resource collection.
@return A count of the number of pages in the resource collection.
@exception NSInternalInconsistencyException Raised if hasPageCount is NO.
*/
@property (nonatomic, readonly) NSUInteger pageCount;
/**
Returns the total number of objects in the collection
@return A count of the number of objects in the resource collection.
@exception NSInternalInconsistencyException Raised if hasObjectCount is NO.
*/
@property (nonatomic, readonly) NSUInteger objectCount;
/**
Returns a Boolean value indicating if the total number of pages in the collection
is known by the paginator.
@return YES if the paginator knows the page count, otherwise NO
*/
– (BOOL)hasPageCount;
/**
Returns a Boolean value indicating if the total number of objects in the collection
is known by the paginator.
@return YES if the paginator knows the number of objects in the paginated collection, otherwise NO.
*/
– (BOOL)hasObjectCount;
/**
Returns a Boolean value indicating if there is a next page in the collection.
@return YES if there is a next page, otherwise NO.
@exception NSInternalInconsistencyException Raised if isLoaded or hasPageCount is NO.
*/
– (BOOL)hasNextPage;
/**
Returns a Boolean value indicating if there is a previous page in the collection.
@return YES if there is a previous page, otherwise NO.
@exception NSInternalInconsistencyException Raised if isLoaded is NO.
*/
– (BOOL)hasPreviousPage;
/** @name Paginator Actions */
/**
Loads the next page of data by incrementing the current page, constructing an object
loader to fetch the data, and object mapping the results.
*/
– (void)loadNextPage;
/**
Loads the previous page of data by decrementing the current page, constructing an object
loader to fetch the data, and object mapping the results.
*/
– (void)loadPreviousPage;
/**
Loads a specific page of data by mutating the current page, constructing an object
loader to fetch the data, and object mapping the results.
@param pageNumber The page of objects to load from the remote backend
*/
– (void)loadPage:(NSUInteger)pageNumber;
@end
/**
The RKObjectPaginatorDelegate formal protocol defines
RKObjectPaginator delegate methods that can be implemented by
objects to receive informational callbacks about paginated loading
of mapping objects through RestKit.
*/
@protocol RKObjectPaginatorDelegate
/**
Tells the delegate the paginator has loaded a page of objects from the collection.
@param paginator The paginator that loaded the objects.
@param objects An array of objects mapped from the remote JSON/XML representation.
@param page The page number that was loaded.
*/
– (void)paginator:(RKObjectPaginator *)paginator didLoadObjects:(NSArray *)objects forPage:(NSUInteger)page;
/**
Tells the delegate the paginator has failed loading due to an error.
@param paginator The paginator that failed loading due to an error.
@param error An NSError indicating the cause of the failure.
@param loader The loader request that resulted in the failure.
*/
– (void)paginator:(RKObjectPaginator *)paginator didFailWithError:(NSError *)error objectLoader:(RKObjectLoader *)loader;
@optional
/**
Tells the delegate that the paginator is about to begin loading a page of objects.
@param paginator The paginator performing the load.
@param page The numeric page number being loaded.
@param loader The object loader request used to load the page.
*/
– (void)paginator:(RKObjectPaginator *)paginator willLoadPage:(NSUInteger)page objectLoader:(RKObjectLoader *)loader;
/**
Tells the delegate the paginator has loaded the first page of objects in the collection.
@param paginator The paginator instance that has loaded the first page.
*/
– (void)paginatorDidLoadFirstPage:(RKObjectPaginator *)paginator;
/**
Tells the delegate the paginator has loaded the last page of objects in the collection.
@param paginator The paginator instance that has loaded the last page.
*/
– (void)paginatorDidLoadLastPage:(RKObjectPaginator *)paginator;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectPaginator.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectPaginator.m
//
// RKObjectPaginator.m
// RestKit
//
// Created by Blake Watters on 12/29/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectPaginator.h”
#import “RKManagedObjectLoader.h”
#import “RKObjectMappingOperation.h”
#import “SOCKit.h”
#import “RKLog.h”
static NSUInteger RKObjectPaginatorDefaultPerPage = 25;
// Private interface
@interface RKObjectPaginator ()
@property (nonatomic, retain) RKObjectLoader *objectLoader;
@end
@implementation RKObjectPaginator
@synthesize patternURL;
@synthesize currentPage;
@synthesize perPage;
@synthesize loaded;
@synthesize pageCount;
@synthesize objectCount;
@synthesize mappingProvider;
@synthesize delegate;
@synthesize objectStore;
@synthesize objectLoader;
@synthesize configurationDelegate;
@synthesize onDidLoadObjectsForPage;
@synthesize onDidFailWithError;
+ (id)paginatorWithPatternURL:(RKURL *)aPatternURL mappingProvider:(RKObjectMappingProvider *)aMappingProvider {
return [[[self alloc] initWithPatternURL:aPatternURL mappingProvider:aMappingProvider] autorelease];
}
– (id)initWithPatternURL:(RKURL *)aPatternURL mappingProvider:(RKObjectMappingProvider *)aMappingProvider {
self = [super init];
if (self) {
patternURL = [aPatternURL copy];
mappingProvider = [aMappingProvider retain];
currentPage = NSUIntegerMax;
pageCount = NSUIntegerMax;
objectCount = NSUIntegerMax;
perPage = RKObjectPaginatorDefaultPerPage;
loaded = NO;
}
return self;
}
– (void)dealloc {
delegate = nil;
configurationDelegate = nil;
objectLoader.delegate = nil;
[patternURL release];
patternURL = nil;
[mappingProvider release];
mappingProvider = nil;
[objectStore release];
objectStore = nil;
[objectLoader cancel];
objectLoader.delegate = nil;
[objectLoader release];
objectLoader = nil;
[onDidLoadObjectsForPage release];
onDidLoadObjectsForPage = nil;
[onDidFailWithError release];
onDidFailWithError = nil;
[super dealloc];
}
– (RKObjectMapping *)paginationMapping {
return [mappingProvider paginationMapping];
}
– (RKURL *)URL {
return [patternURL URLByInterpolatingResourcePathWithObject:self];
}
// Private. Public consumers can rely on isLoaded
– (BOOL)hasCurrentPage {
return currentPage != NSUIntegerMax;
}
– (BOOL)hasPageCount {
return pageCount != NSUIntegerMax;
}
– (BOOL)hasObjectCount {
return objectCount != NSUIntegerMax;
}
– (NSUInteger)currentPage {
// Referenced during initial load, so we don’t rely on isLoaded.
NSAssert([self hasCurrentPage], @”Current page has not been initialized.”);
return currentPage;
}
– (NSUInteger)pageCount {
NSAssert([self hasPageCount], @”Page count not available.”);
return pageCount;
}
– (BOOL)hasNextPage {
NSAssert(self.isLoaded, @”Cannot determine hasNextPage: paginator is not loaded.”);
NSAssert([self hasPageCount], @”Cannot determine hasNextPage: page count is not known.”);
return self.currentPage < self.pageCount;
}
- (BOOL)hasPreviousPage {
NSAssert(self.isLoaded, @"Cannot determine hasPreviousPage: paginator is not loaded.");
return self.currentPage > 1;
}
#pragma mark – RKObjectLoaderDelegate methods
– (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
self.objectLoader = nil;
loaded = YES;
RKLogInfo(@”Loaded objects: %@”, objects);
[self.delegate paginator:self didLoadObjects:objects forPage:self.currentPage];
if (self.onDidLoadObjectsForPage) {
self.onDidLoadObjectsForPage(objects, self.currentPage);
}
if ([self hasPageCount] && self.currentPage == 1) {
if ([self.delegate respondsToSelector:@selector(paginatorDidLoadFirstPage:)]) {
[self.delegate paginatorDidLoadFirstPage:self];
}
}
if ([self hasPageCount] && self.currentPage == self.pageCount) {
if ([self.delegate respondsToSelector:@selector(paginatorDidLoadLastPage:)]) {
[self.delegate paginatorDidLoadLastPage:self];
}
}
}
– (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
RKLogError(@”Paginator error %@”, error);
[self.delegate paginator:self didFailWithError:error objectLoader:self.objectLoader];
if (self.onDidFailWithError) {
self.onDidFailWithError(error, self.objectLoader);
}
self.objectLoader = nil;
}
– (void)objectLoader:(RKObjectLoader *)loader willMapData:(inout id *)mappableData {
NSError *error = nil;
RKObjectMappingOperation *mappingOperation = [RKObjectMappingOperation mappingOperationFromObject:*mappableData toObject:self withMapping:[self paginationMapping]];
BOOL success = [mappingOperation performMapping:&error];
if (!success) {
pageCount = currentPage = 0;
RKLogError(@”Paginator didn’t map info to compute page count. Assuming no pages.”);
} else if (self.perPage && [self hasObjectCount]) {
float objectCountFloat = self.objectCount;
pageCount = ceilf(objectCountFloat / self.perPage);
RKLogInfo(@”Paginator objectCount: %ld pageCount: %ld”, (long) self.objectCount, (long) self.pageCount);
} else {
NSAssert(NO, @”Paginator perPage set is 0.”);
RKLogError(@”Paginator perPage set is 0.”);
}
}
#pragma mark – Action methods
– (void)loadNextPage {
[self loadPage:currentPage + 1];
}
– (void)loadPreviousPage {
[self loadPage:currentPage – 1];
}
– (void)loadPage:(NSUInteger)pageNumber {
NSAssert(self.mappingProvider, @”Cannot perform a load with a nil mappingProvider.”);
NSAssert(! objectLoader, @”Cannot perform a load while one is already in progress.”);
currentPage = pageNumber;
if (self.objectStore) {
self.objectLoader = [[[RKManagedObjectLoader alloc] initWithURL:self.URL mappingProvider:self.mappingProvider objectStore:self.objectStore] autorelease];
} else {
self.objectLoader = [[[RKObjectLoader alloc] initWithURL:self.URL mappingProvider:self.mappingProvider] autorelease];
}
if ([self.configurationDelegate respondsToSelector:@selector(configureObjectLoader:)]) {
[self.configurationDelegate configureObjectLoader:objectLoader];
}
self.objectLoader.method = RKRequestMethodGET;
self.objectLoader.delegate = self;
if ([self.delegate respondsToSelector:@selector(paginator:willLoadPage:objectLoader:)]) {
[self.delegate paginator:self willLoadPage:pageNumber objectLoader:self.objectLoader];
}
[self.objectLoader send];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectPaginator.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectPropertyInspector.h
//
// RKObjectPropertyInspector.h
// RestKit
//
// Created by Blake Watters on 3/4/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@class NSEntityDescription;
@interface RKObjectPropertyInspector : NSObject {
NSMutableDictionary* _cachedPropertyNamesAndTypes;
}
+ (RKObjectPropertyInspector*)sharedInspector;
/**
* Returns a dictionary of names and types for the properties of a given class
*/
– (NSDictionary *)propertyNamesAndTypesForClass:(Class)objectClass;
/**
Returns the Class type of the specified property on the object class
*/
– (Class)typeForProperty:(NSString*)propertyName ofClass:(Class)objectClass;
/**
Returns the name of a property when provided the name of a property obtained
via the property_getAttributes reflection API
*/
+ (NSString *)propertyTypeFromAttributeString:(NSString *)attributeString;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectPropertyInspector.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectPropertyInspector.m
//
// RKObjectPropertyInspector.m
// RestKit
//
// Created by Blake Watters on 3/4/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectPropertyInspector.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
static RKObjectPropertyInspector* sharedInspector = nil;
@implementation RKObjectPropertyInspector
+ (RKObjectPropertyInspector*)sharedInspector {
if (sharedInspector == nil) {
sharedInspector = [RKObjectPropertyInspector new];
}
return sharedInspector;
}
– (id)init {
if ((self = [super init])) {
_cachedPropertyNamesAndTypes = [[NSMutableDictionary alloc] init];
}
return self;
}
– (void)dealloc {
[_cachedPropertyNamesAndTypes release];
[super dealloc];
}
+ (NSString*)propertyTypeFromAttributeString:(NSString*)attributeString {
NSString *type = [NSString string];
NSScanner *typeScanner = [NSScanner scannerWithString:attributeString];
[typeScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@”@”] intoString:NULL];
// we are not dealing with an object
if([typeScanner isAtEnd]) {
return @”NULL”;
}
[typeScanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@”\”@”] intoString:NULL];
// this gets the actual object type
[typeScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@”\””] intoString:&type];
return type;
}
– (NSDictionary *)propertyNamesAndTypesForClass:(Class)theClass {
NSMutableDictionary* propertyNames = [_cachedPropertyNamesAndTypes objectForKey:theClass];
if (propertyNames) {
return propertyNames;
}
propertyNames = [NSMutableDictionary dictionary];
//include superclass properties
Class currentClass = theClass;
while (currentClass != nil) {
// Get the raw list of properties
unsigned int outCount;
objc_property_t *propList = class_copyPropertyList(currentClass, &outCount);
// Collect the property names
int i;
NSString *propName;
for (i = 0; i < outCount; i++) {
// property_getAttributes() returns everything we need to implement this...
// See: http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW5
objc_property_t* prop = propList + i;
NSString* attributeString = [NSString stringWithCString:property_getAttributes(*prop) encoding:NSUTF8StringEncoding];
propName = [NSString stringWithCString:property_getName(*prop) encoding:NSUTF8StringEncoding];
if (![propName isEqualToString:@"_mapkit_hasPanoramaID"]) {
const char* className = [[RKObjectPropertyInspector propertyTypeFromAttributeString:attributeString] cStringUsingEncoding:NSUTF8StringEncoding];
Class aClass = objc_getClass(className);
if (aClass) {
[propertyNames setObject:aClass forKey:propName];
}
}
}
free(propList);
currentClass = [currentClass superclass];
}
[_cachedPropertyNamesAndTypes setObject:propertyNames forKey:theClass];
RKLogDebug(@"Cached property names and types for Class '%@': %@", NSStringFromClass(theClass), propertyNames);
return propertyNames;
}
- (Class)typeForProperty:(NSString*)propertyName ofClass:(Class)objectClass {
NSDictionary* dictionary = [self propertyNamesAndTypesForClass:objectClass];
return [dictionary objectForKey:propertyName];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectPropertyInspector.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectRelationshipMapping.h
//
// RKObjectRelationshipMapping.h
// RestKit
//
// Created by Blake Watters on 5/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectAttributeMapping.h”
#import “RKObjectMappingDefinition.h”
@class RKObjectmapping;
@interface RKObjectRelationshipMapping : RKObjectAttributeMapping {
RKObjectMappingDefinition * _mapping;
BOOL _reversible;
}
@property (nonatomic, retain) RKObjectMappingDefinition * mapping;
@property (nonatomic, assign) BOOL reversible;
+ (RKObjectRelationshipMapping*)mappingFromKeyPath:(NSString*)sourceKeyPath toKeyPath:(NSString*)destinationKeyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping;
+ (RKObjectRelationshipMapping*)mappingFromKeyPath:(NSString*)sourceKeyPath toKeyPath:(NSString*)destinationKeyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping reversible:(BOOL)reversible;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectRelationshipMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectRelationshipMapping.m
//
// RKObjectRelationshipMapping.m
// RestKit
//
// Created by Blake Watters on 5/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectRelationshipMapping.h”
@implementation RKObjectRelationshipMapping
@synthesize mapping = _mapping;
@synthesize reversible = _reversible;
+ (RKObjectRelationshipMapping*)mappingFromKeyPath:(NSString*)sourceKeyPath toKeyPath:(NSString*)destinationKeyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping reversible:(BOOL)reversible {
RKObjectRelationshipMapping* relationshipMapping = (RKObjectRelationshipMapping*) [self mappingFromKeyPath:sourceKeyPath toKeyPath:destinationKeyPath];
relationshipMapping.reversible = reversible;
relationshipMapping.mapping = objectOrDynamicMapping;
return relationshipMapping;
}
+ (RKObjectRelationshipMapping*)mappingFromKeyPath:(NSString*)sourceKeyPath toKeyPath:(NSString*)destinationKeyPath withMapping:(RKObjectMappingDefinition *)objectOrDynamicMapping {
return [self mappingFromKeyPath:sourceKeyPath toKeyPath:destinationKeyPath withMapping:objectOrDynamicMapping reversible:YES];
}
– (id)copyWithZone:(NSZone *)zone {
RKObjectRelationshipMapping* copy = [super copyWithZone:zone];
copy.mapping = self.mapping;
copy.reversible = self.reversible;
return copy;
}
– (void)dealloc {
[_mapping release];
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectRelationshipMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectRouter.h
//
// RKObjectRouter.h
// RestKit
//
// Created by Blake Watters on 10/18/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequest.h”
#import “RKRouter.h”
// TODO: Cleanup the comments in here
/**
* An implementation of the RKRouter protocol that is suitable for use in either
* static or dynamic route generation. Static routes are added by simply encoding
* the resourcePath that the mappable object should be sent to when a GET, POST, PUT
* or DELETE action is invoked. Dynamic routes are available by encoding key paths into
* the resourcePath using a single colon delimiter, such as /users/:userID
*/
@interface RKObjectRouter : NSObject
NSMutableDictionary* _routes;
}
/**
* Register a mapping from an object class to a resource path. This resourcePath can be static
* (i.e. /this/is/the/path) or dynamic (i.e. /users/:userID/:username). Dynamic routes are
* evaluated against the object being routed using Key-Value coding and coerced into a string.
* *NOTE* – The pattern matcher fully supports KVM, so /:key1.otherKey normally resolves as it
* would in any other KVM situation, … otherKey is a sub-key on a the object represented by
* key1. This presents a problem in situations where you might want to build a pattern like
* /:filename.json, where the dot isn’t intended as a sub-key on the dynamic “filename”, but
* rather it is part of the “json” static string. In these instances, you need to escape the
* dot with two backslashes, like so: /:filename\\.json
* @see RKPathMatcher
*/
– (void)routeClass:(Class)objectClass toResourcePathPattern:(NSString*)resourcePathPattern;
/**
* Register a mapping from an object class to a resource path for a specific HTTP method.
* @see RKPathMatcher
*/
– (void)routeClass:(Class)objectClass toResourcePathPattern:(NSString*)resourcePathPattern forMethod:(RKRequestMethod)method;
/**
* Register a mapping from an object class to a resource path for a specific HTTP method,
* optionally adding url escapes to the path. This urlEscape flag comes in handy when you want to provide
* your own fully escaped dynamic resource path via a method/attribute on the object model.
* For example, if your Person model has a string attribute titled “polymorphicResourcePath” that returns
* @”/this/is/the/path”, you should configure the route with url escapes ‘off’, otherwise the router will return
* @”%2Fthis%2Fis%2Fthe%2Fpath”.
* @see RKPathMatcher
*/
– (void)routeClass:(Class)objectClass toResourcePathPattern:(NSString*)resourcePathPattern forMethod:(RKRequestMethod)method escapeRoutedPath:(BOOL)addEscapes;
@end
// Method signatures being phased out
@interface RKObjectRouter (CompatibilityAliases)
– (void)routeClass:(Class)objectClass toResourcePath:(NSString*)resourcePath;
– (void)routeClass:(Class)objectClass toResourcePath:(NSString*)resourcePath forMethod:(RKRequestMethod)method;
– (void)routeClass:(Class)objectClass toResourcePath:(NSString*)resourcePath forMethod:(RKRequestMethod)method escapeRoutedPath:(BOOL)addEscapes;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectRouter.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectRouter.m
//
// RKObjectRouter.m
// RestKit
//
// Created by Blake Watters on 10/18/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectRouter.h”
#import “RKPathMatcher.h”
#import “NSDictionary+RKRequestSerialization.h”
@implementation RKObjectRouter
– (id)init {
if ((self = [super init])) {
_routes = [[NSMutableDictionary alloc] init];
}
return self;
}
– (void)dealloc {
[_routes release];
[super dealloc];
}
– (void)routeClass:(Class)theClass toResourcePathPattern:(NSString *)resourcePathPattern forMethodName:(NSString *)methodName escapeRoutedPath:(BOOL)addEscapes {
NSString *className = NSStringFromClass(theClass);
if (nil == [_routes objectForKey:theClass]) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[_routes setObject:dictionary forKey:theClass];
}
NSMutableDictionary *classRoutes = [_routes objectForKey:theClass];
if ([classRoutes objectForKey:methodName]) {
[NSException raise:nil format:@”A route has already been registered for class ‘%@’ and HTTP method ‘%@'”, className, methodName];
}
NSMutableDictionary *routeEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:
resourcePathPattern, @”resourcePath”,
[NSNumber numberWithBool:addEscapes], @”addEscapes”, nil];
[classRoutes setValue:routeEntry forKey:methodName];
}
– (NSString *)HTTPVerbForMethod:(RKRequestMethod)method {
switch (method) {
case RKRequestMethodGET:
return @”GET”;
break;
case RKRequestMethodPOST:
return @”POST”;
break;
case RKRequestMethodPUT:
return @”PUT”;
break;
case RKRequestMethodDELETE:
return @”DELETE”;
break;
default:
return nil;
break;
}
}
// Public
– (void)routeClass:(Class)theClass toResourcePathPattern:(NSString *)resourcePathPattern {
[self routeClass:theClass toResourcePathPattern:resourcePathPattern forMethodName:@”ANY” escapeRoutedPath:YES];
}
– (void)routeClass:(Class)theClass toResourcePathPattern:(NSString *)resourcePath forMethod:(RKRequestMethod)method {
[self routeClass:theClass toResourcePath:resourcePath forMethod:method escapeRoutedPath:YES];
}
– (void)routeClass:(Class)theClass toResourcePathPattern:(NSString *)resourcePath forMethod:(RKRequestMethod)method escapeRoutedPath:(BOOL)addEscapes {
NSString *methodName = [self HTTPVerbForMethod:method];
[self routeClass:theClass toResourcePathPattern:resourcePath forMethodName:methodName escapeRoutedPath:addEscapes];
}
#pragma mark RKRouter
– (NSString *)resourcePathForObject:(NSObject *)object method:(RKRequestMethod)method {
NSString *methodName = [self HTTPVerbForMethod:method];
NSString *className = NSStringFromClass([object class]);
NSDictionary *classRoutes = nil;
// Check for exact matches
for (Class possibleClass in _routes) {
if ([object isMemberOfClass:possibleClass]) {
classRoutes = [_routes objectForKey:possibleClass];
break;
}
}
// Check for superclass matches
if (! classRoutes) {
for (Class possibleClass in _routes) {
if ([object isKindOfClass:possibleClass]) {
classRoutes = [_routes objectForKey:possibleClass];
break;
}
}
}
NSDictionary *routeEntry = [classRoutes objectForKey:methodName];
if (!routeEntry)
routeEntry = [classRoutes objectForKey:@”ANY”];
if (routeEntry) {
BOOL addEscapes = [[routeEntry objectForKey:@”addEscapes”] boolValue];
RKPathMatcher *matcher = [RKPathMatcher matcherWithPattern:[routeEntry objectForKey:@”resourcePath”]];
NSString *interpolatedPath = [matcher pathFromObject:object addingEscapes:addEscapes];
return interpolatedPath;
}
[NSException raise:@”Unable to find a routable path for object” format:@”Unable to find a routable path for object of type ‘%@’ for HTTP Method ‘%@'”, className, methodName];
return nil;
}
@end
@implementation RKObjectRouter (CompatibilityAliases)
– (void)routeClass:(Class)objectClass toResourcePath:(NSString *)resourcePath {
[self routeClass:objectClass toResourcePathPattern:resourcePath];
}
– (void)routeClass:(Class)objectClass toResourcePath:(NSString *)resourcePath forMethod:(RKRequestMethod)method {
[self routeClass:objectClass toResourcePathPattern:resourcePath forMethod:method];
}
– (void)routeClass:(Class)objectClass toResourcePath:(NSString *)resourcePath forMethod:(RKRequestMethod)method escapeRoutedPath:(BOOL)addEscapes {
[self routeClass:objectClass toResourcePathPattern:resourcePath forMethod:method escapeRoutedPath:addEscapes];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectRouter.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectSerializer.h
//
// RKObjectSerializer.h
// RestKit
//
// Created by Blake Watters on 5/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKObjectMapping.h”
#import “RKObjectMappingOperation.h”
#import “RKRequestSerializable.h”
/**
Performs a serialization of an object and its relationships back into
a dictionary representation according to the mappings specified. The
transformed object is then enclosed in an RKRequestSerializable representation
that is suitable for inclusion in an RKRequest.
*/
@interface RKObjectSerializer : NSObject
id _object;
RKObjectMapping* _mapping;
}
@property (nonatomic, readonly) id object;
@property (nonatomic, readonly) RKObjectMapping* mapping;
+ (id)serializerWithObject:(id)object mapping:(RKObjectMapping*)mapping;
– (id)initWithObject:(id)object mapping:(RKObjectMapping*)mapping;
/**
Return a serialized representation of the source object by applying an object mapping
with a target object type of NSMutableDictionary. The serialized object will contain attributes
and relationships composed of simple KVC compliant Cocoa types.
*/
– (NSMutableDictionary*)serializedObject:(NSError**)error;
/**
Return a serialized representation of the source object by mapping it into a NSMutableDictionary and
then encoding it into the destination MIME Type via an instance of RKParser that is registered
for the specified MIME Type
*/
– (NSString*)serializedObjectForMIMEType:(NSString*)MIMEType error:(NSError**)error;
/**
Return a request serialization for the source object by mapping it to an NSMutableDictionary, encoding
the data via a parser into the specified MIME Type, and wrapping it into a serializable format that can
be used as the params of an RKRequest or RKObjectLoader
*/
– (id
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectSerializer.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKObjectSerializer.m
//
// RKObjectSerializer.m
// RestKit
//
// Created by Blake Watters on 5/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKRequestSerialization.h”
#import “RKMIMETypes.h”
#import “RKParser.h”
#import “RKObjectSerializer.h”
#import “NSDictionary+RKRequestSerialization.h”
#import “RKParserRegistry.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
@implementation RKObjectSerializer
@synthesize object = _object;
@synthesize mapping = _mapping;
+ (id)serializerWithObject:(id)object mapping:(RKObjectMapping*)mapping {
return [[[self alloc] initWithObject:object mapping:mapping] autorelease];
}
– (id)initWithObject:(id)object mapping:(RKObjectMapping*)mapping {
self = [super init];
if (self) {
_object = [object retain];
_mapping = [mapping retain];
}
return self;
}
– (void)dealloc {
[_object release];
[_mapping release];
[super dealloc];
}
// Return it serialized into a dictionary
– (id)serializedObject:(NSError**)error {
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
RKObjectMappingOperation* operation = [RKObjectMappingOperation mappingOperationFromObject:_object toObject:dictionary withMapping:_mapping];
operation.delegate = self;
BOOL success = [operation performMapping:error];
if (!success) {
return nil;
}
// Optionally enclose the serialized object within a container…
if (_mapping.rootKeyPath) {
// TODO: Should log this…
dictionary = [NSMutableDictionary dictionaryWithObject:dictionary forKey:_mapping.rootKeyPath];
}
return dictionary;
}
– (id)serializedObjectForMIMEType:(NSString*)MIMEType error:(NSError**)error {
// TODO: This will fail for form encoded…
id serializedObject = [self serializedObject:error];
if (serializedObject) {
id
NSString* string = [parser stringFromObject:serializedObject error:error];
if (string == nil) {
return nil;
}
return string;
}
return nil;
}
– (id
if ([MIMEType isEqualToString:RKMIMETypeFormURLEncoded]) {
// Dictionaries are natively RKRequestSerializable as Form Encoded
return [self serializedObject:error];
} else {
NSString* string = [self serializedObjectForMIMEType:MIMEType error:error];
if (string) {
NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [RKRequestSerialization serializationWithData:data MIMEType:MIMEType];
}
}
return nil;
}
#pragma mark – RKObjectMappingOperationDelegate
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didSetValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKObjectAttributeMapping *)mapping {
id transformedValue = nil;
Class orderedSetClass = NSClassFromString(@”NSOrderedSet”);
if ([value isKindOfClass:[NSDate class]]) {
// Date’s are not natively serializable, must be encoded as a string
@synchronized(self.mapping.preferredDateFormatter) {
transformedValue = [self.mapping.preferredDateFormatter stringForObjectValue:value];
}
} else if ([value isKindOfClass:[NSDecimalNumber class]]) {
// Precision numbers are serialized as strings to work around Javascript notation limits
transformedValue = [(NSDecimalNumber*)value stringValue];
} else if ([value isKindOfClass:orderedSetClass]) {
// NSOrderedSets are not natively serializable, so let’s just turn it into an NSArray
transformedValue = [value array];
}
if (transformedValue) {
RKLogDebug(@”Serialized %@ value at keyPath to %@ (%@)”, NSStringFromClass([value class]), NSStringFromClass([transformedValue class]), value);
[operation.destinationObject setValue:transformedValue forKey:keyPath];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKObjectSerializer.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKParserRegistry.h
//
// RKParserRegistry.h
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKMIMETypes.h”
#import “RKParser.h”
/**
RKParserRegistry provides for the registration of RKParser classes
that handle parsing/serializing for content by MIME Type. Registration
is configured via exact string matches (i.e. application/json) or via regular
expression.
*/
@interface RKParserRegistry : NSObject {
NSMutableDictionary *_MIMETypeToParserClasses;
NSMutableArray *_MIMETypeToParserClassesRegularExpressions;
}
/**
Return the global shared singleton registry for MIME Type to Parsers
@return The global shared RKParserRegistry instance.
*/
+ (RKParserRegistry *)sharedRegistry;
/**
Sets the global shared registry singleton to a new instance of RKParserRegistry
@param registry A new parser registry object to configure as the shared instance.
*/
+ (void)setSharedRegistry:(RKParserRegistry *)registry;
/**
Returns an instance of the RKParser conformant class registered to handle content
with the given MIME Type.
MIME Types are searched in the order in which they are registered and exact
string matches are favored over regular expressions.
@param MIMEType The MIME Type of the content to be parsed/serialized.
@return An instance of the RKParser conformant class registered to handle the given MIME Type.
*/
– (id
/**
Returns an instance of the RKParser conformant class registered to handle content
with the given MIME Type.
MIME Types are searched in the order in which they are registered and exact
string matches are favored over regular expressions.
@param MIMEType The MIME Type of the content to be parsed/serialized.
@return The RKParser conformant class registered to handle the given MIME Type.
*/
– (Class
/**
Registers an RKParser conformant class as the handler for MIME Types exactly matching the
specified MIME Type string.
@param parserClass The RKParser conformant class to instantiate when parsing/serializing MIME Types matching MIMETypeExpression.
@param MIMEType A MIME Type string for which instances of parserClass should be used for parsing/serialization.
*/
– (void)setParserClass:(Class
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
/**
Registers an RKParser conformant class as the handler for MIME Types matching the
specified regular expression.
@param parserClass The RKParser conformant class to instantiate when parsing/serializing MIME Types matching MIMETypeExpression.
@param MIMETypeRegex A regular expression that matches MIME Types that should be handled by instances of parserClass.
*/
– (void)setParserClass:(Class
#endif
/**
Automatically configure the registry via run-time reflection of the RKParser classes
available that ship with RestKit. This happens automatically when the shared registry
singleton is initialized and makes configuration transparent to users.
*/
– (void)autoconfigure;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKParserRegistry.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKParserRegistry.m
//
// RKParserRegistry.m
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKParserRegistry.h”
RKParserRegistry *gSharedRegistry;
@implementation RKParserRegistry
+ (RKParserRegistry *)sharedRegistry {
if (gSharedRegistry == nil) {
gSharedRegistry = [RKParserRegistry new];
[gSharedRegistry autoconfigure];
}
return gSharedRegistry;
}
+ (void)setSharedRegistry:(RKParserRegistry *)registry {
[registry retain];
[gSharedRegistry release];
gSharedRegistry = registry;
}
– (id)init {
self = [super init];
if (self) {
_MIMETypeToParserClasses = [[NSMutableDictionary alloc] init];
_MIMETypeToParserClassesRegularExpressions = [[NSMutableArray alloc] init];
}
return self;
}
– (void)dealloc {
[_MIMETypeToParserClasses release];
[_MIMETypeToParserClassesRegularExpressions release];
[super dealloc];
}
– (Class
id parserClass = [_MIMETypeToParserClasses objectForKey:MIMEType];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
if (!parserClass)
{
for (NSArray *regexAndClass in _MIMETypeToParserClassesRegularExpressions) {
NSRegularExpression *regex = [regexAndClass objectAtIndex:0];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:MIMEType options:0 range:NSMakeRange(0, [MIMEType length])];
if (numberOfMatches) {
parserClass = [regexAndClass objectAtIndex:1];
break;
}
}
}
#endif
return parserClass;
}
– (void)setParserClass:(Class
[_MIMETypeToParserClasses setObject:parserClass forKey:MIMEType];
}
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
– (void)setParserClass:(Class
NSArray *expressionAndClass = [NSArray arrayWithObjects:MIMETypeRegex, parserClass, nil];
[_MIMETypeToParserClassesRegularExpressions addObject:expressionAndClass];
}
#endif
– (id
Class parserClass = [self parserClassForMIMEType:MIMEType];
if (parserClass) {
return [[[parserClass alloc] init] autorelease];
}
return nil;
}
– (void)autoconfigure {
Class parserClass = nil;
// JSON
NSSet *JSONParserClassNames = [NSSet setWithObjects:@”RKJSONParserJSONKit”, @”RKJSONParserYAJL”, @”RKJSONParserSBJSON”, @”RKJSONParserNXJSON”, nil];
for (NSString *parserClassName in JSONParserClassNames) {
parserClass = NSClassFromString(parserClassName);
if (parserClass) {
[self setParserClass:parserClass forMIMEType:RKMIMETypeJSON];
break;
}
}
// XML
parserClass = NSClassFromString(@”RKXMLParserXMLReader”);
if (parserClass) {
[self setParserClass:parserClass forMIMEType:RKMIMETypeXML];
[self setParserClass:parserClass forMIMEType:RKMIMETypeTextXML];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKParserRegistry.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/RKRouter.h
//
// RKRouter.h
// RestKit
//
// Created by Blake Watters on 7/20/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “Network.h”
/**
* Defines a protocol for mapping Cocoa objects to remote resource locations and
* serializables representations.
*/
@protocol RKRouter
/**
* Returns the resource path to send requests for a given object and HTTP method
*/
– (NSString*)resourcePathForObject:(NSObject*)object method:(RKRequestMethod)method;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/ObjectMapping/._RKRouter.h
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._ObjectMapping
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/RestKit.h
//
// RestKit.h
// RestKit
//
// Created by Blake Watters on 2/19/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “Network.h”
#import “Support.h”
#import “ObjectMapping.h”
#import “CoreData.h”
/**
Set the App logging component. This header
file is generally only imported by apps that
are pulling in all of RestKit. By setting the
log component to App here, we allow the app developer
to use RKLog() in their own app.
*/
#undef RKLogComponent
#define RKLogComponent lcl_cApp
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._RestKit.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/lcl_config_components.h
//
// lcl_config_components.h
// RestKit
//
// Created by Blake Watters on 6/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// The lcl_config_components.h file is used to define the application’s log
// components.
//
// Use the code
//
// _lcl_component(
//
// for defining a log component, where
//
// –
// to lcl_log etc. A symbol ‘lcl_c
// each log component.
//
// –
// when writing a log message for the log component. The header is a technical
// key for identifying a log component’s messages. It is recommended to use
// a ‘Reverse ICANN’ naming scheme when the header contains grouping
// information, e.g. ‘example.main.component1’.
//
// –
// and its grouping information in a non-technical, human-readable way
// which could be used by a user interface. Groups should be separated by the
// path separator ‘/’, e.g. ‘Example/Main/Component 1’.
//
//
// RestKit Logging Components
//
_lcl_component(RestKit, “restkit”, “RestKit”)
_lcl_component(RestKitNetwork, “restkit.network”, “RestKit/Network”)
_lcl_component(RestKitNetworkCache, “restkit.network.cache”, “RestKit/Network/Cache”)
_lcl_component(RestKitNetworkQueue, “restkit.network.queue”, “RestKit/Network/Queue”)
_lcl_component(RestKitNetworkReachability, “restkit.network.reachability”, “RestKit/Network/Reachability”)
_lcl_component(RestKitObjectMapping, “restkit.object_mapping”, “RestKit/ObjectMapping”)
_lcl_component(RestKitCoreData, “restkit.core_data”, “RestKit/CoreData”)
_lcl_component(RestKitCoreDataCache, “restkit.core_data.cache”, “RestKit/CoreData/Cache”)
_lcl_component(RestKitCoreDataSearchEngine, “restkit.core_data.search_engine”, “RestKit/CoreData/SearchEngine”)
_lcl_component(RestKitSupport, “restkit.support”, “RestKit/Support”)
_lcl_component(RestKitSupportParsers, “restkit.support.parsers”, “RestKit/Support/Parsers”)
_lcl_component(RestKitThree20, “restkit.three20”, “RestKit/Three20”)
_lcl_component(RestKitUI, “restkit.ui”, “RestKit/UI”)
_lcl_component(RestKitTesting, “restkit.testing”, “RestKit/Testing”)
_lcl_component(App, “app”, “App”)
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._lcl_config_components.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/lcl_config_extensions.h
//
// lcl_config_extensions.h
// RestKit
//
// Created by Blake Watters on 6/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKLog.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._lcl_config_extensions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/lcl_config_logger.h
//
// lcl_config_logger.h
// RestKit
//
// Created by Blake Watters on 6/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// NSLog
#import “LCLNSLog.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._lcl_config_logger.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSArray+RKAdditions.h
//
// NSArray+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 4/10/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import
/**
Provides useful additions to the NSArray interface.
*/
@interface NSArray (RKAdditions)
/**
Evaluates a given key path against the receiving array, divides the array entries into
sections grouped by the value for the key path, and returns an aggregate array of arrays
containing the sections. The receiving array is assumed to be sorted.
@param keyPath The key path of the value to group the entries by.
@returns An array of section arrays, with each section containing a group of objects sharing
the same value for the given key path.
*/
– (NSArray *)sectionsGroupedByKeyPath:(NSString *)keyPath;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSArray+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSArray+RKAdditions.m
//
// NSArray+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 4/10/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import “NSArray+RKAdditions.h”
@implementation NSArray (RKAdditions)
– (NSArray *)sectionsGroupedByKeyPath:(NSString *)keyPath
{
// Code adapted from: https://gist.github.com/1243312
NSMutableArray *sections = [NSMutableArray array];
// If we don’t contain any items, return an empty collection of sections.
if([self count] == 0) {
return sections;
}
// Create the first section and establish the first section’s grouping value.
NSMutableArray *sectionItems = [NSMutableArray array];
id currentGroup = [[self objectAtIndex:0] valueForKeyPath:keyPath];
// Iterate over our items, placing them in the appropriate section and
// creating new sections when necessary.
for (id item in self) {
// Retrieve the grouping value from the current item.
id itemGroup = [item valueForKeyPath:keyPath];
// Compare the current item’s grouping value to the current section’s
// grouping value.
if (![itemGroup isEqual:currentGroup] && (currentGroup != nil || itemGroup != nil)) {
// The current item doesn’t belong in the current section, so
// store the section we’ve been building and create a new one,
// caching the new grouping value.
[sections addObject:sectionItems];
sectionItems = [NSMutableArray array];
currentGroup = itemGroup;
}
// Add the item to the appropriate section.
[sectionItems addObject:item];
}
// If we were adding items to a section that has not yet been added
// to the aggregate section collection, add it now.
if ([sectionItems count] > 0) {
[sections addObject:sectionItems];
}
return sections;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSArray+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSBundle+RKAdditions.h
//
// NSBundle+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 2/1/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#if TARGET_OS_IPHONE
#import
#endif
/**
Provides convenience methods for accessing data in resources
within an NSBundle.
*/
@interface NSBundle (RKAdditions)
/**
Returns an NSBundle reference to the RestKitResources.bundle file containing
RestKit specific resource assets.
This method is a convenience wrapper for invoking
`[NSBundle bundleWithIdentifier:@”org.restkit.RestKitResources”]`
@return An NSBundle object corresponding to the RestKitResources.bundle file.
*/
+ (NSBundle *)restKitResourcesBundle;
/**
Returns the MIME Type for the resource identified by the specified name and file extension.
@param name The name of the resource file.
@param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name.
@return The MIME Type for the resource file or nil if the file could not be located.
*/
– (NSString *)MIMETypeForResource:(NSString *)name withExtension:(NSString *)extension;
/**
Creates and returns a data object by reading every byte from the resource identified by the specified name and file extension.
@param name The name of the resource file.
@param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name.
@return A data object by reading every byte from the resource file.
*/
– (NSData *)dataWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension;
/**
Creates and returns a string object by reading data from the resource identified by the specified name and file extension using a given encoding.
@param name The name of the resource file.
@param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name.
@param encoding The encoding of the resource file.
@return A string created by reading data from the resource file using the encoding.
*/
– (NSString *)stringWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension encoding:(NSStringEncoding)encoding;
#if TARGET_OS_IPHONE
/**
Creates and returns an image object by loading the image data from the resource identified by the specified name and file extension.
@param name The name of the resource file.
@param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name.
@return A new image object for the specified file, or nil if the method could not initialize the image from the specified file.
*/
– (UIImage *)imageWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension;
#endif
/**
Creates and returns an object representation of the data from the resource identified by the specified name and file extension by reading the
data as a string and parsing it using a parser appropriate for the MIME Type of the file.
@param name The name of the resource file.
@param extension If extension is an empty string or nil, the extension is assumed not to exist and the file is the first file encountered that exactly matches name.
@return A new image object for the specified file, or nil if the method could not initialize the image from the specified file.
@see RKParserRegistry
*/
– (id)parsedObjectWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSBundle+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSBundle+RKAdditions.m
//
// NSBundle+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 2/1/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSBundle+RKAdditions.h”
#import “NSString+RKAdditions.h”
#import “UIImage+RKAdditions.h”
#import “RKLog.h”
#import “RKParser.h”
#import “RKParserRegistry.h”
@implementation NSBundle (RKAdditions)
+ (NSBundle *)restKitResourcesBundle {
static BOOL searchedForBundle = NO;
if (! searchedForBundle) {
NSString *path = [[NSBundle mainBundle] pathForResource:@”RestKitResources” ofType:@”bundle”];
searchedForBundle = YES;
NSBundle *resourcesBundle = [NSBundle bundleWithPath:path];
if (! resourcesBundle) RKLogWarning(@”Unable to find RestKitResources.bundle in your project. Did you forget to add it?”);
return resourcesBundle;
}
return [NSBundle bundleWithIdentifier:@”org.restkit.RestKitResources”];
}
– (NSString *)MIMETypeForResource:(NSString *)name withExtension:(NSString *)extension {
NSString *resourcePath = [self pathForResource:name ofType:extension];
if (resourcePath) {
return [resourcePath MIMETypeForPathExtension];
}
return nil;
}
– (NSData *)dataWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension {
NSString *resourcePath = [self pathForResource:name ofType:extension];
if (! resourcePath) {
RKLogWarning(@”%@ Failed to locate Resource with name ‘%@’ and extension ‘%@’: File Not Found.”, self, resourcePath, extension);
return nil;
}
return [NSData dataWithContentsOfFile:resourcePath];
}
– (NSString *)stringWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension encoding:(NSStringEncoding)encoding {
NSError* error = nil;
NSString *resourcePath = [self pathForResource:name ofType:extension];
if (! resourcePath) {
RKLogWarning(@”%@ Failed to locate Resource with name ‘%@’ and extension ‘%@’: File Not Found.”, self, resourcePath, extension);
return nil;
}
NSString* fixtureData = [NSString stringWithContentsOfFile:resourcePath encoding:encoding error:&error];
if (fixtureData == nil && error) {
RKLogWarning(@”Failed to read “);
}
return fixtureData;
}
#if TARGET_OS_IPHONE
– (UIImage *)imageWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension {
NSString *resourcePath = [self pathForResource:name ofType:extension];
if (! resourcePath) {
RKLogWarning(@”%@ Failed to locate Resource with name ‘%@’ and extension ‘%@’: File Not Found.”, self, resourcePath, extension);
return nil;
}
return [UIImage imageWithContentsOfResolutionIndependentFile:resourcePath];
}
#endif
– (id)parsedObjectWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension {
NSError* error = nil;
NSString* resourceContents = [self stringWithContentsOfResource:name withExtension:extension encoding:NSUTF8StringEncoding];
NSString* MIMEType = [self MIMETypeForResource:name withExtension:extension];
id
if (! parser) {
RKLogError(@”%@ Unable to parse Resource with name ‘%@’ and extension ‘%@’: failed to find parser registered to handle MIME Type ‘%@'”, self, name, extension, MIMEType);
return nil;
}
id object = [parser objectFromString:resourceContents error:&error];
if (object == nil) {
RKLogCritical(@”%@ Failed to parse resource with name ‘%@’ and extension ‘%@’. Error: %@”, self, name, extension, [error localizedDescription]);
return nil;
}
return object;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSBundle+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSDictionary+RKAdditions.h
//
// NSDictionary+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
Provides useful additions to the NSDictionary interface.
*/
@interface NSDictionary (RKAdditions)
/**
Creates and initializes a dictionary with key value pairs, with the keys specified
first instead of the objects.
*/
+ (id)dictionaryWithKeysAndObjects:(id)firstKey, … NS_REQUIRES_NIL_TERMINATION;
/**
Return a new dictionary by stripping out any percent escapes (such as %20)
from the receiving dictionary’s key and values.
@return A new dictionary wherein any percent escape sequences in the key and values
have been replaced with their literal values.
*/
– (NSDictionary *)dictionaryByReplacingPercentEscapesInEntries;
/**
Returns a dictionary by digesting a URL encoded set of key/value pairs into unencoded
values. Keys that appear multiple times with the string are decoded into an array of
values.
*/
+ (NSDictionary *)dictionaryWithURLEncodedString:(NSString *)URLEncodedString;
/**
Returns a representation of the dictionary as a URLEncoded string
@returns A UTF-8 encoded string representation of the keys/values in the dictionary
*/
– (NSString *)stringWithURLEncodedEntries;
– (NSString *)URLEncodedString; // TODO: Deprecated..
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSDictionary+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSDictionary+RKAdditions.m
//
// NSDictionary+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSDictionary+RKAdditions.h”
#import “NSString+RKAdditions.h”
#import “RKFixCategoryBug.h”
RK_FIX_CATEGORY_BUG(NSDictionary_RKAdditions)
@implementation NSDictionary (RKAdditions)
+ (id)dictionaryWithKeysAndObjects:(id)firstKey, … {
va_list args;
va_start(args, firstKey);
NSMutableArray* keys = [NSMutableArray array];
NSMutableArray* values = [NSMutableArray array];
for (id key = firstKey; key != nil; key = va_arg(args, id)) {
id value = va_arg(args, id);
[keys addObject:key];
[values addObject:value];
}
va_end(args);
return [self dictionaryWithObjects:values forKeys:keys];
}
– (NSDictionary *)dictionaryByReplacingPercentEscapesInEntries {
NSMutableDictionary *results = [NSMutableDictionary dictionaryWithCapacity:[self count]];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop)
{
NSString *escapedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
id escapedValue = value;
if ([value respondsToSelector:@selector(stringByReplacingPercentEscapesUsingEncoding:)])
escapedValue = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[results setObject:escapedValue forKey:escapedKey];
}];
return results;
}
// TODO: Unit tests…
+ (NSDictionary *)dictionaryWithURLEncodedString:(NSString *)URLEncodedString {
NSMutableDictionary *queryComponents = [NSMutableDictionary dictionary];
for(NSString *keyValuePairString in [URLEncodedString componentsSeparatedByString:@”&”]) {
NSArray *keyValuePairArray = [keyValuePairString componentsSeparatedByString:@”=”];
if ([keyValuePairArray count] < 2) continue; // Verify that there is at least one key, and at least one value. Ignore extra = signs
NSString *key = [[keyValuePairArray objectAtIndex:0] stringByReplacingURLEncoding];
NSString *value = [[keyValuePairArray objectAtIndex:1] stringByReplacingURLEncoding];
// URL spec says that multiple values are allowed per key
id results = [queryComponents objectForKey:key];
if(results) {
if ([results isKindOfClass:[NSMutableArray class]]) {
[(NSMutableArray *)results addObject:value];
} else {
// On second occurrence of the key, convert into an array
NSMutableArray *values = [NSMutableArray arrayWithObjects:results, value, nil];
[queryComponents setObject:values forKey:key];
}
} else {
[queryComponents setObject:value forKey:key];
}
[results addObject:value];
}
return queryComponents;
}
- (void)URLEncodePart:(NSMutableArray*)parts path:(NSString*)path value:(id)value {
NSString *encodedPart = [[value description] stringByAddingURLEncoding];
[parts addObject:[NSString stringWithFormat: @"%@=%@", path, encodedPart]];
}
- (void)URLEncodeParts:(NSMutableArray*)parts path:(NSString*)inPath {
[self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
NSString *encodedKey = [[key description] stringByAddingURLEncoding];
NSString *path = inPath ? [inPath stringByAppendingFormat:@"[%@]", encodedKey] : encodedKey;
if ([value isKindOfClass:[NSArray class]]) {
for (id item in value) {
if ([item isKindOfClass:[NSDictionary class]] || [item isKindOfClass:[NSMutableDictionary class]]) {
[item URLEncodeParts:parts path:[path stringByAppendingString:@"[]"]];
} else {
[self URLEncodePart:parts path:[path stringByAppendingString:@"[]"] value:item];
}
}
} else if([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSMutableDictionary class]]) {
[value URLEncodeParts:parts path:path];
}
else {
[self URLEncodePart:parts path:path value:value];
}
}];
}
- (NSString *)stringWithURLEncodedEntries {
NSMutableArray* parts = [NSMutableArray array];
[self URLEncodeParts:parts path:nil];
return [parts componentsJoinedByString:@"&"];
}
- (NSString *)URLEncodedString {
return [self stringWithURLEncodedEntries];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSDictionary+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSString+RKAdditions.h
//
// NSString+RestKit.h
// RestKit
//
// Created by Blake Watters on 6/15/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
A library of helpful additions to the NSString class to simplify
common tasks within RestKit
*/
@interface NSString (RKAdditions)
/**
Returns a resource path from a dictionary of query parameters URL encoded and appended
This is a convenience method for constructing a new resource path that includes a query. For example,
when given a resourcePath of /contacts and a dictionary of parameters containing foo=bar and color=red,
will return /contacts?foo=bar&color=red
*NOTE* – Assumes that the resource path does not already contain any query parameters.
@param queryParameters A dictionary of query parameters to be URL encoded and appended to the resource path
@return A new resource path with the query parameters appended
*/
– (NSString *)stringByAppendingQueryParameters:(NSDictionary *)queryParameters;
– (NSString *)appendQueryParams:(NSDictionary*)queryParams DEPRECATED_ATTRIBUTE;
/**
Convenience method for generating a path against the properties of an object. Takes
a string with property names prefixed with a colon and interpolates the values of
the properties specified and returns the generated path.
For example, given an ‘article’ object with an ‘articleID’ property of 12345
[@”articles/:articleID” interpolateWithObject:article] would generate @”articles/12345″
This functionality is the basis for resource path generation in the Router.
@param object The object to interpolate the properties against
@see RKMakePathWithObject
@see RKPathMatcher
*/
– (NSString *)interpolateWithObject:(id)object;
/**
Returns a dictionary of parameter keys and values using UTF-8 encoding given a URL-style query string
on the receiving object. For example, when given the string /contacts?foo=bar&color=red,
this will return a dictionary of parameters containing foo=bar and color=red, excluding the path “/contacts?”
@param receiver A string in the form of @”/object/?sortBy=name”, or @”/object/?sortBy=name&color=red”
@return A new dictionary of query parameters, with keys like ‘sortBy’ and values like ‘name’.
*/
– (NSDictionary *)queryParameters;
/**
Returns a dictionary of parameter keys and values given a URL-style query string
on the receiving object. For example, when given the string /contacts?foo=bar&color=red,
this will return a dictionary of parameters containing foo=bar and color=red, excludes the path “/contacts?”
This method originally appeared as queryContentsUsingEncoding: in the Three20 project:
https://github.com/facebook/three20/blob/master/src/Three20Core/Sources/NSStringAdditions.m
@param receiver A string in the form of @”/object/?sortBy=name”, or @”/object/?sortBy=name&color=red”
@param encoding The encoding for to use while parsing the query string.
@return A new dictionary of query parameters, with keys like ‘sortBy’ and values like ‘name’.
*/
– (NSDictionary *)queryParametersUsingEncoding:(NSStringEncoding)encoding;
/**
Returns a dictionary of parameter keys and values arrays (if requested) given a URL-style query string
on the receiving object. For example, when given the string /contacts?foo=bar&color=red,
this will return a dictionary of parameters containing foo=[bar] and color=[red], excludes the path “/contacts?”
This method originally appeared as queryContentsUsingEncoding: in the Three20 project:
https://github.com/facebook/three20/blob/master/src/Three20Core/Sources/NSStringAdditions.m
@param receiver A string in the form of @”/object?sortBy=name”, or @”/object?sortBy=name&color=red”
@param shouldUseArrays If NO, it yields the same results as queryParametersUsingEncoding:, otherwise it creates value arrays instead of value strings.
@param encoding The encoding for to use while parsing the query string.
@return A new dictionary of query parameters, with keys like ‘sortBy’ and value arrays (if requested) like [‘name’].
@see queryParametersUsingEncoding:
*/
– (NSDictionary *)queryParametersUsingArrays:(BOOL)shouldUseArrays encoding:(NSStringEncoding)encoding;
/**
Returns a URL encoded representation of self.
*/
– (NSString *)stringByAddingURLEncoding;
/**
Returns a representation of self with percent URL encoded characters replaced with
their literal values.
*/
– (NSString *)stringByReplacingURLEncoding;
/**
Returns a new string made by appending a path component to the original string,
along with a trailing slash if the component is designated a directory.
@param pathComponent The path component to add to the URL.
@param isDirectory: If TRUE, a trailing slash is appended after pathComponent.
@return A new string with pathComponent appended.
*/
– (NSString *)stringByAppendingPathComponent:(NSString *)pathComponent isDirectory:(BOOL)isDirectory;
/**
Interprets the receiver as a path and returns the MIME Type for the path extension
using Core Services.
For example, given a string with the path /Users/blake/Documents/monkey.json we would get
@”application/json” as the MIME Type.
@return The expected MIME Type of the resource identified by the path or nil if unknown
*/
– (NSString *)MIMETypeForPathExtension;
/**
Returns YES if the receiver contains a valid IP address
For example, @”127.0.0.1″ and @”10.0.1.35″ would return YES
while @”restkit.org” would return NO
*/
– (BOOL)isIPAddress;
/**
Returns a string of the MD5 sum of the receiver.
@return A new string containing the MD5 sum of the receiver.
*/
– (NSString *)MD5;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSString+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSString+RKAdditions.m
//
// NSString+RestKit.m
// RestKit
//
// Created by Blake Watters on 6/15/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#else
#import
#endif
#import
#include
#include
#import “NSString+RKAdditions.h”
#import “NSDictionary+RKAdditions.h”
#import “RKFixCategoryBug.h”
#import “RKPathMatcher.h”
RK_FIX_CATEGORY_BUG(NSString_RKAdditions)
@implementation NSString (RKAdditions)
– (NSString *)stringByAppendingQueryParameters:(NSDictionary *)queryParameters {
if ([queryParameters count] > 0) {
return [NSString stringWithFormat:@”%@?%@”, self, [queryParameters stringWithURLEncodedEntries]];
}
return [NSString stringWithString:self];
}
// Deprecated
– (NSString *)appendQueryParams:(NSDictionary *)queryParams {
return [self stringByAppendingQueryParameters:queryParams];
}
– (NSString *)interpolateWithObject:(id)object addingEscapes:(BOOL)addEscapes {
NSCAssert(object != NULL, @”Object provided is invalid; cannot create a path from a NULL object”);
RKPathMatcher *matcher = [RKPathMatcher matcherWithPattern:self];
NSString *interpolatedPath = [matcher pathFromObject:object addingEscapes:addEscapes];
return interpolatedPath;
}
– (NSString *)interpolateWithObject:(id)object {
return [self interpolateWithObject:object addingEscapes:YES];
}
– (NSDictionary *)queryParameters {
return [self queryParametersUsingEncoding:NSUTF8StringEncoding];
}
– (NSDictionary*)queryParametersUsingEncoding:(NSStringEncoding)encoding {
return [self queryParametersUsingArrays:NO encoding:encoding];
}
// TODO: Eliminate…
– (NSDictionary*)queryParametersUsingArrays:(BOOL)shouldUseArrays encoding:(NSStringEncoding)encoding {
NSString *stringToParse = self;
NSRange chopRange = [stringToParse rangeOfString:@”?”];
if (chopRange.length > 0) {
chopRange.location+=1; // we want inclusive chopping up *through* “?”
if (chopRange.location < [stringToParse length])
stringToParse = [stringToParse substringFromIndex:chopRange.location];
}
NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
NSScanner* scanner = [[[NSScanner alloc] initWithString:stringToParse] autorelease];
while (![scanner isAtEnd]) {
NSString* pairString = nil;
[scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
[scanner scanCharactersFromSet:delimiterSet intoString:NULL];
NSArray* kvPair = [pairString componentsSeparatedByString:@"="];
if (!shouldUseArrays) {
if (kvPair.count == 2) {
NSString* key = [[kvPair objectAtIndex:0]
stringByReplacingPercentEscapesUsingEncoding:encoding];
NSString* value = [[kvPair objectAtIndex:1]
stringByReplacingPercentEscapesUsingEncoding:encoding];
[pairs setObject:value forKey:key];
}
}
else {
if (kvPair.count == 1 || kvPair.count == 2) {
NSString* key = [[kvPair objectAtIndex:0]
stringByReplacingPercentEscapesUsingEncoding:encoding];
NSMutableArray* values = [pairs objectForKey:key];
if (nil == values) {
values = [NSMutableArray array];
[pairs setObject:values forKey:key];
}
if (kvPair.count == 1) {
[values addObject:[NSNull null]];
} else if (kvPair.count == 2) {
NSString* value = [[kvPair objectAtIndex:1]
stringByReplacingPercentEscapesUsingEncoding:encoding];
[values addObject:value];
}
}
}
}
return [NSDictionary dictionaryWithDictionary:pairs];
}
// NOTE: See http://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters
- (NSString *)stringByAddingURLEncoding {
CFStringRef legalURLCharactersToBeEscaped = CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`\n\r”);
CFStringRef encodedString = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
NULL,
legalURLCharactersToBeEscaped,
kCFStringEncodingUTF8);
if (encodedString) {
return [(NSString *)encodedString autorelease];
}
// TODO: Log a warning?
return @””;
}
– (NSString *)stringByReplacingURLEncoding {
return [self stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
– (NSDictionary *)fileExtensionsToMIMETypesDictionary {
return [NSDictionary dictionaryWithObjectsAndKeys:@”application/json”, @”json”, nil];
}
– (NSString *)MIMETypeForPathExtension {
NSString *fileExtension = [self pathExtension];
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef) fileExtension, NULL);
if (uti != NULL) {
CFStringRef mime = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType);
CFRelease(uti);
if (mime != NULL) {
NSString *type = [NSString stringWithString:(NSString *)mime];
CFRelease(mime);
return type;
}
}
// Consult our internal dictionary of mappings if not found
return [[self fileExtensionsToMIMETypesDictionary] valueForKey:fileExtension];
}
– (BOOL)isIPAddress {
struct sockaddr_in sa;
char *hostNameOrIPAddressCString = (char *) [self UTF8String];
int result = inet_pton(AF_INET, hostNameOrIPAddressCString, &(sa.sin_addr));
return (result != 0);
}
– (NSString *)stringByAppendingPathComponent:(NSString *)pathComponent isDirectory:(BOOL)isDirectory {
NSString *stringWithPathComponent = [self stringByAppendingPathComponent:pathComponent];
if (isDirectory) return [stringWithPathComponent stringByAppendingString:@”/”];
return stringWithPathComponent;
}
– (NSString *)MD5 {
// Create pointer to the string as UTF8
const char* ptr = [self UTF8String];
// Create byte array of unsigned chars
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
// Create 16 byte MD5 hash value, store in buffer
CC_MD5(ptr, (CC_LONG) strlen(ptr), md5Buffer);
// Convert MD5 value in the buffer to NSString of hex values
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x",md5Buffer[i]];
}
return output;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSString+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSURL+RKAdditions.h
//
// NSURL+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 10/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@interface NSURL (RKAdditions)
/**
Returns the query portion of the URL as a dictionary
*/
– (NSDictionary *)queryParameters;
/**
Returns the MIME Type for the resource identified by the URL by interpretting the
path extension using Core Services.
For example, given a URL to http://restkit.org/monkey.json we would get
@”application/json” as the MIME Type.
@return The expected MIME Type of the resource identified by the URL or nil if unknown
*/
– (NSString *)MIMETypeForPathExtension;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSURL+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/NSURL+RKAdditions.m
//
// NSURL+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 10/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “NSURL+RKAdditions.h”
#import “NSDictionary+RKAdditions.h”
#import “RKFixCategoryBug.h”
#import “NSString+RKAdditions.h”
RK_FIX_CATEGORY_BUG(NSURL_RKAdditions)
@implementation NSURL (RKAdditions)
– (NSDictionary *)queryParameters {
return [NSDictionary dictionaryWithURLEncodedString:self.query];
}
– (NSString *)MIMETypeForPathExtension {
return [[self path] MIMETypeForPathExtension];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._NSURL+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/JSON/RKJSONParserJSONKit.h
//
// RKJSONParserJSONKit.h
// RestKit
//
// Created by Blake Watters on 5/14/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKParser.h”
@interface RKJSONParserJSONKit : NSObject
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/JSON/._RKJSONParserJSONKit.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/JSON/RKJSONParserJSONKit.m
//
// RKJSONParserJSONKit.m
// RestKit
//
// Created by Jeff Arena on 3/16/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKJSONParserJSONKit.h”
#import “JSONKit.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitSupportParsers
// TODO: JSONKit serializer instance should be reused to enable leverage
// the internal caching capabilities from the JSONKit serializer
@implementation RKJSONParserJSONKit
– (NSDictionary*)objectFromString:(NSString*)string error:(NSError**)error {
RKLogTrace(@”string=’%@'”, string);
return [string objectFromJSONStringWithParseOptions:JKParseOptionStrict error:error];
}
– (NSString*)stringFromObject:(id)object error:(NSError**)error {
return [object JSONStringWithOptions:JKSerializeOptionNone error:error];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/JSON/._RKJSONParserJSONKit.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/._JSON
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/XML/RKXMLParserXMLReader.h
//
// RKXMLParserXMLReader.h
// RestKit
//
// Created by Christopher Swasey on 1/24/12.
// Copyright (c) 2012 GateGuru. All rights reserved.
//
/**
Provides a basic XML implementation using an adapted version
of the XMLReader class by “Insert-Witty-Name” available at:
https://github.com/RestKit/XML-to-NSDictionary
RKXMLParserXMLReader will parse an XML document into an NSDictionary
representation suitable for use with RestKit’s key-value coding based
object mapping implementation.
XML attributes are represented as keys in a dictionary.
**NOTE** When an XML tag is parsed containing both XML attributes and
an enclosed text node, the value of the text node will be inserted in
the parsed dictionary at the `@”text”` key.
*/
#import “XMLReader.h”
#import “RKParser.h”
@interface RKXMLParserXMLReader : NSObject
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/XML/._RKXMLParserXMLReader.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/XML/RKXMLParserXMLReader.m
//
// RKXMLParserXMLReader.m
// RestKit
//
// Created by Christopher Swasey on 1/24/12.
// Copyright (c) 2012 GateGuru. All rights reserved.
//
#import “RKXMLParserXMLReader.h”
@implementation RKXMLParserXMLReader
– (id)objectFromString:(NSString*)string error:(NSError**)error {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [XMLReader dictionaryForXMLData:data error:error];
}
– (NSString*)stringFromObject:(id)object error:(NSError**)error {
return nil;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/XML/._RKXMLParserXMLReader.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Parsers/._XML
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._Parsers
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RestKit-Prefix.pch
//
// Prefix header for all source files of the ‘RestKit’ target in the ‘RestKit’ project
//
#ifdef __OBJC__
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RestKit-Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKAlert.h
//
// RKAlert.h
// RestKit
//
// Created by Blake Watters on 4/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
* Presents an alert dialog with the specified message
*/
void RKAlert(NSString* message);
/**
* Presents an alert dialog with the specified message and title
*/
void RKAlertWithTitle(NSString* message, NSString* title);
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKAlert.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKAlert.m
//
// RKAlert.m
// RestKit
//
// Created by Blake Watters on 4/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#elif TARGET_OS_MAC
#import
#endif
#import “RKAlert.h”
#import “RKLog.h”
void RKAlert(NSString* message) {
RKAlertWithTitle(message, @”Alert”);
}
void RKAlertWithTitle(NSString* message, NSString* title) {
#if TARGET_OS_IPHONE
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(@”OK”, nil)
otherButtonTitles:nil];
[alertView show];
[alertView release];
#elif TARGET_OS_MAC
Class alertClass = NSClassFromString(@”NSAlert”);
if (alertClass) {
NSAlert *alert = [[alertClass alloc] init];
[alert setMessageText:message];
[alert setInformativeText:message];
[alert addButtonWithTitle:NSLocalizedString(@”OK”, nil)];
[alert runModal];
[alert release];
} else {
RKLogCritical(@”%@: %@”, title, message);
}
#elif TARGET_OS_UNIX
RKLogCritical(@”%@: %@”, title, message);
#endif
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKAlert.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKBenchmark.h
//
// RKBenchmark.h
// RestKit
//
// Derived from Benchmark class: https://gist.github.com/1479490
// Created by Sijawusz Pur Rahnama on 03/02/09.
// Copyleft 2009. Some rights reserved.
//
#import
/**
RKBenchmark objects provide a simple, lightweight interface for
quickly benchmarking the performance of units of code. Benchmark
objects can be used procedurally, by manually starting & stopping
the benchmark, or using a block interface to measure the execution
time of the block.
*/
@interface RKBenchmark : NSObject
///—————————————————————————–
/// @name Accessing Benchmark Values
///—————————————————————————–
/**
A name for the benchmark. Can be nil.
*/
@property (nonatomic, retain) NSString *name;
/**
The start time of the benchmark as an absolute time value.
*/
@property (nonatomic, assign, readonly) CFAbsoluteTime startTime;
/**
The end time of the benchmark as an absolute time value.
*/
@property (nonatomic, assign, readonly) CFAbsoluteTime endTime;
/**
The elapsed time of the benchmark as determined by subtracting the
end time from the start time. Returns zero until the benchmark has
been stopped.
*/
@property (nonatomic, assign, readonly) CFTimeInterval elapsedTime;
///—————————————————————————–
/// @name Quickly Performing Benchmarks
///—————————————————————————–
/**
*/
+ (id)report:(NSString *)info executionBlock:(void (^)(void))block;
/**
Performs a benchmark and returns a time interval measurement of the
total time elapsed during the execution of the blocl.
@param block A block to execute and measure the elapsed time during execution.
@return A time interval equal to the total time elapsed during execution.
*/
+ (CFTimeInterval)measureWithExecutionBlock:(void (^)(void))block;
///—————————————————————————–
/// @name Creating Benchmark Objects
///—————————————————————————–
/**
Retrieves or creates a benchmark object instance with a given name.
@param name A name for the benchmark.
@return A new or existing benchmark object with the given name.
*/
+ (RKBenchmark *)instanceWithName:(NSString *)name;
/**
Creates and returns a benchmark object with a name.
@param name A name for the benchmark.
@return A new benchmark object with the given name.
*/
+ (id)benchmarkWithName:(NSString *)name;
/**
Initializes a new benchmark object with a name.
@param name The name to initialize the receiver with.
@return The receiver, initialized with the given name.
*/
– (id)initWithName:(NSString *)name;
///—————————————————————————–
/// @name Performing Benchmarks
///—————————————————————————–
/**
Runs a benchmark by starting the receiver, executing the block, and then stopping
the benchmark object.
@param executionBlock A block to execute as the body of the benchmark.
*/
– (void)run:(void (^)(void))executionBlock;
/**
Starts the benchmark by recording the start time.
*/
– (void)start;
/**
Stops the benchmark by recording the stop time.
*/
– (void)stop;
/**
Logs the current benchmark status. If the receiver has been stopped, the
elapsed time of the benchmark is logged. If the benchmark is still running,
the total time since the benchmark was started is logged.
*/
– (void)log;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKBenchmark.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKBenchmark.m
//
// RKBenchmark.h
// RestKit
//
// Derived from Benchmark class: https://gist.github.com/1479490
// Created by Sijawusz Pur Rahnama on 03/02/09.
// Copyleft 2009. Some rights reserved.
//
#import “RKBenchmark.h”
@interface RKBenchmark ()
@property (nonatomic, assign, readwrite) CFAbsoluteTime startTime;
@property (nonatomic, assign, readwrite) CFAbsoluteTime endTime;
@property (nonatomic, assign, readwrite) CFTimeInterval elapsedTime;
@property (nonatomic, assign, getter = isStopped) BOOL stopped;
@end
@implementation RKBenchmark
static NSMutableDictionary * __sharedBenchmarks = nil;
+ (NSMutableDictionary *)sharedBenchmarks {
if (!__sharedBenchmarks) {
__sharedBenchmarks = [[NSMutableDictionary alloc] init];
}
return __sharedBenchmarks;
}
+ (id)instanceWithName:(NSString *)name {
@synchronized (self) {
// get the benchmark or create it on-the-fly
id benchmark = [[self sharedBenchmarks] objectForKey:name];
if (!benchmark) {
benchmark = [self benchmarkWithName:name];
[[self sharedBenchmarks] setObject:benchmark forKey:name];
}
return benchmark;
}
return nil;
}
@synthesize name = _name;
@synthesize startTime = _startTime;
@synthesize endTime = _endTime;
@synthesize elapsedTime = _elapsedTime;
@synthesize stopped = _stopped;
# pragma mark –
# pragma mark Quick access class methods
+ (id)report:(NSString *)info executionBlock:(void (^)(void))block {
RKBenchmark *benchmark = [self instanceWithName:info];
[benchmark run:block];
[benchmark log];
return benchmark;
}
+ (CFTimeInterval)measureWithExecutionBlock:(void (^)(void))block {
RKBenchmark *benchmark = [[self new] autorelease];
[benchmark run:block];
return benchmark.elapsedTime;
}
# pragma mark –
# pragma mark Initializers
+ (id)benchmarkWithName:(NSString *)name {
return [[[self alloc] initWithName:name] autorelease];
}
– (id)initWithName:(NSString *)name {
if (self = [self init]) {
self.name = name;
}
return self;
}
# pragma mark –
# pragma mark Benchmark methods
– (void)run:(void (^)(void))executionBlock {
[self start];
executionBlock();
[self stop];
}
– (void)start {
self.startTime = CFAbsoluteTimeGetCurrent();
}
– (void)stop {
self.endTime = CFAbsoluteTimeGetCurrent();
self.stopped = YES;
// Calculate elapsed time
CFDateRef startDate = CFDateCreate(NULL, self.startTime);
CFDateRef endDate = CFDateCreate(NULL, self.endTime);
self.elapsedTime = CFDateGetTimeIntervalSinceDate(endDate, startDate);
CFRelease(startDate);
CFRelease(endDate);
}
– (void)log {
CFTimeInterval timeElapsed;
if (self.isStopped) {
timeElapsed = self.elapsedTime;
} else {
CFDateRef startDate = CFDateCreate(NULL, self.startTime);
timeElapsed = CFDateGetTimeIntervalSinceDate(startDate, (CFDateRef)[NSDate date]);
CFRelease(startDate);
}
// log elapsed time
if (_name) NSLog(@”Benchmark ‘%@’ took %f seconds.”, _name, timeElapsed);
else NSLog(@”Benchmark took %f seconds.”, timeElapsed);
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKBenchmark.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKCache.h
//
// RKCache.h
// RestKit
//
// Created by Jeff Arena on 8/26/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
@interface RKCache : NSObject {
NSString* _cachePath;
NSRecursiveLock* _cacheLock;
}
@property (nonatomic, readonly) NSString* cachePath;
– (id)initWithPath:(NSString*)cachePath subDirectories:(NSArray*)subDirectories;
– (BOOL)hasEntry:(NSString*)cacheKey;
– (void)invalidateEntry:(NSString*)cacheKey;
– (void)invalidateSubDirectory:(NSString*)subDirectory;
– (void)invalidateAll;
– (void)writeDictionary:(NSDictionary*)dictionary withCacheKey:(NSString*)cacheKey;
– (void)writeData:(NSData*)data withCacheKey:(NSString*)cacheKey;
– (NSDictionary*)dictionaryForCacheKey:(NSString*)cacheKey ;
– (NSData*)dataForCacheKey:(NSString*)cacheKey;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKCache.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKCache.m
//
// RKCache.h
// RestKit
//
// Created by Jeff Arena on 8/26/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKCache.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitSupport
@implementation RKCache
– (id)initWithPath:(NSString*)cachePath subDirectories:(NSArray*)subDirectories {
self = [super init];
if (self) {
_cachePath = [cachePath copy];
_cacheLock = [[NSRecursiveLock alloc] init];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSMutableArray* pathArray = [NSMutableArray arrayWithObject:_cachePath];
for (NSString* subDirectory in subDirectories) {
[pathArray addObject:[_cachePath stringByAppendingPathComponent:subDirectory]];
}
for (NSString* path in pathArray) {
BOOL isDirectory = NO;
BOOL fileExists = [fileManager fileExistsAtPath:path isDirectory:&isDirectory];
if (!fileExists) {
NSError* error = nil;
BOOL created = [fileManager createDirectoryAtPath:path
withIntermediateDirectories:YES
attributes:nil
error:&error];
if (!created || error != nil) {
RKLogError(@”Failed to create cache directory at %@: error %@”, path, [error localizedDescription]);
} else {
RKLogDebug(@”Created cache storage at path ‘%@'”, path);
}
} else {
if (!isDirectory) {
RKLogWarning(@”Skipped creation of cache directory as non-directory file exists at path: %@”, path);
}
}
}
}
return self;
}
– (void)dealloc {
[_cachePath release];
_cachePath = nil;
[_cacheLock release];
_cacheLock = nil;
[super dealloc];
}
– (NSString*)cachePath {
return _cachePath;
}
– (NSString*)pathForCacheKey:(NSString*)cacheKey {
[_cacheLock lock];
NSString* pathForCacheKey = [_cachePath stringByAppendingPathComponent:cacheKey];
[_cacheLock unlock];
RKLogTrace(@”Found cachePath ‘%@’ for %@”, pathForCacheKey, cacheKey);
return pathForCacheKey;
}
– (BOOL)hasEntry:(NSString*)cacheKey {
[_cacheLock lock];
BOOL hasEntry = NO;
NSFileManager* fileManager = [NSFileManager defaultManager];
NSString* cachePath = [self pathForCacheKey:cacheKey];
hasEntry = [fileManager fileExistsAtPath:cachePath];
[_cacheLock unlock];
RKLogTrace(@”Determined hasEntry: %@ => %@”, cacheKey, hasEntry ? @”YES” : @”NO”);
return hasEntry;
}
– (void)writeDictionary:(NSDictionary*)dictionary withCacheKey:(NSString*)cacheKey {
if (dictionary) {
[_cacheLock lock];
RKLogTrace(@”Writing dictionary to cache key: ‘%@'”, cacheKey);
BOOL success = [dictionary writeToFile:[self pathForCacheKey:cacheKey] atomically:YES];
if (success) {
RKLogTrace(@”Wrote cached dictionary to cacheKey ‘%@'”, cacheKey);
} else {
RKLogError(@”Failed to write cached dictionary to cacheKey ‘%@'”, cacheKey);
}
[_cacheLock unlock];
}
}
– (void)writeData:(NSData*)data withCacheKey:(NSString*)cacheKey {
if (data) {
[_cacheLock lock];
NSString* cachePath = [self pathForCacheKey:cacheKey];
if (cachePath) {
NSError* error = nil;
BOOL success = [data writeToFile:cachePath options:NSDataWritingAtomic error:&error];
if (success) {
RKLogTrace(@”Wrote cached data to path ‘%@'”, cachePath);
} else {
RKLogError(@”Failed to write cached data to path ‘%@’: %@”, cachePath, [error localizedDescription]);
}
}
[_cacheLock unlock];
}
}
– (NSDictionary*)dictionaryForCacheKey:(NSString*)cacheKey {
[_cacheLock lock];
NSDictionary* dictionary = nil;
NSString* cachePath = [self pathForCacheKey:cacheKey];
if (cachePath) {
dictionary = [NSDictionary dictionaryWithContentsOfFile:cachePath];
if (dictionary) {
RKLogDebug(@”Read cached dictionary ‘%@’ from cachePath ‘%@’ for ‘%@'”, dictionary, cachePath, cacheKey);
} else {
RKLogDebug(@”Read nil cached dictionary from cachePath ‘%@’ for ‘%@'”, cachePath, cacheKey);
}
} else {
RKLogDebug(@”Unable to read cached dictionary for ‘%@’: cachePath not found”, cacheKey);
}
[_cacheLock unlock];
return dictionary;
}
– (NSData*)dataForCacheKey:(NSString*)cacheKey {
[_cacheLock lock];
NSData* data = nil;
NSString* cachePath = [self pathForCacheKey:cacheKey];
if (cachePath) {
data = [NSData dataWithContentsOfFile:cachePath];
if (data) {
RKLogDebug(@”Read cached data ‘%@’ from cachePath ‘%@’ for ‘%@'”, data, cachePath, cacheKey);
} else {
RKLogDebug(@”Read nil cached data from cachePath ‘%@’ for ‘%@'”, cachePath, cacheKey);
}
}
[_cacheLock unlock];
return data;
}
– (void)invalidateEntry:(NSString*)cacheKey {
[_cacheLock lock];
RKLogDebug(@”Invalidating cache entry for ‘%@'”, cacheKey);
NSString* cachePath = [self pathForCacheKey:cacheKey];
if (cachePath) {
NSFileManager* fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:cachePath error:NULL];
RKLogTrace(@”Removed cache entry at path ‘%@’ for ‘%@'”, cachePath, cacheKey);
}
[_cacheLock unlock];
}
– (void)invalidateSubDirectory:(NSString*)subDirectory {
[_cacheLock lock];
if (_cachePath && subDirectory) {
NSString* subDirectoryPath = [_cachePath stringByAppendingPathComponent:subDirectory];
RKLogInfo(@”Invalidating cache at path: %@”, subDirectoryPath);
NSFileManager* fileManager = [NSFileManager defaultManager];
BOOL isDirectory = NO;
BOOL fileExists = [fileManager fileExistsAtPath:subDirectoryPath isDirectory:&isDirectory];
if (fileExists && isDirectory) {
NSError* error = nil;
NSArray* cacheEntries = [fileManager contentsOfDirectoryAtPath:subDirectoryPath error:&error];
if (nil == error) {
for (NSString* cacheEntry in cacheEntries) {
NSString* cacheEntryPath = [subDirectoryPath stringByAppendingPathComponent:cacheEntry];
[fileManager removeItemAtPath:cacheEntryPath error:&error];
if (nil != error) {
RKLogError(@”Failed to delete cache entry for file: %@”, cacheEntryPath);
}
}
} else {
RKLogWarning(@”Failed to fetch list of cache entries for cache path: %@”, subDirectoryPath);
}
}
}
[_cacheLock unlock];
}
– (void)invalidateAll {
[_cacheLock lock];
if (_cachePath) {
RKLogInfo(@”Invalidating cache at path: %@”, _cachePath);
NSFileManager* fileManager = [NSFileManager defaultManager];
BOOL isDirectory = NO;
BOOL fileExists = [fileManager fileExistsAtPath:_cachePath isDirectory:&isDirectory];
if (fileExists && isDirectory) {
NSError* error = nil;
NSArray* cacheEntries = [fileManager contentsOfDirectoryAtPath:_cachePath error:&error];
if (nil == error) {
for (NSString* cacheEntry in cacheEntries) {
NSString* cacheEntryPath = [_cachePath stringByAppendingPathComponent:cacheEntry];
[fileManager removeItemAtPath:cacheEntryPath error:&error];
if (nil != error) {
RKLogError(@”Failed to delete cache entry for file: %@”, cacheEntryPath);
}
}
} else {
RKLogWarning(@”Failed to fetch list of cache entries for cache path: %@”, _cachePath);
}
}
}
[_cacheLock unlock];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKCache.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKDirectory.h
//
// RKDirectory.h
// RestKit
//
// Created by Blake Watters on 12/9/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
iOS and OS X agnostic accessors for safely returning directory paths for use
by the framework and applications.
*/
@interface RKDirectory : NSObject
/**
Returns the path to the Application Data directory for the executing application. On iOS,
this is a sandboxed path specific for the executing application. On OS X, this is an application
specific path under NSApplicationSupportDirectory (i.e. ~/Application Support).
@return The full path to the application data directory.
*/
+ (NSString *)applicationDataDirectory;
/**
Returns a path to the root caches directory used by RestKit for storage. On iOS, this is
a sanboxed path specific for the executing application. On OS X, this is an application
specific path under NSCachesDirectory (i.e. ~/Library/Caches).
@return The full path to the Caches directory.
*/
+ (NSString *)cachesDirectory;
/**
Ensures that a directory exists at a given path by checking for the existence
of the directory and creating it if it does not exist.
@param path The path to ensure a directory exists at.
@param error On input, a pointer to an error object.
@returns A Boolean value indicating if the directory exists.
*/
+ (BOOL)ensureDirectoryExistsAtPath:(NSString *)path error:(NSError **)error;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKDirectory.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKDirectory.m
//
// RKDirectory.m
// RestKit
//
// Created by Blake Watters on 12/9/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKDirectory.h”
#import “NSBundle+RKAdditions.h”
#import “RKLog.h”
@implementation RKDirectory
+ (NSString *)executableName
{
NSString *executableName = [[[NSBundle mainBundle] executablePath] lastPathComponent];
if (nil == executableName) {
RKLogWarning(@”Unable to determine CFBundleExecutable: storing data under RestKit directory name.”);
executableName = @”RestKit”;
}
return executableName;
}
+ (NSString *)applicationDataDirectory
{
#if TARGET_OS_IPHONE
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
#else
NSFileManager *sharedFM = [NSFileManager defaultManager];
NSArray *possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask];
NSURL *appSupportDir = nil;
NSURL *appDirectory = nil;
if ([possibleURLs count] >= 1) {
appSupportDir = [possibleURLs objectAtIndex:0];
}
if (appSupportDir) {
NSString *executableName = [RKDirectory executableName];
appDirectory = [appSupportDir URLByAppendingPathComponent:executableName];
return [appDirectory path];
}
return nil;
#endif
}
+ (NSString *)cachesDirectory
{
#if TARGET_OS_IPHONE
return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
#else
NSString *path = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
if ([paths count]) {
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[RKDirectory executableName]];
}
return path;
#endif
}
+ (BOOL)ensureDirectoryExistsAtPath:(NSString *)path error:(NSError **)error
{
BOOL isDirectory;
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
if (isDirectory) {
// Exists at a path and is a directory, we’re good
if (error) *error = nil;
return YES;
}
}
// Create the directory and any intermediates
NSError *errorReference = (error == nil) ? nil : *error;
if (! [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&errorReference]) {
RKLogError(@”Failed to create requested directory at path ‘%@’: %@”, path, errorReference);
return NO;
}
return YES;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKDirectory.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKDotNetDateFormatter.h
//
// RKDotNetDateFormatter.h
// RestKit
//
// Created by Greg Combs on 9/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
// NSRegularExpression not available until OS X 10.7 and iOS 4.0 (NS_CLASS_AVAILABLE(10_7, 4_0))
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
/**
A subclass of NSDateFormatter that serves as translator between ASP.NET date serializations in JSON
strings and NSDate objects. This is useful for properly mapping these dates from an ASP.NET driven backend.
*NOTE* – DO NOT attempt to use setDateFormat: on this class. It will return invalid results.
*/
@interface RKDotNetDateFormatter : NSDateFormatter {
NSRegularExpression *dotNetExpression;
}
/**
Instantiates an autoreleased RKDotNetDateFormatter object with the timezone set to UTC
(Greenwich Mean Time).
@return An autoreleased RKDotNetDateFormatter object
@see dotNetDateFormatterWithTimeZone
*/
+ (RKDotNetDateFormatter *)dotNetDateFormatter;
/**
Instantiates an autoreleased RKDotNetDateFormatter object.
The supplied timeZone, such as one produced with [NSTimeZone timeZoneWithName:@”UTC”],
is only used during calls to stringFromDate:, for a detailed explanation see dateFromString:
@param timeZone An NSTimeZone object.
@return An autoreleased RKDotNetDateFormatter object
@see dotNetDateFormatter
*/
+ (RKDotNetDateFormatter *)dotNetDateFormatterWithTimeZone:(NSTimeZone *)timeZone;
/**
Returns an NSDate object from an ASP.NET style date string respresentation, as seen in JSON.
Acceptable examples are:
/Date(1112715000000-0500)/
/Date(1112715000000)/
/Date(-1112715000000)/
Where 1112715000000 is the number of milliseconds since January 1, 1970 00:00 GMT/UTC, and -0500 represents the
timezone offset from GMT in 24-hour time. Negatives milliseconds are treated as dates before January 1, 1970.
*NOTE* NSDate objects do not have timezones, and you should never change an actual date value based on a
timezone offset. However, timezones are important when presenting dates to the user. Therefore,
If an offset is present in the ASP.NET string (it should be), we actually ignore the offset portion because
we want to store the actual date value in its raw form, without any pollution of timezone information.
If, on the other hand, there is no offset in the ASP.NET string, we assume GMT (+0000) anyway.
In summation, for this class setTimeZone: is ignored except when using stringFromDate:
@param string The ASP.NET style string, /Date(1112715000000-0500)/
@return An NSDate object
@see stringFromDate
@see NSDateFormatter
@see NSTimeZone
*/
– (NSDate *)dateFromString:(NSString *)string;
/**
Returns an ASP.NET style date string from an NSDate, such as /Date(1112715000000+0000)/
Where 1112715000000 is the number of milliseconds since January 1, 1970 00:00 GMT/UTC, and +0000 is the
timezone offset from GMT in 24-hour time.
*NOTE* GMT (+0000) is assumed otherwise specified via setTimeZone:
@param date An NSDate
@return The ASP.NET style string, /Date(1112715000000-0500)/
@see dateFromString
@see NSDateFormatter
@see NSTimeZone
*/
– (NSString *)stringFromDate:(NSDate *)date;
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKDotNetDateFormatter.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKDotNetDateFormatter.m
//
// RKDotNetDateFormatter.h
// RestKit
//
// Created by Greg Combs on 9/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKDotNetDateFormatter.h”
#import “RestKit.h”
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
BOOL isValidRange(NSRange rangeOfMatch);
NSTimeInterval secondsFromMilliseconds(NSTimeInterval millisecs);
NSTimeInterval millisecondsFromSeconds(NSTimeInterval seconds);
@interface RKDotNetDateFormatter()
– (NSString *)millisecondsFromString:(NSString *)string;
@end
@implementation RKDotNetDateFormatter
+ (RKDotNetDateFormatter *)dotNetDateFormatter {
return [RKDotNetDateFormatter dotNetDateFormatterWithTimeZone:nil];
}
+ (RKDotNetDateFormatter *)dotNetDateFormatterWithTimeZone:(NSTimeZone *)newTimeZone {
RKDotNetDateFormatter *formatter = [[[RKDotNetDateFormatter alloc] init] autorelease];
if (newTimeZone)
formatter.timeZone = newTimeZone;
return formatter;
}
– (NSDate *)dateFromString:(NSString *)string {
NSString *milliseconds = [self millisecondsFromString:string];
if (!milliseconds) {
RKLogError(@”Attempted to interpret an invalid .NET date string: %@”, string);
return nil;
}
NSTimeInterval seconds = secondsFromMilliseconds([milliseconds doubleValue]);
return [NSDate dateWithTimeIntervalSince1970:seconds];
}
– (NSString *)stringFromDate:(NSDate *)date {
if (!date) {
RKLogError(@”Attempted to represent an invalid date: %@”, date);
return nil;
}
NSTimeInterval milliseconds = millisecondsFromSeconds([date timeIntervalSince1970]);
NSString *timeZoneOffset = [super stringFromDate:date];
return [NSString stringWithFormat:@”/Date(%1.0lf%@)/”, milliseconds, timeZoneOffset];
}
– (BOOL)getObjectValue:(id *)outValue forString:(NSString *)string errorDescription:(NSString **)error {
NSDate *date = [self dateFromString:string];
if (outValue)
*outValue = date;
return (date != nil);
}
– (id)init {
self = [super init];
if (self) {
self.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@”en_US_POSIX”] autorelease];
self.timeZone = [NSTimeZone timeZoneWithName:@”UTC”];
[self setDateFormat:@”ZZ”]; // GMT offset, like “-0500″
NSString *pattern = @”\\/Date\\((-?\\d+)((?:[\\+\\-]\\d+)?)\\)\\/”; // /Date(mSecs)/ or /Date(-mSecs)/ or /Date(mSecs-0400)/
dotNetExpression = [[NSRegularExpression alloc] initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:NULL];
}
return self;
}
– (void)dealloc {
[dotNetExpression release];
[super dealloc];
}
– (NSString *)millisecondsFromString:(NSString *)string {
if (!string)
return nil;
NSTextCheckingResult *match = [dotNetExpression firstMatchInString:string options:NSMatchingCompleted range:NSMakeRange(0, [string length])];
if (!match)
return nil;
NSRange millisecRange = [match rangeAtIndex:1];
if (!isValidRange(millisecRange))
return nil;
//NSRange timeZoneRange = [match rangeAtIndex:2];
NSString *milliseconds = [string substringWithRange:millisecRange];
return milliseconds;
}
@end
BOOL isValidRange(NSRange rangeOfMatch) {
return (!NSEqualRanges(rangeOfMatch, NSMakeRange(NSNotFound, 0)));
}
NSTimeInterval secondsFromMilliseconds(NSTimeInterval millisecs) {
return millisecs / 1000.f;
}
NSTimeInterval millisecondsFromSeconds(NSTimeInterval seconds) {
return seconds * 1000.f;
}
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKDotNetDateFormatter.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKErrors.h
//
// RKErrors.h
// RestKit
//
// Created by Blake Watters on 3/25/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/** @name Error Domain & Codes */
// The error domain for RestKit generated errors
extern NSString* const RKErrorDomain;
typedef enum {
RKObjectLoaderRemoteSystemError = 1,
RKRequestBaseURLOfflineError = 2,
RKRequestUnexpectedResponseError = 3,
RKObjectLoaderUnexpectedResponseError = 4,
RKRequestConnectionTimeoutError = 5
} RKRestKitError;
/** @name Error Constants */
/**
The key RestKit generated errors will appear at within an NSNotification
indicating an error
*/
extern NSString* const RKErrorNotificationErrorKey;
/**
When RestKit constructs an NSError object from one or more RKErrorMessage
(or other object mapped error representations), the userInfo of the NSError
object will be populated with an array of the underlying error objects.
These underlying errors can be accessed via RKObjectMapperErrorObjectsKey key.
@see RKObjectMappingResult
*/
extern NSString* const RKObjectMapperErrorObjectsKey;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKErrors.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKErrors.m
//
// RKErrors.m
// RestKit
//
// Created by Blake Watters on 3/25/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKErrors.h”
NSString* const RKErrorDomain = @”org.restkit.RestKit.ErrorDomain”;
NSString* const RKObjectMapperErrorObjectsKey = @”RKObjectMapperErrorObjectsKey”;
NSString* const RKErrorNotificationErrorKey = @”error”;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKErrors.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKFixCategoryBug.h
//
// RKCategoryFix.h
// RestKit
//
// Created by Blake Watters on 9/1/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef RestKit_RKCategoryFix_h
#define RestKit_RKCategoryFix_h
/*
Add this macro before each category implementation, so we don’t have to use
-all_load or -force_load to load object files from static libraries that only contain
categories and no classes.
See http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html for more info.
Shamelessly borrowed from Three20
*/
#define RK_FIX_CATEGORY_BUG(name) @interface RK_FIX_CATEGORY_BUG##name @end \
@implementation RK_FIX_CATEGORY_BUG##name @end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKFixCategoryBug.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKISO8601DateFormatter.h
//
// RKISO8601DateFormatter.h
// RestKit
//
// Created by Christopher Swasey on 1/20/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “ISO8601DateFormatter.h”
@interface RKISO8601DateFormatter : ISO8601DateFormatter
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKISO8601DateFormatter.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKISO8601DateFormatter.m
//
// RKISO8601DateFormatter.m
// RestKit
//
// Created by Christopher Swasey on 1/20/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKISO8601DateFormatter.h”
@implementation RKISO8601DateFormatter
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKISO8601DateFormatter.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKLog.h
//
// RKLog.h
// RestKit
//
// Created by Blake Watters on 5/3/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
RestKit Logging is based on the LibComponentLogging framework
@see lcl_config_components.h
@see lcl_config_logger.h
*/
#import “lcl.h”
/**
RKLogComponent defines the active component within any given portion of RestKit
By default, messages will log to the base ‘RestKit’ log component. All other components
used by RestKit are nested under this parent, so this effectively sets the default log
level for the entire library.
The component can be undef’d and redefined to change the active logging component.
*/
#define RKLogComponent lcl_cRestKit
/**
The logging macros. These macros will log to the currently active logging component
at the log level identified in the name of the macro.
For example, in the RKObjectMappingOperation class we would redefine the RKLogComponent:
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
The lcl_c prefix is the LibComponentLogging data structure identifying the logging component
we want to target within this portion of the codebase. See lcl_config_component.h for reference.
Having defined the logging component, invoking the logger via:
RKLogInfo(@”This is my log message!”);
Would result in a log message similar to:
I RestKit.ObjectMapping:RKLog.h:42 This is my log message!
The message will only be logged if the log level for the active component is equal to or higher
than the level the message was logged at (in this case, Info).
*/
#define RKLogCritical(…) \
lcl_log(RKLogComponent, lcl_vCritical, @”” __VA_ARGS__)
#define RKLogError(…) \
lcl_log(RKLogComponent, lcl_vError, @”” __VA_ARGS__)
#define RKLogWarning(…) \
lcl_log(RKLogComponent, lcl_vWarning, @”” __VA_ARGS__)
#define RKLogInfo(…) \
lcl_log(RKLogComponent, lcl_vInfo, @”” __VA_ARGS__)
#define RKLogDebug(…) \
lcl_log(RKLogComponent, lcl_vDebug, @”” __VA_ARGS__)
#define RKLogTrace(…) \
lcl_log(RKLogComponent, lcl_vTrace, @”” __VA_ARGS__)
/**
Log Level Aliases
These aliases simply map the log levels defined within LibComponentLogger to something more friendly
*/
#define RKLogLevelOff lcl_vOff
#define RKLogLevelCritical lcl_vCritical
#define RKLogLevelError lcl_vError
#define RKLogLevelWarning lcl_vWarning
#define RKLogLevelInfo lcl_vInfo
#define RKLogLevelDebug lcl_vDebug
#define RKLogLevelTrace lcl_vTrace
/**
Alias the LibComponentLogger logging configuration method. Also ensures logging
is initialized for the framework.
Expects the name of the component and a log level.
Examples:
// Log debugging messages from the Network component
RKLogConfigureByName(“RestKit/Network”, RKLogLevelDebug);
// Log only critical messages from the Object Mapping component
RKLogConfigureByName(“RestKit/ObjectMapping”, RKLogLevelCritical);
*/
#define RKLogConfigureByName(name, level) \
RKLogInitialize(); \
lcl_configure_by_name(name, level);
/**
Alias for configuring the LibComponentLogger logging component for the App. This
enables the end-user of RestKit to leverage RKLog() to log messages inside of
their apps.
*/
#define RKLogSetAppLoggingLevel(level) \
RKLogInitialize(); \
lcl_configure_by_name(“App”, level);
/**
Temporarily changes the logging level for the specified component and executes the block. Any logging
statements executed within the body of the block against the specified component will log at the new
logging level. After the block has executed, the logging level is restored to its previous state.
*/
#define RKLogToComponentWithLevelWhileExecutingBlock(_component, _level, _block) \
do { \
int _currentLevel = _lcl_component_level[_component]; \
lcl_configure_by_component(_component, _level); \
@try { \
_block(); \
} \
@catch (NSException *exception) { \
@throw; \
} \
@finally { \
lcl_configure_by_component(_component, _currentLevel); \
} \
} while(false);
/**
Temporarily turns off logging for the given logging component during execution of the block.
After the block has finished execution, the logging level is restored to its previous state.
*/
#define RKLogSilenceComponentWhileExecutingBlock(component, _block) \
RKLogToComponentWithLevelWhileExecutingBlock(component, RKLogLevelOff, _block)
/**
Temporarily changes the logging level for the configured RKLogComponent and executes the block. Any logging
statements executed within the body of the block for the current logging component will log at the new
logging level. After the block has finished execution, the logging level is restored to its previous state.
*/
#define RKLogWithLevelWhileExecutingBlock(_level, _block) \
RKLogToComponentWithLevelWhileExecutingBlock(RKLogComponent, _level, _block)
/**
Temporarily turns off logging for current logging component during execution of the block.
After the block has finished execution, the logging level is restored to its previous state.
*/
#define RKLogSilenceWhileExecutingBlock(_block) \
RKLogToComponentWithLevelWhileExecutingBlock(RKLogComponent, RKLogLevelOff, _block)
/**
Set the Default Log Level
Based on the presence of the DEBUG flag, we default the logging for the RestKit parent component
to Info or Warning.
You can override this setting by defining RKLogLevelDefault as a pre-processor macro.
*/
#ifndef RKLogLevelDefault
#ifdef DEBUG
#define RKLogLevelDefault RKLogLevelInfo
#else
#define RKLogLevelDefault RKLogLevelWarning
#endif
#endif
/**
Initialize the logging environment
*/
void RKLogInitialize(void);
/**
Configure RestKit logging from environment variables.
(Use Option + Command + R to set Environment Variables prior to run.)
For example to configure the equivalent of setting the following in code:
RKLogConfigureByName(“RestKit/Network”, RKLogLevelTrace);
Define an environment variable named RKLogLevel.RestKit.Network and set its value to “Trace”
See lcl_config_components.h for configurable RestKit logging components.
Valid values are the following:
Default or 0
Critical or 1
Error or 2
Warning or 3
Info or 4
Debug or 5
Trace or 6
*/
void RKLogConfigureFromEnvironment(void);
/**
Logs extensive information about an NSError generated as the results
of a failed key-value validation error.
*/
void RKLogValidationError(NSError *);
/**
Logs the value of an NSUInteger as a binary string. Useful when
examining integers containing bitmasked values.
*/
void RKLogIntegerAsBinary(NSUInteger);
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKLog.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKLog.m
//
// RKLog.m
// RestKit
//
// Created by Blake Watters on 6/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKLog.h”
#import “lcl.h”
int RKLogLevelForString(NSString *, NSString *);
static BOOL loggingInitialized = NO;
void RKLogInitialize(void)
{
if (loggingInitialized == NO) {
lcl_configure_by_name(“RestKit*”, RKLogLevelDefault);
lcl_configure_by_name(“App”, RKLogLevelDefault);
RKLogInfo(@”RestKit initialized…”);
loggingInitialized = YES;
}
}
void RKLogConfigureFromEnvironment(void)
{
NSArray *validEnvVariables = [NSArray arrayWithObjects:
@”RKLogLevel.App”,
@”RKLogLevel.RestKit”,
@”RKLogLevel.RestKit.CoreData”,
@”RKLogLevel.RestKit.CoreData.SearchEngine”,
@”RKLogLevel.RestKit.Network”,
@”RKLogLevel.RestKit.Network.Cache”,
@”RKLogLevel.RestKit.Network.Queue”,
@”RKLogLevel.RestKit.Network.Reachability”,
@”RKLogLevel.RestKit.ObjectMapping”,
@”RKLogLevel.RestKit.Support”,
@”RKLogLevel.RestKit.Support.Parsers”,
@”RKLogLevel.RestKit.Testing”,
@”RKLogLevel.RestKit.Three20″,
@”RKLogLevel.RestKit.UI”,
nil];
static NSString *logComponentPrefix = @”RKLogLevel.”;
NSDictionary *envVars = [[NSProcessInfo processInfo] environment];
for (NSString *envVarName in [envVars allKeys]) {
if ([envVarName hasPrefix:logComponentPrefix]) {
if (![validEnvVariables containsObject:envVarName]) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@”The RKLogLevel Environment Variable name must be one of the following: %@”, validEnvVariables] userInfo:nil];
}
NSString *logLevel = [envVars valueForKey:envVarName];
NSString *logComponent = [envVarName stringByReplacingOccurrencesOfString:logComponentPrefix withString:@””];
logComponent = [logComponent stringByReplacingOccurrencesOfString:@”.” withString:@”/”];
const char* log_component_c_str = [logComponent cStringUsingEncoding:NSUTF8StringEncoding];
int log_level_int = RKLogLevelForString(logLevel, envVarName);
RKLogConfigureByName(log_component_c_str, log_level_int);
}
}
}
int RKLogLevelForString(NSString *logLevel, NSString *envVarName)
{
// Forgive the user if they specify the full name for the value i.e. “RKLogLevelDebug” instead of “Debug”
logLevel = [logLevel stringByReplacingOccurrencesOfString:@”RKLogLevel” withString:@””];
if ([logLevel isEqualToString:@”Off”] ||
[logLevel isEqualToString:@”0″]) {
return RKLogLevelOff;
}
else if ([logLevel isEqualToString:@”Critical”] ||
[logLevel isEqualToString:@”1″]) {
return RKLogLevelCritical;
}
else if ([logLevel isEqualToString:@”Error”] ||
[logLevel isEqualToString:@”2″]) {
return RKLogLevelError;
}
else if ([logLevel isEqualToString:@”Warning”] ||
[logLevel isEqualToString:@”3″]) {
return RKLogLevelWarning;
}
else if ([logLevel isEqualToString:@”Info”] ||
[logLevel isEqualToString:@”4″]) {
return RKLogLevelInfo;
}
else if ([logLevel isEqualToString:@”Debug”] ||
[logLevel isEqualToString:@”5″]) {
return RKLogLevelDebug;
}
else if ([logLevel isEqualToString:@”Trace”] ||
[logLevel isEqualToString:@”6″]) {
return RKLogLevelTrace;
}
else if ([logLevel isEqualToString:@”Default”]) {
return RKLogLevelDefault;
}
else {
NSString *errorMessage = [NSString stringWithFormat:@”The value: \”%@\” for the environment variable: \”%@\” is invalid. \
\nThe log level must be set to one of the following values \
\n Default or 0 \
\n Critical or 1 \
\n Error or 2 \
\n Warning or 3 \
\n Info or 4 \
\n Debug or 5 \
\n Trace or 6\n”, logLevel, envVarName];
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:errorMessage userInfo:nil];
return -1;
}
}
void RKLogValidationError(NSError *validationError) {
if ([[validationError domain] isEqualToString:@”NSCocoaErrorDomain”]) {
NSDictionary *userInfo = [validationError userInfo];
NSArray *errors = [userInfo valueForKey:@”NSDetailedErrors”];
if (errors) {
for (NSError *detailedError in errors) {
NSDictionary *subUserInfo = [detailedError userInfo];
RKLogError(@”Core Data Save Error\n \
NSLocalizedDescription:\t\t%@\n \
NSValidationErrorKey:\t\t\t%@\n \
NSValidationErrorPredicate:\t%@\n \
NSValidationErrorObject:\n%@\n”,
[subUserInfo valueForKey:@”NSLocalizedDescription”],
[subUserInfo valueForKey:@”NSValidationErrorKey”],
[subUserInfo valueForKey:@”NSValidationErrorPredicate”],
[subUserInfo valueForKey:@”NSValidationErrorObject”]);
}
}
else {
RKLogError(@”Core Data Save Error\n \
NSLocalizedDescription:\t\t%@\n \
NSValidationErrorKey:\t\t\t%@\n \
NSValidationErrorPredicate:\t%@\n \
NSValidationErrorObject:\n%@\n”,
[userInfo valueForKey:@”NSLocalizedDescription”],
[userInfo valueForKey:@”NSValidationErrorKey”],
[userInfo valueForKey:@”NSValidationErrorPredicate”],
[userInfo valueForKey:@”NSValidationErrorObject”]);
}
}
}
void RKLogIntegerAsBinary(NSUInteger bitMask) {
NSUInteger bit = ~(NSUIntegerMax >> 1);
NSMutableString *string = [NSMutableString string];
do {
[string appendString:(((NSUInteger)bitMask & bit) ? @”1″ : @”0″)];
} while ( bit >>= 1 );
NSLog(@”Value of %ld in binary: %@”, (long) bitMask, string);
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKLog.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKMIMETypes.h
//
// RKMIMETypes.h
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
MIME Type Constants
*/
/// MIME Type application/json
extern NSString* const RKMIMETypeJSON;
/// MIME Type application/x-www-form-urlencoded
extern NSString* const RKMIMETypeFormURLEncoded;
/// MIME Type application/xml
extern NSString* const RKMIMETypeXML;
/// MIME Type text/xml
extern NSString* const RKMIMETypeTextXML;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKMIMETypes.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKMIMETypes.m
//
// RKMIMETypes.m
// RestKit
//
// Created by Blake Watters on 5/18/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKMIMETypes.h”
NSString* const RKMIMETypeJSON = @”application/json”;
NSString* const RKMIMETypeFormURLEncoded = @”application/x-www-form-urlencoded”;
NSString* const RKMIMETypeXML = @”application/xml”;
NSString* const RKMIMETypeTextXML = @”text/xml”;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKMIMETypes.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKMutableBlockDictionary.h
//
// RKMutableBlockDictionary.h
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
A dictionary capable of storing dynamic values provided
as a Objective-C block. Otherwise identical in functionality
to a vanilla NSMutableDictionary
*/
@interface RKMutableBlockDictionary : NSMutableDictionary {
@private
NSMutableDictionary *_mutableDictionary;
}
/**
Assigns a block as the value for a key in the dictionary. This allows you
to implement simple logic using key-value coding semantics within the dictionary.
When valueForKey: is invoked on the dictionary for a key with a block value, the
block will be evaluated and the result returned.
@param block An Objective-C block returning an id and accepting no parameters
@param key An NSString key for setting the
*/
– (void)setValueWithBlock:(id (^)())block forKey:(NSString *)key;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKMutableBlockDictionary.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKMutableBlockDictionary.m
//
// RKMutableBlockDictionary.m
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKMutableBlockDictionary.h”
typedef id (^RKMutableBlockDictionaryValueBlock)();
@interface RKMutableBlockDictionaryBlockValue : NSObject {
RKMutableBlockDictionaryValueBlock _executionBlock;
}
@property (nonatomic, copy) RKMutableBlockDictionaryValueBlock executionBlock;
+ (id)valueWithBlock:(RKMutableBlockDictionaryValueBlock)executionBlock;
@end
@implementation RKMutableBlockDictionaryBlockValue
@synthesize executionBlock = _executionBlock;
+ (id)valueWithBlock:(RKMutableBlockDictionaryValueBlock)executionBlock {
RKMutableBlockDictionaryBlockValue* value = [[self new] autorelease];
value.executionBlock = executionBlock;
return value;
}
– (void)setExecutionBlock:(RKMutableBlockDictionaryValueBlock)executionBlock {
if (_executionBlock) {
Block_release(_executionBlock);
_executionBlock = nil;
}
_executionBlock = Block_copy(executionBlock);
}
– (void)dealloc {
if (_executionBlock) {
Block_release(_executionBlock);
_executionBlock = nil;
}
[super dealloc];
}
@end
@implementation RKMutableBlockDictionary
– (id)init {
return [self initWithCapacity:0];
}
– (id)initWithCapacity:(NSUInteger)capacity {
self = [super init];
if (self != nil) {
_mutableDictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
}
return self;
}
– (void)dealloc {
[_mutableDictionary release];
[super dealloc];
}
– (id)copy {
return [self mutableCopy];
}
– (void)setObject:(id)anObject forKey:(id)aKey {
[_mutableDictionary setObject:anObject forKey:aKey];
}
– (void)removeObjectForKey:(id)aKey {
[_mutableDictionary removeObjectForKey:aKey];
}
– (NSUInteger)count {
return [_mutableDictionary count];
}
– (id)objectForKey:(id)aKey {
return [_mutableDictionary objectForKey:aKey];
}
– (NSEnumerator *)keyEnumerator {
return [_mutableDictionary keyEnumerator];
}
– (void)setValueWithBlock:(id (^)())block forKey:(NSString *)key {
RKMutableBlockDictionaryBlockValue* blockValue = [RKMutableBlockDictionaryBlockValue valueWithBlock:block];
[self setObject:blockValue forKey:key];
}
– (id)valueForKey:(NSString *)key {
id value = [self objectForKey:key];
if (value) {
if ([value isKindOfClass:[RKMutableBlockDictionaryBlockValue class]]) {
RKMutableBlockDictionaryBlockValue *blockValue = (RKMutableBlockDictionaryBlockValue *)value;
return blockValue.executionBlock();
}
return value;
}
return nil;
}
– (id)valueForKeyPath:(NSString *)keyPath {
id value = [super valueForKeyPath:keyPath];
if (value) {
if ([value isKindOfClass:[RKMutableBlockDictionaryBlockValue class]]) {
RKMutableBlockDictionaryBlockValue *blockValue = (RKMutableBlockDictionaryBlockValue *)value;
return blockValue.executionBlock();
}
return value;
}
return nil;
}
– (void)setValue:(id)value forKey:(NSString *)key {
[self setObject:value forKey:key];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKMutableBlockDictionary.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKOrderedDictionary.h
//
// OrderedDictionary.h
// OrderedDictionary
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided ‘as-is’, without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import
/**
The RKOrderedDictionary class declares the programmatic interface to objects that manage mutable
associations of keys and values wherein the keys have a specific order. It adds ordered key modification
operations to the basic operations it inherits from NSMutableDictionary.
*/
// Borrowed from Matt Gallagher – http://cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html
@interface RKOrderedDictionary : NSMutableDictionary
{
NSMutableDictionary *dictionary;
NSMutableArray *array;
}
/**
Inserts an object into the dictionary for a given key at a specific index.
@param anObject The object to add the dictionary.
@param aKey The key to store the value under.
@param anIndex The index in the dictionary at which to insert aKey.
*/
– (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
/**
Returns the key within the dictionary at a given index.
@param anIndex An index within the bounds of the array keys.
@return The key that appears at the given index.
*/
– (id)keyAtIndex:(NSUInteger)anIndex;
/**
Returns an enumerator object that lets you access each key in the dictionary,
in reverse order.
@return An enumerator object that lets you access each key in the dictionary
in reverse order.
*/
– (NSEnumerator *)reverseKeyEnumerator;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKOrderedDictionary.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKOrderedDictionary.m
//
// OrderedDictionary.m
// OrderedDictionary
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided ‘as-is’, without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import “RKOrderedDictionary.h”
NSString *RKDescriptionForObject(NSObject *object, id locale, NSUInteger indent);
NSString *RKDescriptionForObject(NSObject *object, id locale, NSUInteger indent)
{
NSString *objectString;
if ([object isKindOfClass:[NSString class]])
{
objectString = (NSString *)[[object retain] autorelease];
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
{
objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
{
objectString = [(NSSet *)object descriptionWithLocale:locale];
}
else
{
objectString = [object description];
}
return objectString;
}
@implementation RKOrderedDictionary
– (id)init
{
return [self initWithCapacity:0];
}
– (id)initWithCapacity:(NSUInteger)capacity
{
self = [super init];
if (self != nil)
{
dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
array = [[NSMutableArray alloc] initWithCapacity:capacity];
}
return self;
}
– (void)dealloc
{
[dictionary release];
[array release];
[super dealloc];
}
– (id)copy
{
return [self mutableCopy];
}
– (void)setObject:(id)anObject forKey:(id)aKey
{
if (![dictionary objectForKey:aKey])
{
[array addObject:aKey];
}
[dictionary setObject:anObject forKey:aKey];
}
– (void)removeObjectForKey:(id)aKey
{
[dictionary removeObjectForKey:aKey];
[array removeObject:aKey];
}
– (NSUInteger)count
{
return [dictionary count];
}
– (id)objectForKey:(id)aKey
{
return [dictionary objectForKey:aKey];
}
– (NSEnumerator *)keyEnumerator
{
return [array objectEnumerator];
}
– (NSEnumerator *)reverseKeyEnumerator
{
return [array reverseObjectEnumerator];
}
– (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
{
if ([dictionary objectForKey:aKey])
{
[self removeObjectForKey:aKey];
}
[array insertObject:aKey atIndex:anIndex];
[dictionary setObject:anObject forKey:aKey];
}
– (id)keyAtIndex:(NSUInteger)anIndex
{
return [array objectAtIndex:anIndex];
}
– (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *indentString = [NSMutableString string];
NSUInteger i, count = level;
for (i = 0; i < count; i++)
{
[indentString appendFormat:@" "];
}
NSMutableString *description = [NSMutableString string];
[description appendFormat:@"%@{\n", indentString];
for (NSObject *key in self)
{
[description appendFormat:@"%@ %@ = %@;\n",
indentString,
RKDescriptionForObject(key, locale, level),
RKDescriptionForObject([self objectForKey:key], locale, level)];
}
[description appendFormat:@"%@}\n", indentString];
return description;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKOrderedDictionary.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKParser.h
//
// RKParser.h
// RestKit
//
// Created by Blake Watters on 10/1/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/**
The RKParser protocol declares two methods that a class must implement
so that it can provide support for parsing and serializing object
representations to the RestKit framework. Parsers are required to transform
data to and from string representations and are configured via the
RKParserRegistry shared instance.
*/
@protocol RKParser
/**
Returns an object representation of the source string encoded in the
format provided by the parser (i.e. JSON, XML, etc).
@param string The string representation of the object to be parsed.
@param error A pointer to an NSError object.
@return The parsed object or nil if an error occurred during parsing.
*/
- (id)objectFromString:(NSString *)string error:(NSError **)error;
/**
Returns a string representation encoded in the format
provided by the parser (i.e. JSON, XML, etc) for the given object.
@param object The object to be serialized.
@param A pointer to an NSError object.
@return A string representation of the serialized object or nil if an error occurred.
*/
- (NSString *)stringFromObject:(id)object error:(NSError **)error;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKParser.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKPathMatcher.h
//
// RKPathMatcher.h
// RestKit
//
// Created by Greg Combs on 9/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@class SOCPattern;
/**
This class performs pattern matching and parameter parsing of strings, usually resource paths.
It provides much of the necessary tools to map a given resource path to local objects (the inverse
of RKRouter’s function). This makes it easier to implement RKManagedObjectCache, and generate fetched
requests from a given resource path. There are two means of instantiating and using a matcher object
in order to provide more flexibility in implementations, and to improve efficiency by eliminating
repetitive and costly pattern initializations.
@see RKManagedObjectCache
@see RKMakePathWithObject
@see RKRouter
*/
@interface RKPathMatcher : NSObject
@private
SOCPattern *socPattern_;
NSString *sourcePath_;
NSString *rootPath_;
NSDictionary *queryParameters_;
}
@property (copy, readonly) NSDictionary *queryParameters;
/**
Creates an RKPathMatcher starting from a resource path string. This method should be followed by
matchesPattern:tokenizeQueryStrings:parsedArguments:
@param pathString The string to evaluate and parse, such as /districts/tx/upper/?apikey=GC5512354
@return An instantiated RKPathMatcher without an established pattern.
*/
+(RKPathMatcher *)matcherWithPath:(NSString *)pathString;
/**
Determines if the path string matches the provided pattern, and yields a dictionary with the resulting
matched key/value pairs. Use of this method should be preceded by matcherWithPath:
Pattern strings should include encoded parameter keys, delimited by a single colon at the
beginning of the key name.
*NOTE 1* – Numerous colon-encoded parameter keys can be joined in a long pattern, but each key must be
separated by at least one unmapped character. For instance, /:key1:key2:key3/ is invalid, whereas
/:key1/:key2/:key3/ is acceptable.
*NOTE 2* – The pattern matcher supports KVM, so :key1.otherKey normally resolves as it would in any other KVM
situation, … otherKey is a sub-key on a the object represented by key1. This presents problems in circumstances where
you might want to build a pattern like /:filename.json, where the dot isn’t intended as a sub-key on the filename, but rather
part of the json static string. In these instances, you need to escape the dot with two backslashes, like so:
/:filename\\.json
@param patternString The pattern to use for evaluating, such as /:entityName/:stateID/:chamber/
@param shouldTokenize If YES, any query parameters will be tokenized and inserted into the parsed argument dictionary.
@param arguments A pointer to a dictionary that contains the key/values from the pattern (and parameter) matching.
@return A boolean indicating if the path string successfully matched the pattern.
*/
– (BOOL)matchesPattern:(NSString *)patternString tokenizeQueryStrings:(BOOL)shouldTokenize parsedArguments:(NSDictionary **)arguments;
/**
Creates an RKPathMatcher starting from a pattern string. This method should be followed by
matchesPath:tokenizeQueryStrings:parsedArguments: Patterns should include encoded parameter keys,
delimited by a single colon at the beginning of the key name.
*NOTE 1* – Numerous colon-encoded parameter keys can be joined in a long pattern, but each key must be
separated by at least one unmapped character. For instance, /:key1:key2:key3/ is invalid, whereas
/:key1/:key2/:key3/ is acceptable.
*NOTE 2* – The pattern matcher supports KVM, so :key1.otherKey normally resolves as it would in any other KVM
situation, … otherKey is a sub-key on a the object represented by key1. This presents problems in circumstances where
you might want to build a pattern like /:filename.json, where the dot isn’t intended as a sub-key on the filename, but rather
part of the json static string. In these instances, you need to escape the dot with two backslashes, like so:
/:filename\\.json
@param patternString The pattern to use for evaluating, such as /:entityName/:stateID/:chamber/
@return An instantiated RKPathMatcher with an established pattern.
*/
+(RKPathMatcher *)matcherWithPattern:(NSString *)patternString;
/**
Determines if the provided resource path string matches a pattern, and yields a dictionary with the resulting
matched key/value pairs. Use of this method should be preceded by matcherWithPattern:
@param pathString The string to evaluate and parse, such as /districts/tx/upper/?apikey=GC5512354
@param shouldTokenize If YES, any query parameters will be tokenized and inserted into the parsed argument dictionary.
@param arguments A pointer to a dictionary that contains the key/values from the pattern (and parameter) matching.
@return A boolean indicating if the path string successfully matched the pattern.
*/
– (BOOL)matchesPath:(NSString *)pathString tokenizeQueryStrings:(BOOL)shouldTokenize parsedArguments:(NSDictionary **)arguments;
/**
This generates a resource path by interpolating the properties of the ‘object’ argument, assuming the existence
of a previously specified pattern established via matcherWithPattern:. Otherwise, this method is identical in
function to RKMakePathWithObject (in fact it is a shortcut for this method).
For example, given an ‘article’ object with an ‘articleID’ property value of 12345 …
RKPathMatcher *matcher = [RKPathMatcher matcherWithPattern:@”/articles/:articleID”];
NSString *resourcePath = [matcher pathFromObject:article];
… will produce a ‘resourcePath’ containing the string “/articles/12345”
@param object The object containing the properties to interpolate.
@return A string with the object’s interpolated property values inserted into the receiver’s established pattern.
@see RKMakePathWithObject
@see RKRouter
*/
– (NSString *)pathFromObject:(id)object;
/**
This generates a resource path by interpolating the properties of the ‘object’ argument, assuming the existence
of a previously specified pattern established via matcherWithPattern:. Otherwise, this method is identical in
function to RKMakePathWithObject (in fact it is a shortcut for this method).
For example, given an ‘article’ object with an ‘articleID’ property value of 12345 and a code of “This/That”…
RKPathMatcher *matcher = [RKPathMatcher matcherWithPattern:@”/articles/:articleID/:code”];
NSString *resourcePath = [matcher pathFromObject:article addingEscapes:YES];
… will produce a ‘resourcePath’ containing the string “/articles/12345/This%2FThat”
@param object The object containing the properties to interpolate.
@param addEscapes Conditionally add percent escapes to the interpolated property values
@return A string with the object’s interpolated property values inserted into the receiver’s established pattern.
@see RKMakePathWithObjectAddingEscapes
@see RKRouter
*/
– (NSString *)pathFromObject:(id)object addingEscapes:(BOOL)addEscapes;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKPathMatcher.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKPathMatcher.m
//
// RKPathMatcher.m
// RestKit
//
// Created by Greg Combs on 9/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKPathMatcher.h”
#import “SOCKit.h”
#import “NSString+RKAdditions.h”
#import “NSDictionary+RKAdditions.h”
#import “RKLog.h”
BOOL RKPathUsesParentheticalParameters(NSString *path);
NSString *RKPathPatternFindAndReplaceParensWithColons(NSString *pattern);
NSString *RKEncodeURLString(NSString *unencodedString);
BOOL RKPathUsesParentheticalParameters(NSString *path) {
NSCharacterSet *parens = [NSCharacterSet characterSetWithCharactersInString:@”()”];
NSArray *parenComponents = [path componentsSeparatedByCharactersInSet:parens];
return (parenComponents != NULL && [parenComponents count] > 1);
}
NSString *RKPathPatternFindAndReplaceParensWithColons(NSString *pattern) {
if (RKPathUsesParentheticalParameters(pattern)) {
RKLogWarning(@”Use of encapsulating parentheses for pattern parameters is deprecated. Use a single colon instead. For example, instead of /group/(role)/(user) you should use /group/:role/:user”);
NSString *noTrailingParen = [pattern stringByReplacingOccurrencesOfString:@”)” withString:@””];
pattern = [noTrailingParen stringByReplacingOccurrencesOfString:@”(” withString:@”:”];
}
return pattern;
}
// NSString’s stringByAddingPercentEscapes doesn’t do a complete job (it ignores “/?&”, among others)
NSString *RKEncodeURLString(NSString *unencodedString) {
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@”!*'();:@&=+$,/?%#[]”,
kCFStringEncodingUTF8 );
return [encodedString autorelease];
}
@interface RKPathMatcher()
@property (nonatomic,retain) SOCPattern *socPattern;
@property (nonatomic,copy) NSString *sourcePath;
@property (nonatomic,copy) NSString *rootPath;
@property (copy,readwrite) NSDictionary *queryParameters;
@end
@implementation RKPathMatcher
@synthesize socPattern=socPattern_;
@synthesize sourcePath=sourcePath_;
@synthesize rootPath=rootPath_;
@synthesize queryParameters=queryParameters_;
– (id)copyWithZone:(NSZone *)zone {
RKPathMatcher* copy = [[[self class] allocWithZone:zone] init];
copy.socPattern = self.socPattern;
copy.sourcePath = self.sourcePath;
copy.rootPath = self.rootPath;
copy.queryParameters = self.queryParameters;
return copy;
}
– (void)dealloc {
self.socPattern = nil;
self.sourcePath = nil;
self.rootPath = nil;
self.queryParameters = nil;
[super dealloc];
}
+(RKPathMatcher *)matcherWithPattern:(NSString *)patternString {
NSAssert(patternString != NULL, @”Pattern string must not be empty in order to perform pattern matching.”);
patternString = RKPathPatternFindAndReplaceParensWithColons(patternString);
RKPathMatcher *matcher = [[[RKPathMatcher alloc] init] autorelease];
matcher.socPattern = [SOCPattern patternWithString:patternString];
return matcher;
}
+(RKPathMatcher *)matcherWithPath:(NSString *)pathString {
RKPathMatcher *matcher = [[[RKPathMatcher alloc] init] autorelease];
matcher.sourcePath = pathString;
matcher.rootPath = pathString;
return matcher;
}
– (BOOL)matches {
NSAssert( (self.socPattern != NULL && self.rootPath != NULL) , @”Matcher is insufficiently configured. Before attempting pattern matching, you must provide a path string and a pattern to match it against.”);
return [self.socPattern stringMatches:self.rootPath];
}
– (BOOL)bifurcateSourcePathFromQueryParameters {
NSArray *components = [self.sourcePath componentsSeparatedByString:@”?”];
if ([components count] > 1) {
self.rootPath = [components objectAtIndex:0];
self.queryParameters = [[components objectAtIndex:1] queryParametersUsingEncoding:NSUTF8StringEncoding];
return YES;
}
return NO;
}
– (BOOL)itMatchesAndHasParsedArguments:(NSDictionary **)arguments tokenizeQueryStrings:(BOOL)shouldTokenize {
NSAssert(self.socPattern != NULL, @”Matcher has no established pattern. Instantiate it using matcherWithPattern: before attempting a pattern match.”);
NSMutableDictionary *argumentsCollection = [NSMutableDictionary dictionary];
if ([self bifurcateSourcePathFromQueryParameters]) {
if (shouldTokenize) {
[argumentsCollection addEntriesFromDictionary:self.queryParameters];
}
}
if (![self matches])
return NO;
if (!arguments) {
return YES;
}
NSDictionary *extracted = [self.socPattern parameterDictionaryFromSourceString:self.rootPath];
if (extracted)
[argumentsCollection addEntriesFromDictionary:[extracted dictionaryByReplacingPercentEscapesInEntries]];
*arguments = argumentsCollection;
return YES;
}
– (BOOL)matchesPattern:(NSString *)patternString tokenizeQueryStrings:(BOOL)shouldTokenize parsedArguments:(NSDictionary **)arguments {
NSAssert(patternString != NULL, @”Pattern string must not be empty in order to perform patterm matching.”);
patternString = RKPathPatternFindAndReplaceParensWithColons(patternString);
self.socPattern = [SOCPattern patternWithString:patternString];
return [self itMatchesAndHasParsedArguments:arguments tokenizeQueryStrings:shouldTokenize];
}
– (BOOL)matchesPath:(NSString *)sourceString tokenizeQueryStrings:(BOOL)shouldTokenize parsedArguments:(NSDictionary **)arguments {
self.sourcePath = sourceString;
self.rootPath = sourceString;
return [self itMatchesAndHasParsedArguments:arguments tokenizeQueryStrings:shouldTokenize];
}
– (NSString *)pathFromObject:(id)object {
return [self pathFromObject:object addingEscapes:YES];
}
– (NSString *)pathFromObject:(id)object addingEscapes:(BOOL)addEscapes {
NSAssert(self.socPattern != NULL, @”Matcher has no established pattern. Instantiate it using matcherWithPattern: before calling pathFromObject:”);
NSAssert(object != NULL, @”Object provided is invalid; cannot create a path from a NULL object”);
NSString *(^encoderBlock)(NSString* interpolatedString) = nil;
if (addEscapes)
encoderBlock = ^NSString *(NSString* interpolatedString) {
return RKEncodeURLString(interpolatedString);
};
NSString *path = [self.socPattern stringFromObject:object withBlock:encoderBlock];
return path;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKPathMatcher.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKPortCheck.h
//
// RKPortCheck.h
// RestKit
//
// Created by Blake Watters on 5/10/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import
/**
The RKPortCheck class provides a simple interface for quickly testing
the availability of a listening TCP port on a remote host by IP Address or
Hostname.
*/
@interface RKPortCheck : NSObject
///—————————————————————————–
/// @name Creating a Port Check
///—————————————————————————–
/**
Initializes the receiver with a given hostname or IP address as a string
and a numeric TCP port number.
@param hostNameOrIPAddress A string containing the hostname or IP address to check.
@param port The TCP port on the remote host to check for a listening server on.
@return The receiver, initialized with host and port.
*/
– (id)initWithHost:(NSString *)hostNameOrIPAddress port:(NSUInteger)port;
///—————————————————————————–
/// @name Accessing Host and Port
///—————————————————————————–
/**
The hostname or IP address the receiver is checking.
*/
@property (nonatomic, retain, readonly) NSString *host;
/**
The TCP port to check for a listening server on.
*/
@property (nonatomic, assign, readonly) NSUInteger port;
///—————————————————————————–
/// @name Running the Check
///—————————————————————————–
/**
Runs the check by creating a socket and attempting to connect to the
target host and port via TCP. The
*/
– (void)run;
///—————————————————————————–
/// @name Inspecting Port Accessibility
///—————————————————————————–
/**
Returns a Boolean value indicating if the check has been run.
@return YES if the check has been run, otherwise NO.
*/
– (BOOL)hasRun;
/**
Returns a Boolean value indicating if the host and port the receiver checked
is open and listening for incoming connections.
@return YES if the port on the remote host is open, otherwise NO.
*/
– (BOOL)isOpen;
/**
Returns a Boolean value indicating if the host and port the receiver checked
is NOT open and listening for incoming connections.
@return YES if the port on the remote host is closed, otherwise NO.
*/
– (BOOL)isClosed;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKPortCheck.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKPortCheck.m
//
// RKPortCheck.m
// RestKit
//
// Created by Blake Watters on 5/10/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import “RKPortCheck.h”
#include
#include
@interface RKPortCheck ()
@property (nonatomic, assign) struct sockaddr_in remote_saddr;
@property (nonatomic, assign, getter = isOpen) BOOL open;
@property (nonatomic, assign, getter = hasRun) BOOL run;
@end
@implementation RKPortCheck
@synthesize host = _host;
@synthesize port = _port;
@synthesize remote_saddr = _remote_saddr;
@synthesize open = _open;
@synthesize run = _run;
– (id)initWithHost:(NSString *)hostNameOrIPAddress port:(NSUInteger)port
{
self = [self init];
if (self) {
_run = NO;
_host = [hostNameOrIPAddress retain];
_port = port;
struct sockaddr_in sa;
char *hostNameOrIPAddressCString = (char *) [hostNameOrIPAddress UTF8String];
int result = inet_pton(AF_INET, hostNameOrIPAddressCString, &(sa.sin_addr));
if (result != 0) {
// IP Address
bzero(&_remote_saddr, sizeof(struct sockaddr_in));
_remote_saddr.sin_len = sizeof(struct sockaddr_in);
_remote_saddr.sin_family = AF_INET;
_remote_saddr.sin_port = htons(port);
inet_aton(hostNameOrIPAddressCString, &(_remote_saddr.sin_addr));
} else {
// Hostname
struct hostent *hp;
if ((hp = gethostbyname(hostNameOrIPAddressCString)) == 0) {
return nil;
}
bzero(&_remote_saddr, sizeof(struct sockaddr_in));
_remote_saddr.sin_family = AF_INET;
_remote_saddr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
_remote_saddr.sin_port = htons(port);
}
}
return self;
}
– (void)dealloc
{
[_host release];
[super dealloc];
}
– (void)run
{
int sd;
_run = YES;
// Create Internet domain socket
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
_open = NO;
return;
}
// Try to connect to the port
_open = (connect(sd,(struct sockaddr *) &_remote_saddr, sizeof(_remote_saddr)) == 0);
if (_open) {
close(sd);
}
}
– (BOOL)isOpen
{
NSAssert(self.hasRun, @”Cannot determine port availability. Check has not been run.”);
return _open;
}
– (BOOL)isClosed
{
return !self.isOpen;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKPortCheck.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKSearchEngine.h
//
// RKSearchEngine.h
// RestKit
//
// Created by Blake Watters on 8/26/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
/**
The RKSearchable protocol declares a method for providing a searchable
textual representation of content contained within the receiver. Searchable
objects can be searched via instances of RKSearchEngine.
*/
@protocol RKSearchable
@required
/**
Returns a string representation of searchable text contained within the receiver.
@return A string of searchable text.
*/
– (NSString *)searchableText;
@end
/**
The mode (and/or) in which to search for tokenized text via an RKSearchEngine instance.
*/
typedef enum {
/**
The search text should be matched inclusively using AND.
Matches will include all search terms.
*/
RKSearchModeAnd,
/**
The search text should be matched exclusively using OR.
Matches will include any search terms.
*/
RKSearchModeOr
} RKSearchMode;
/**
An instance of RKSearchEngine provides a simple interface for searching
arbitrary objects for matching text. Searching is performed by constructing
a compound NSPredicate and evaluating a collection of candidate objects for matches.
RKSearchEngine is only suitable for searching a relatively small collection of in-memory
objects that are not backed by Core Data (see RKManagedObjectSearchEngine).
@see RKManagedObjectSearchEngine
*/
@interface RKSearchEngine : NSObject
///—————————————————————————–
/// @name Configuring Search Parameters
///—————————————————————————–
/**
The type of matching to perform. Can be either RKSearchModeAnd or RKSearchModeOr.
**Default**: RKSearchModeOr
*/
@property (nonatomic, assign) RKSearchMode mode;
/**
A Boolean value that determines if the search query should be split into subterms at whitespace boundaries.
**Default**: YES
*/
@property (nonatomic, assign) BOOL tokenizeQuery;
/**
A Boolean value that determines if whitespace is to be stripped off of the search terms before searching.
This can prevent search misses when the terms have leading/trailing whitespace.
**Default**: YES
*/
@property (nonatomic, assign) BOOL stripsWhitespace;
/**
A Boolean value that determines if search terms should be matched case sensitively.
**Default**: NO
*/
@property (nonatomic, assign, getter = isCaseSensitive) BOOL caseSensitive;
/**
Creates and returns a search engine object.
@returns A search engine object.
*/
+ (id)searchEngine;
///—————————————————————————–
/// @name Performing a Search
///—————————————————————————–
/**
Searches a collection of RKSearchable objects for the given text using the configuration of the receiver
and returns an array of objects for which a match was found.
@return A new array containing the objects in the given collection for which a match was found.
@exception NSInvalidArgumentException Raised if any objects contained in the search collection do not
conform to the RKSearchable protocol.
*/
– (NSArray *)searchFor:(NSString *)searchText inCollection:(NSArray *)collection;
/**
Searches a set of properties in a collection of objects for the given text using the configuration of the receiver
and returns an array of objects for which a match was found.
@return A new array containing the objects in the given collection for which a match was found.
@exception NSInvalidArgumentException Raised if any objects contained in the search collection do not
conform to the RKSearchable protocol.
*/
– (NSArray *)searchFor:(NSString *)searchText onProperties:(NSArray *)properties inCollection:(NSArray *)collection;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKSearchEngine.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/RKSearchEngine.m
//
// RKSearchEngine.m
// RestKit
//
// Created by Blake Watters on 8/26/09.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKSearchEngine.h”
@implementation RKSearchEngine
@synthesize mode;
@synthesize tokenizeQuery;
@synthesize stripsWhitespace;
@synthesize caseSensitive;
+ (id)searchEngine
{
return [[[RKSearchEngine alloc] init] autorelease];
}
– (id)init
{
self = [super init];
if (self) {
mode = RKSearchModeOr;
tokenizeQuery = YES;
stripsWhitespace = YES;
caseSensitive = NO;
}
return self;
}
#pragma mark Private
#pragma mark –
– (NSString *)stripWhitespaceIfNecessary:(NSString *)string
{
if (stripsWhitespace) {
return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
return string;
}
– (NSArray *)tokenizeOrCollect:(NSString *)string
{
if (self.tokenizeQuery) {
return [string componentsSeparatedByString:@” “];
}
return [NSArray arrayWithObject:string];
}
– (NSArray *)searchWithTerms:(NSArray*)searchTerms onProperties:(NSArray *)properties inCollection:(NSArray *)collection compoundSelector:(SEL)selector
{
NSPredicate *searchPredicate = nil;
// do any of these properties contain all of these terms
NSMutableArray *propertyPredicates = [NSMutableArray array];
for (NSString *property in properties) {
NSMutableArray *termPredicates = [NSMutableArray array];
for (NSString *searchTerm in searchTerms) {
NSPredicate *predicate;
if (self.isCaseSensitive) {
predicate = [NSPredicate predicateWithFormat:@”(%K contains %@)”, property, searchTerm];
} else {
predicate = [NSPredicate predicateWithFormat:@”(%K contains[cd] %@)”, property, searchTerm];
}
[termPredicates addObject:predicate];
}
// build a predicate for all of the search terms
NSPredicate *termsPredicate = [NSCompoundPredicate performSelector:selector withObject:termPredicates];
[propertyPredicates addObject:termsPredicate];
}
searchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:propertyPredicates];
return [collection filteredArrayUsingPredicate:searchPredicate];
}
#pragma mark Public
#pragma mark –
– (NSArray *)searchFor:(NSString *)searchText inCollection:(NSArray *)collection
{
NSArray *properties = [NSArray arrayWithObject:@”searchableText”];
return [self searchFor:searchText onProperties:properties inCollection:collection];
}
– (NSArray *)searchFor:(NSString *)searchText onProperties:(NSArray *)properties inCollection:(NSArray *)collection
{
NSString *searchQuery = [[searchText copy] autorelease];
searchQuery = [self stripWhitespaceIfNecessary:searchQuery];
NSArray *searchTerms = [self tokenizeOrCollect:searchQuery];
if (mode == RKSearchModeOr) {
return [self searchWithTerms:searchTerms onProperties:properties inCollection:collection compoundSelector:@selector(orPredicateWithSubpredicates:)];
} else if (mode == RKSearchModeAnd) {
return [self searchWithTerms:searchTerms onProperties:properties inCollection:collection compoundSelector:@selector(andPredicateWithSubpredicates:)];
} else {
return nil;
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._RKSearchEngine.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/Support.h
//
// Support.h
// RestKit
//
// Created by Blake Watters on 9/30/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Load shared support code
#import “RKErrors.h”
#import “RKMIMETypes.h”
#import “RKLog.h”
#import “RKPathMatcher.h”
#import “RKDotNetDateFormatter.h”
#import “RKDirectory.h”
#import “RKBenchmark.h”
// Load our categories
#import “NSDictionary+RKAdditions.h”
#import “NSString+RKAdditions.h”
#import “NSBundle+RKAdditions.h”
#import “NSArray+RKAdditions.h”
#import “NSData+RKAdditions.h”
#import “NSURL+RKAdditions.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Support/._Support.h
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._Support
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKMappingTest.h
//
// RKMappingTest.h
// RestKit
//
// Created by Blake Watters on 2/17/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMappingOperation.h”
#import “RKMappingTestExpectation.h”
/**
An RKMappingTest object provides support for unit testing
a RestKit object mapping operation by evaluation expectations
against events recorded during an object mapping operation.
*/
@interface RKMappingTest : NSObject
///—————————————————————————–
/// @name Creating Tests
///—————————————————————————–
/**
Creates and returns a new test for a given object mapping and source object.
@param mapping The object mapping being tested.
@param sourceObject The source object being mapped.
@return A new mapping test object for a mapping and sourceObject.
*/
+ (RKMappingTest *)testForMapping:(RKObjectMapping *)mapping object:(id)sourceObject;
/**
Creates and returns a new test for a given object mapping, source object and destination
object.
@param mapping The object mapping being tested.
@param sourceObject The source object being mapped from.
@param destinationObject The destionation object being to.
@return A new mapping test object for a mapping, a source object and a destination object.
*/
+ (RKMappingTest *)testForMapping:(RKObjectMapping *)mapping sourceObject:(id)sourceObject destinationObject:(id)destinationObject;
/**
Initializes the receiver with a given object mapping, source object, and destination object.
@param mapping The object mapping being tested.
@param sourceObject The source object being mapped from.
@param destinationObject The destionation object being to.
@return The receiver, initialized with mapping, sourceObject and destinationObject.
*/
– (id)initWithMapping:(RKObjectMapping *)mapping sourceObject:(id)sourceObject destinationObject:(id)destinationObject;
///—————————————————————————–
/// @name Setting Expectations
///—————————————————————————–
/**
Creates and adds an expectation that a key path on the source object will be mapped to a new
key path on the destination object.
@param sourceKeyPath A key path on the sourceObject that should be mapped from.
@param destinationKeyPath A key path on the destinationObject that should be mapped to.
@see RKObjectMappingTestExpectation
*/
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath;
/**
Creates and adds an expectation that a key path on the source object will be mapped to a new
key path on the destination object with a given value.
@param sourceKeyPath A key path on the sourceObject that should be mapped from.
@param destinationKeyPath A key path on the destinationObject that should be mapped from.
@param value A value that is expected to be assigned to destinationKeyPath on the destinationObject.
@see RKObjectMappingTestExpectation
*/
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath withValue:(id)value;
/**
Creates and adds an expectation that a key path on the source object will be mapped to a new
key path on the destination object with a value that passes a given test block.
@param sourceKeyPath A key path on the sourceObject that should be mapped from.
@param destinationKeyPath A key path on the destinationObject that should be mapped to.
@param evaluationBlock A block with which to evaluate the success of the mapping.
@see RKObjectMappingTestExpectation
*/
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath passingTest:(BOOL (^)(RKObjectAttributeMapping *mapping, id value))evaluationBlock;
/**
Adds an expectation to the receiver to be evaluated during verification.
If the receiver has been configured with verifiesOnExpect = YES, the mapping
operation is performed immediately and the expectation is evaluated.
@param expectation An expectation object to evaluate during test verification.
@see RKObjectMappingTestExpectation
@see verifiesOnExpect
*/
– (void)addExpectation:(RKMappingTestExpectation *)expectation;
///—————————————————————————–
/// @name Verifying Results
///—————————————————————————–
/**
Performs the object mapping operation and records any mapping events that occur. The
mapping events can be verified against expectation through a subsequent call to verify.
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if mapping fails.
*/
– (void)performMapping;
/**
Verifies that the mapping is configured correctly by performing an object mapping operation
and ensuring that all expectations are met.
@exception NSInternalInconsistencyException Raises an
NSInternalInconsistencyException if mapping fails or any expectation is not satisfied.
*/
– (void)verify;
///—————————————————————————–
/// @name Test Configuration
///—————————————————————————–
/**
The object mapping under test.
*/
@property(nonatomic, strong, readonly) RKObjectMapping *mapping;
/**
A key path to apply to the source object to specify the location of the root
of the data under test. Useful when testing subsets of a larger payload or
object graph.
**Default**: nil
*/
@property(nonatomic, copy) NSString *rootKeyPath;
/**
The source object being mapped from.
*/
@property(nonatomic, strong, readonly) id sourceObject;
/**
The destionation object being mapped to.
If nil, the mapping test will instantiate a destination object to perform the mapping
by invoking `[self.mapping mappableObjectForData:self.sourceObject]` and set the
new object as the value for the destinationObject property.
@see [RKObjectMapping mappableObjectForData:]
*/
@property(nonatomic, strong, readonly) id destinationObject;
/**
A Boolean value that determines if expectations should be verified immediately
when added to the receiver.
**Default**: NO
*/
@property(nonatomic, assign) BOOL verifiesOnExpect;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKMappingTest.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKMappingTest.m
//
// RKMappingTest.m
// RestKit
//
// Created by Blake Watters on 2/17/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKMappingTest.h”
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
///—————————————————————————–
///—————————————————————————–
@interface RKMappingTestEvent : NSObject
@property (nonatomic, strong, readonly) RKObjectAttributeMapping *mapping;
@property (nonatomic, strong, readonly) id value;
@property (nonatomic, readonly) NSString *sourceKeyPath;
@property (nonatomic, readonly) NSString *destinationKeyPath;
+ (RKMappingTestEvent *)eventWithMapping:(RKObjectAttributeMapping *)mapping value:(id)value;
@end
@interface RKMappingTestEvent ()
@property (nonatomic, strong, readwrite) id value;
@property (nonatomic, strong, readwrite) RKObjectAttributeMapping *mapping;
@end
@implementation RKMappingTestEvent
@synthesize value;
@synthesize mapping;
+ (RKMappingTestEvent *)eventWithMapping:(RKObjectAttributeMapping *)mapping value:(id)value {
RKMappingTestEvent *event = [RKMappingTestEvent new];
event.value = value;
event.mapping = mapping;
return event;
}
– (NSString *)sourceKeyPath {
return self.mapping.sourceKeyPath;
}
– (NSString *)destinationKeyPath {
return self.mapping.destinationKeyPath;
}
– (NSString *)description {
return [NSString stringWithFormat:@”%@: mapped sourceKeyPath ‘%@’ => destinationKeyPath ‘%@’ with value: %@”, [self class], self.sourceKeyPath, self.destinationKeyPath, self.value];
}
@end
///—————————————————————————–
///—————————————————————————–
@interface RKMappingTest ()
@property (nonatomic, strong, readwrite) RKObjectMapping *mapping;
@property (nonatomic, strong, readwrite) id sourceObject;
@property (nonatomic, strong, readwrite) id destinationObject;
@property (nonatomic, strong) NSMutableArray *expectations;
@property (nonatomic, strong) NSMutableArray *events;
@property (nonatomic, assign, getter = hasPerformedMapping) BOOL performedMapping;
// Method Definitions for old compilers
– (void)performMapping;
– (void)verifyExpectation:(RKMappingTestExpectation *)expectation;
@end
@implementation RKMappingTest
@synthesize sourceObject = _sourceObject;
@synthesize destinationObject = _destinationObject;
@synthesize mapping = _mapping;
@synthesize rootKeyPath = _rootKeyPath;
@synthesize expectations = _expectations;
@synthesize events = _events;
@synthesize verifiesOnExpect = _verifiesOnExpect;
@synthesize performedMapping = _performedMapping;
+ (RKMappingTest *)testForMapping:(RKObjectMapping *)mapping object:(id)sourceObject {
return [[self alloc] initWithMapping:mapping sourceObject:sourceObject destinationObject:nil];
}
+ (RKMappingTest *)testForMapping:(RKObjectMapping *)mapping sourceObject:(id)sourceObject destinationObject:(id)destinationObject {
return [[self alloc] initWithMapping:mapping sourceObject:sourceObject destinationObject:destinationObject];
}
– (id)initWithMapping:(RKObjectMapping *)mapping sourceObject:(id)sourceObject destinationObject:(id)destinationObject {
NSAssert(sourceObject != nil, @”Cannot perform a mapping operation without a sourceObject object”);
NSAssert(mapping != nil, @”Cannot perform a mapping operation without a mapping”);
self = [super init];
if (self) {
_sourceObject = sourceObject;
_destinationObject = destinationObject;
_mapping = mapping;
_expectations = [NSMutableArray new];
_events = [NSMutableArray new];
_verifiesOnExpect = NO;
_performedMapping = NO;
}
return self;
}
– (void)addExpectation:(RKMappingTestExpectation *)expectation {
[self.expectations addObject:expectation];
if (self.verifiesOnExpect) {
[self performMapping];
[self verifyExpectation:expectation];
}
}
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath {
[self addExpectation:[RKMappingTestExpectation expectationWithSourceKeyPath:sourceKeyPath destinationKeyPath:destinationKeyPath]];
}
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath withValue:(id)value {
[self addExpectation:[RKMappingTestExpectation expectationWithSourceKeyPath:sourceKeyPath destinationKeyPath:destinationKeyPath value:value]];
}
– (void)expectMappingFromKeyPath:(NSString *)sourceKeyPath toKeyPath:(NSString *)destinationKeyPath passingTest:(BOOL (^)(RKObjectAttributeMapping *mapping, id value))evaluationBlock {
[self addExpectation:[RKMappingTestExpectation expectationWithSourceKeyPath:sourceKeyPath destinationKeyPath:destinationKeyPath evaluationBlock:evaluationBlock]];
}
– (RKMappingTestEvent *)eventMatchingKeyPathsForExpectation:(RKMappingTestExpectation *)expectation {
for (RKMappingTestEvent *event in self.events) {
if ([event.sourceKeyPath isEqualToString:expectation.sourceKeyPath] && [event.destinationKeyPath isEqualToString:expectation.destinationKeyPath]) {
return event;
}
}
return nil;
}
– (BOOL)event:(RKMappingTestEvent *)event satisfiesExpectation:(RKMappingTestExpectation *)expectation {
if (expectation.evaluationBlock) {
// Let the expectation block evaluate the match
return expectation.evaluationBlock(event.mapping, event.value);
} else if (expectation.value) {
// Use RestKit comparison magic to match values
return RKObjectIsValueEqualToValue(event.value, expectation.value);
}
// We only wanted to know that a mapping occured between the keyPaths
return YES;
}
– (void)performMapping {
NSAssert(self.mapping.objectClass, @”Cannot test a mapping that does not have a destination objectClass”);
// Ensure repeated invocations of verify only result in a single mapping operation
if (! self.hasPerformedMapping) {
id sourceObject = self.rootKeyPath ? [self.sourceObject valueForKeyPath:self.rootKeyPath] : self.sourceObject;
if (nil == self.destinationObject) {
self.destinationObject = [self.mapping mappableObjectForData:self.sourceObject];
}
RKObjectMappingOperation *mappingOperation = [RKObjectMappingOperation mappingOperationFromObject:sourceObject toObject:self.destinationObject withMapping:self.mapping];
NSError *error = nil;
mappingOperation.delegate = self;
BOOL success = [mappingOperation performMapping:&error];
if (! success) {
[NSException raise:NSInternalInconsistencyException format:@”%@: failure when mapping from %@ to %@ with mapping %@”,
[self description], self.sourceObject, self.destinationObject, self.mapping];
}
self.performedMapping = YES;
}
}
– (void)verifyExpectation:(RKMappingTestExpectation *)expectation {
RKMappingTestEvent *event = [self eventMatchingKeyPathsForExpectation:expectation];
if (event) {
// Found a matching event, check if it satisfies the expectation
if (! [self event:event satisfiesExpectation:expectation]) {
[NSException raise:NSInternalInconsistencyException format:@”%@: expectation not satisfied: %@, but instead got %@ ‘%@'”,
[self description], expectation, [event.value class], event.value];
}
} else {
// No match
[NSException raise:NSInternalInconsistencyException format:@”%@: expectation not satisfied: %@, but did not.”,
[self description], [expectation mappingDescription]];
}
}
– (void)verify {
[self performMapping];
for (RKMappingTestExpectation *expectation in self.expectations) {
[self verifyExpectation:expectation];
}
}
#pragma mark – RKObjecMappingOperationDelegate
– (void)addEvent:(RKMappingTestEvent *)event {
[self.events addObject:event];
}
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didSetValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKObjectAttributeMapping *)mapping {
[self addEvent:[RKMappingTestEvent eventWithMapping:mapping value:value]];
}
– (void)objectMappingOperation:(RKObjectMappingOperation *)operation didNotSetUnchangedValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKObjectAttributeMapping *)mapping {
[self addEvent:[RKMappingTestEvent eventWithMapping:mapping value:value]];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKMappingTest.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKMappingTestExpectation.h
//
// RKMappingTestExpectation.h
// RestKit
//
// Created by Blake Watters on 2/17/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectAttributeMapping.h”
/**
An RKMappingTestExpectation defines an expected mapping event that should
occur during the execution of a RKMappingTest.
@see RKMappingTest
*/
@interface RKMappingTestExpectation : NSObject
///—————————————————————————–
/// @name Creating Expectations
///—————————————————————————–
/**
Creates and returns a new expectation specifying that a key path in a source object should be
mapped to another key path on a destination object. The value mapped is not evaluated.
@param sourceKeyPath A key path on the source object that should be mapped.
@param destinationKeyPath A key path on the destination object that should be mapped onto.
@return An expectation specifying that sourceKeyPath should be mapped to destionationKeyPath.
*/
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath;
/**
Creates and returns a new expectation specifying that a key path in a source object should be
mapped to another key path on a destination object with a given value.
@param sourceKeyPath A key path on the source object that should be mapped.
@param destinationKeyPath A key path on the destination object that should be mapped onto.
@param value The value that is expected to be assigned to the destination object at destinationKeyPath.
@return An expectation specifying that sourceKeyPath should be mapped to destionationKeyPath with value.
*/
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath value:(id)value;
/**
Creates and returns a new expectation specifying that a key path in a source object should be
mapped to another key path on a destinaton object and that the attribute mapping and value should
evaluate to true with a given block.
@param sourceKeyPath A key path on the source object that should be mapped.
@param destinationKeyPath A key path on the destination object that should be mapped onto.
@param evaluationBlock A block with which to evaluate the success of the mapping.
@return An expectation specifying that sourceKeyPath should be mapped to destionationKeyPath with value.
*/
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath evaluationBlock:(BOOL (^)(RKObjectAttributeMapping *mapping, id value))evaluationBlock;
///—————————————————————————–
/// @name Expectation Values
///—————————————————————————–
/**
Returns a keyPath on the source object that a value should be mapped from.
*/
@property (nonatomic, copy, readonly) NSString *sourceKeyPath;
/**
Returns a keyPath on the destination object that a value should be mapped to.
*/
@property (nonatomic, copy, readonly) NSString *destinationKeyPath;
/**
Returns the expected value that should be set to the destinationKeyPath of the destination object.
*/
@property (nonatomic, strong, readonly) id value;
/**
A block used to evaluate if the expectation has been satisfied.
*/
@property (nonatomic, copy, readonly) BOOL (^evaluationBlock)(RKObjectAttributeMapping *mapping, id value);
/**
Returns a string summary of the expected keyPath mapping within the expectation
@return A string describing the expected sourceKeyPath to destinationKeyPath mapping.
*/
– (NSString *)mappingDescription;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKMappingTestExpectation.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKMappingTestExpectation.m
//
// RKMappingTestExpectation.m
// RestKit
//
// Created by Blake Watters on 2/17/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKMappingTestExpectation.h”
@interface RKMappingTestExpectation ()
@property (nonatomic, copy, readwrite) NSString *sourceKeyPath;
@property (nonatomic, copy, readwrite) NSString *destinationKeyPath;
@property (nonatomic, strong, readwrite) id value;
@property (nonatomic, copy, readwrite) BOOL (^evaluationBlock)(RKObjectAttributeMapping *mapping, id value);
@end
@implementation RKMappingTestExpectation
@synthesize sourceKeyPath;
@synthesize destinationKeyPath;
@synthesize value;
@synthesize evaluationBlock;
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath {
RKMappingTestExpectation *expectation = [self new];
expectation.sourceKeyPath = sourceKeyPath;
expectation.destinationKeyPath = destinationKeyPath;
return expectation;
}
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath value:(id)value {
RKMappingTestExpectation *expectation = [self new];
expectation.sourceKeyPath = sourceKeyPath;
expectation.destinationKeyPath = destinationKeyPath;
expectation.value = value;
return expectation;
}
+ (RKMappingTestExpectation *)expectationWithSourceKeyPath:(NSString *)sourceKeyPath destinationKeyPath:(NSString *)destinationKeyPath evaluationBlock:(BOOL (^)(RKObjectAttributeMapping *mapping, id value))testBlock {
RKMappingTestExpectation *expectation = [self new];
expectation.sourceKeyPath = sourceKeyPath;
expectation.destinationKeyPath = destinationKeyPath;
expectation.evaluationBlock = testBlock;
return expectation;
}
– (NSString *)mappingDescription {
return [NSString stringWithFormat:@”expected sourceKeyPath ‘%@’ to map to destinationKeyPath ‘%@'”,
self.sourceKeyPath, self.destinationKeyPath];
}
– (NSString *)description {
if (self.value) {
return [NSString stringWithFormat:@”expected sourceKeyPath ‘%@’ to map to destinationKeyPath ‘%@’ with %@ value ‘%@'”,
self.sourceKeyPath, self.destinationKeyPath, [self.value class], self.value];
} else if (self.evaluationBlock) {
return [NSString stringWithFormat:@”expected sourceKeyPath ‘%@’ to map to destinationKeyPath ‘%@’ satisfying evaluation block”,
self.sourceKeyPath, self.destinationKeyPath];
}
return [self mappingDescription];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKMappingTestExpectation.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTableControllerTestDelegate.h
//
// RKTableControllerTestDelegate.h
// RestKit
//
// Created by Blake Watters on 5/23/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#if TARGET_OS_IPHONE
#import “RKTableController.h”
#import “RKFetchedResultsTableController.h”
@interface RKAbstractTableControllerTestDelegate : NSObject
@property(nonatomic, readonly, getter = isCancelled) BOOL cancelled;
@property(nonatomic, assign) NSTimeInterval timeout;
@property(nonatomic, assign) BOOL awaitingResponse;
+ (id)tableControllerDelegate;
– (void)waitForLoad;
@end
@interface RKTableControllerTestDelegate : RKAbstractTableControllerTestDelegate
@end
@interface RKFetchedResultsTableControllerTestDelegate : RKAbstractTableControllerTestDelegate
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTableControllerTestDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTableControllerTestDelegate.m
//
// RKTableControllerTestDelegate.m
// RestKit
//
// Created by Blake Watters on 5/23/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import “RKTableControllerTestDelegate.h”
#import “RKLog.h”
#if TARGET_OS_IPHONE
@implementation RKAbstractTableControllerTestDelegate
@synthesize timeout = _timeout;
@synthesize awaitingResponse = _awaitingResponse;
@synthesize cancelled = _cancelled;
+ (id)tableControllerDelegate {
return [[self new] autorelease];
}
– (id)init {
self = [super init];
if (self) {
_timeout = 1.0;
_awaitingResponse = NO;
_cancelled = NO;
}
return self;
}
– (void)waitForLoad {
_awaitingResponse = YES;
NSDate *startDate = [NSDate date];
while (_awaitingResponse) {
RKLogTrace(@”Awaiting response = %d”, _awaitingResponse);
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
if ([[NSDate date] timeIntervalSinceDate:startDate] > self.timeout) {
NSLog(@”%@: Timed out!!!”, self);
_awaitingResponse = NO;
[NSException raise:nil format:@”*** Operation timed out after %f seconds…”, self.timeout];
}
}
}
#pragma RKTableControllerDelegate methods
– (void)tableControllerDidFinishLoad:(RKAbstractTableController *)tableController {
_awaitingResponse = NO;
}
– (void)tableController:(RKAbstractTableController*)tableController didFailLoadWithError:(NSError *)error {
_awaitingResponse = NO;
}
– (void)tableControllerDidCancelLoad:(RKAbstractTableController *)tableController {
_awaitingResponse = NO;
_cancelled = YES;
}
– (void)tableControllerDidFinalizeLoad:(RKAbstractTableController *)tableController {
_awaitingResponse = NO;
}
// NOTE – Delegate methods below are implemented to allow trampoline through
// OCMock expectations
– (void)tableControllerDidStartLoad:(RKAbstractTableController *)tableController
{}
– (void)tableControllerDidBecomeEmpty:(RKAbstractTableController *)tableController
{}
– (void)tableController:(RKAbstractTableController *)tableController willLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader
{}
– (void)tableController:(RKAbstractTableController *)tableController didLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader
{}
– (void)tableController:(RKAbstractTableController*)tableController willBeginEditing:(id)object atIndexPath:(NSIndexPath*)indexPath
{}
– (void)tableController:(RKAbstractTableController*)tableController didEndEditing:(id)object atIndexPath:(NSIndexPath*)indexPath
{}
– (void)tableController:(RKAbstractTableController*)tableController didInsertSection:(RKTableSection*)section atIndex:(NSUInteger)sectionIndex
{}
– (void)tableController:(RKAbstractTableController*)tableController didRemoveSection:(RKTableSection*)section atIndex:(NSUInteger)sectionIndex
{}
– (void)tableController:(RKAbstractTableController*)tableController didInsertObject:(id)object atIndexPath:(NSIndexPath*)indexPath
{}
– (void)tableController:(RKAbstractTableController*)tableController didUpdateObject:(id)object atIndexPath:(NSIndexPath*)indexPath
{}
– (void)tableController:(RKAbstractTableController*)tableController didDeleteObject:(id)object atIndexPath:(NSIndexPath*)indexPath
{}
– (void)tableController:(RKAbstractTableController*)tableController willAddSwipeView:(UIView*)swipeView toCell:(UITableViewCell*)cell forObject:(id)object
{}
– (void)tableController:(RKAbstractTableController*)tableController willRemoveSwipeView:(UIView*)swipeView fromCell:(UITableViewCell*)cell forObject:(id)object
{}
– (void)tableController:(RKTableController *)tableController didLoadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex
{}
– (void)tableController:(RKAbstractTableController *)tableController willDisplayCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath
{}
– (void)tableController:(RKAbstractTableController *)tableController didSelectCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath
{}
@end
@implementation RKTableControllerTestDelegate
– (void)tableController:(RKTableController *)tableController didLoadObjects:(NSArray *)objects inSection:(RKTableSection *)section
{}
@end
@implementation RKFetchedResultsTableControllerTestDelegate
– (void)tableController:(RKFetchedResultsTableController *)tableController didInsertSectionAtIndex:(NSUInteger)sectionIndex
{}
– (void)tableController:(RKFetchedResultsTableController *)tableController didDeleteSectionAtIndex:(NSUInteger)sectionIndex
{}
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTableControllerTestDelegate.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestConstants.m
//
// RKTestConstants.m
// RestKit
//
// Created by Blake Watters on 5/4/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
/*
This file defines constants used by the Testing module. It is necessary due to strange
linking errors when building for the Device. When these constants were defined within
RKTestFactory.m, they would resolve on the Simulator but produce linker when building
for Device. [sbw – 05/04/2012]
*/
NSString * const RKTestFactoryDefaultNamesClient = @”client”;
NSString * const RKTestFactoryDefaultNamesObjectManager = @”objectManager”;
NSString * const RKTestFactoryDefaultNamesMappingProvider = @”mappingProvider”;
NSString * const RKTestFactoryDefaultNamesManagedObjectStore = @”managedObjectStore”;
NSString * const RKTestFactoryDefaultStoreFilename = @”RKTests.sqlite”;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestConstants.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestFactory.h
//
// RKTestFactory.h
// RKGithub
//
// Created by Blake Watters on 2/16/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
The default filename used for managed object stores created via the factory.
@see [RKTestFactory setManagedObjectStoreFilename:]
*/
extern NSString * const RKTestFactoryDefaultStoreFilename;
/**
Defines optional callback methods for extending the functionality of the
factory. Implementation can be provided via a category.
@see RKTestFactory
*/
@protocol RKTestFactoryCallbacks
@optional
///—————————————————————————–
/// @name Customizing the Factory
///—————————————————————————–
/**
Application specific initialization point for the factory.
Called once per unit testing run when the factory singleton instance is initialized. RestKit
applications may override via a category.
*/
+ (void)didInitialize;
/**
Application specific customization point for the factory.
Invoked each time the factory is asked to set up the environment. RestKit applications
leveraging the factory may override via a category.
*/
+ (void)didSetUp;
/**
Application specific customization point for the factory.
Invoked each time the factory is tearing down the environment. RestKit applications
leveraging the factory may override via a category.
*/
+ (void)didTearDown;
@end
/*
Default Factory Names
*/
extern NSString * const RKTestFactoryDefaultNamesClient;
extern NSString * const RKTestFactoryDefaultNamesObjectManager;
extern NSString * const RKTestFactoryDefaultNamesMappingProvider;
extern NSString * const RKTestFactoryDefaultNamesManagedObjectStore;
/**
RKTestFactory provides an interface for initializing RestKit
objects within a unit testing environment. The factory is used to ensure isolation
between test cases by ensuring that RestKit’s important singleton objects are torn
down between tests and that each test is working within a clean Core Data environment.
Callback hooks are provided so that application specific set up and tear down logic can be
integrated as well.
The factory also provides for the definition of named factories for instantiating objects
quickly. At initialization, there are factories defined for creating instances of RKClient,
RKObjectManager, RKObjectMappingProvider, and RKManagedObjectStore. These factories may be
redefined within your application should you choose to utilize a subclass or wish to centralize
configuration of objects across the test suite. You may also define additional factories for building
instances of objects specific to your application using the same infrastructure.
*/
@interface RKTestFactory : NSObject
///—————————————————————————–
/// @name Configuring the Factory
///—————————————————————————–
/**
Returns the base URL with which to initialize RKClient and RKObjectManager
instances created via the factory.
@return The base URL for the factory.
*/
+ (RKURL *)baseURL;
/**
Sets the base URL for the factory.
@param URL The new base URL.
*/
+ (void)setBaseURL:(RKURL *)URL;
/**
Returns the base URL as a string value.
@return The base URL for the factory, as a string.
*/
+ (NSString *)baseURLString;
/**
Sets the base URL for the factory to a new value by constructing an RKURL
from the given string.
@param baseURLString A string containing the URL to set as the base URL for the factory.
*/
+ (void)setBaseURLString:(NSString *)baseURLString;
/**
Returns the filename used when constructing instances of RKManagedObjectStore
via the factory.
@return A string containing the filename to use when creating a managed object store.
*/
+ (NSString *)managedObjectStoreFilename;
/**
Sets the filename to use when the factory constructs an instance of RKManagedObjectStore.
@param managedObjectStoreFilename A string containing the filename to use when creating managed object
store instances.
*/
+ (void)setManagedObjectStoreFilename:(NSString *)managedObjectStoreFilename;
///—————————————————————————–
/// @name Defining & Instantiating Objects from Factories
///—————————————————————————–
/**
Defines a factory with a given name for building object instances using the
given block. When the factory singleton receives an objectFromFactory: message,
the block designated for the given factory name is invoked and the resulting object
reference is returned.
Existing factories can be invoking defineFactory:withBlock: with an existing factory name.
@param factoryName The name to assign the factory.
@param block A block to execute when building an object instance for the factory name.
@return A configured object instance.
*/
+ (void)defineFactory:(NSString *)factoryName withBlock:(id (^)())block;
/**
Creates and returns a new instance of an object using the factory with the given
name.
@param factoryName The name of the factory to use when building the requested object.
@raises NSInvalidArgumentException Raised if a factory with the given name is not defined.
@return An object built using the factory registered for the given name.
*/
+ (id)objectFromFactory:(NSString *)factoryName;
/**
Returns a set of names for all defined factories.
@return A set of the string names for all defined factories.
*/
+ (NSSet *)factoryNames;
///—————————————————————————–
/// @name Building Instances
///—————————————————————————–
/**
Creates and returns an RKClient instance using the factory defined
for the name RKTestFactoryDefaultNamesClient.
@return A new client instance.
*/
+ (id)client;
/**
Creates and returns an RKObjectManager instance using the factory defined
for the name RKTestFactoryDefaultNamesObjectManager.
@return A new object manager instance.
*/
+ (id)objectManager;
/**
Creates and returns an RKObjectMappingProvider instance using the factory defined
for the name RKTestFactoryDefaultNamesMappingProvider.
@return A new object mapping provider instance.
*/
+ (id)mappingProvider;
/**
Creates and returns a RKManagedObjectStore instance using the factory defined
for the name RKTestFactoryDefaultNamesManagedObjectStore.
A new managed object store will be configured and returned. If there is an existing
persistent store (i.e. from a previous test invocation), then the persistent store
is deleted.
@return A new managed object store instance.
*/
+ (id)managedObjectStore;
///—————————————————————————–
/// @name Managing Test State
///—————————————————————————–
/**
Sets up the RestKit testing environment. Invokes the didSetUp callback for application
specific setup.
*/
+ (void)setUp;
/**
Tears down the RestKit testing environment by clearing singleton instances, helping to
ensure test case isolation. Invokes the didTearDown callback for application specific
cleanup.
*/
+ (void)tearDown;
///—————————————————————————–
/// @name Other Tasks
///—————————————————————————–
/**
Clears the contents of the cache directory by removing the directory and
recreating it.
@see [RKDirectory cachesDirectory]
*/
+ (void)clearCacheDirectory;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestFactory.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestFactory.m
//
// RKTestFactory.m
// RKGithub
//
// Created by Blake Watters on 2/16/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKTestFactory.h”
@interface RKTestFactory ()
@property (nonatomic, strong) RKURL *baseURL;
@property (nonatomic, strong) NSString *managedObjectStoreFilename;
@property (nonatomic, strong) NSMutableDictionary *factoryBlocks;
+ (RKTestFactory *)sharedFactory;
– (void)defineFactory:(NSString *)factoryName withBlock:(id (^)())block;
– (id)objectFromFactory:(NSString *)factoryName;
– (void)defineDefaultFactories;
@end
static RKTestFactory *sharedFactory = nil;
@implementation RKTestFactory
@synthesize baseURL = _baseURL;
@synthesize managedObjectStoreFilename = _managedObjectStoreFilename;
@synthesize factoryBlocks = _factoryBlocks;
+ (void)initialize
{
// Ensure the shared factory is initialized
[self sharedFactory];
if ([RKTestFactory respondsToSelector:@selector(didInitialize)]) {
[RKTestFactory didInitialize];
}
}
+ (RKTestFactory *)sharedFactory
{
if (! sharedFactory) {
sharedFactory = [RKTestFactory new];
}
return sharedFactory;
}
– (id)init
{
self = [super init];
if (self) {
self.baseURL = [RKURL URLWithString:@”http://127.0.0.1:4567″];
self.managedObjectStoreFilename = RKTestFactoryDefaultStoreFilename;
self.factoryBlocks = [NSMutableDictionary new];
[self defineDefaultFactories];
}
return self;
}
– (void)defineFactory:(NSString *)factoryName withBlock:(id (^)())block
{
[self.factoryBlocks setObject:[block copy] forKey:factoryName];
}
– (id)objectFromFactory:(NSString *)factoryName
{
id (^block)() = [self.factoryBlocks objectForKey:factoryName];
NSAssert(block, @”No factory is defined with the name ‘%@'”, factoryName);
return block();
}
– (void)defineDefaultFactories
{
[self defineFactory:RKTestFactoryDefaultNamesClient withBlock:^id {
__block RKClient *client;
RKLogSilenceComponentWhileExecutingBlock(lcl_cRestKitNetworkReachability, ^{
RKLogSilenceComponentWhileExecutingBlock(lcl_cRestKitSupport, ^{
client = [RKClient clientWithBaseURL:self.baseURL];
client.requestQueue.suspended = NO;
[client.reachabilityObserver getFlags];
});
});
return client;
}];
[self defineFactory:RKTestFactoryDefaultNamesObjectManager withBlock:^id {
__block RKObjectManager *objectManager;
RKLogSilenceComponentWhileExecutingBlock(lcl_cRestKitNetworkReachability, ^{
RKLogSilenceComponentWhileExecutingBlock(lcl_cRestKitSupport, ^{
objectManager = [RKObjectManager managerWithBaseURL:self.baseURL];
RKObjectMappingProvider *mappingProvider = [self objectFromFactory:RKTestFactoryDefaultNamesMappingProvider];
objectManager.mappingProvider = mappingProvider;
// Force reachability determination
[objectManager.client.reachabilityObserver getFlags];
});
});
return objectManager;
}];
[self defineFactory:RKTestFactoryDefaultNamesMappingProvider withBlock:^id {
RKObjectMappingProvider *mappingProvider = [RKObjectMappingProvider mappingProvider];
return mappingProvider;
}];
[self defineFactory:RKTestFactoryDefaultNamesManagedObjectStore withBlock:^id {
NSString *storePath = [[RKDirectory applicationDataDirectory] stringByAppendingPathComponent:RKTestFactoryDefaultStoreFilename];
if ([[NSFileManager defaultManager] fileExistsAtPath:storePath]) {
[RKManagedObjectStore deleteStoreInApplicationDataDirectoryWithFilename:RKTestFactoryDefaultStoreFilename];
}
RKManagedObjectStore *store = [RKManagedObjectStore objectStoreWithStoreFilename:RKTestFactoryDefaultStoreFilename];
return store;
}];
}
#pragma mark – Public Static Interface
+ (RKURL *)baseURL
{
return [RKTestFactory sharedFactory].baseURL;
}
+ (void)setBaseURL:(RKURL *)URL
{
[RKTestFactory sharedFactory].baseURL = URL;
}
+ (NSString *)baseURLString
{
return [[[RKTestFactory sharedFactory] baseURL] absoluteString];
}
+ (void)setBaseURLString:(NSString *)baseURLString
{
[[RKTestFactory sharedFactory] setBaseURL:[RKURL URLWithString:baseURLString]];
}
+ (NSString *)managedObjectStoreFilename
{
return [RKTestFactory sharedFactory].managedObjectStoreFilename;
}
+ (void)setManagedObjectStoreFilename:(NSString *)managedObjectStoreFilename
{
[RKTestFactory sharedFactory].managedObjectStoreFilename = managedObjectStoreFilename;
}
+ (void)defineFactory:(NSString *)factoryName withBlock:(id (^)())block
{
[[RKTestFactory sharedFactory] defineFactory:factoryName withBlock:block];
}
+ (id)objectFromFactory:(NSString *)factoryName
{
return [[RKTestFactory sharedFactory] objectFromFactory:factoryName];
}
+ (NSSet *)factoryNames
{
return [NSSet setWithArray:[[RKTestFactory sharedFactory].factoryBlocks allKeys] ];
}
+ (id)client
{
RKClient *client = [self objectFromFactory:RKTestFactoryDefaultNamesClient];
[RKClient setSharedClient:client];
return client;
}
+ (id)objectManager
{
RKObjectManager *objectManager = [self objectFromFactory:RKTestFactoryDefaultNamesObjectManager];
[RKObjectManager setSharedManager:objectManager];
[RKClient setSharedClient:objectManager.client];
return objectManager;
}
+ (id)mappingProvider
{
RKObjectMappingProvider *mappingProvider = [self objectFromFactory:RKTestFactoryDefaultNamesMappingProvider];
return mappingProvider;
}
+ (id)managedObjectStore
{
RKManagedObjectStore *objectStore = [self objectFromFactory:RKTestFactoryDefaultNamesManagedObjectStore];
[RKManagedObjectStore setDefaultObjectStore:objectStore];
return objectStore;
}
+ (void)setUp
{
[RKObjectManager setDefaultMappingQueue:dispatch_queue_create(“org.restkit.ObjectMapping”, DISPATCH_QUEUE_SERIAL)];
[RKObjectMapping setDefaultDateFormatters:nil];
// Delete the store if it exists
NSString *path = [[RKDirectory applicationDataDirectory] stringByAppendingPathComponent:RKTestFactoryDefaultStoreFilename];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[RKManagedObjectStore deleteStoreInApplicationDataDirectoryWithFilename:RKTestFactoryDefaultStoreFilename];
}
if ([self respondsToSelector:@selector(didSetUp)]) {
[self didSetUp];
}
}
+ (void)tearDown
{
[RKObjectManager setSharedManager:nil];
[RKClient setSharedClient:nil];
[RKManagedObjectStore setDefaultObjectStore:nil];
if ([self respondsToSelector:@selector(didTearDown)]) {
[self didTearDown];
}
}
+ (void)clearCacheDirectory
{
NSError* error = nil;
NSString* cachePath = [RKDirectory cachesDirectory];
BOOL success = [[NSFileManager defaultManager] removeItemAtPath:cachePath error:&error];
if (success) {
RKLogDebug(@”Cleared cache directory…”);
success = [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:YES attributes:nil error:&error];
if (!success) {
RKLogError(@”Failed creation of cache path ‘%@’: %@”, cachePath, [error localizedDescription]);
}
} else {
RKLogError(@”Failed to clear cache path ‘%@’: %@”, cachePath, [error localizedDescription]);
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestFactory.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestFixture.h
//
// RKTestFixture.h
// RestKit
//
// Created by Blake Watters on 2/1/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#if TARGET_OS_IPHONE
#import
#endif
/**
Provides a static method API for conveniently accessing fixture data
contained within a designated NSBundle. Useful when writing unit tests that
leverage fixture data for testing parsing and object mapping operations.
*/
@interface RKTestFixture : NSObject
/**
Returns the NSBundle object designated as the source location for unit testing fixture data.
@return The NSBundle object designated as the source location for unit testing fixture data
or nil if none has been configured.
*/
+ (NSBundle *)fixtureBundle;
/**
Designates the specified NSBundle object as the source location for unit testing fixture data.
@param bundle The new fixture NSBundle object.
*/
+ (void)setFixtureBundle:(NSBundle *)bundle;
/**
Returns the full path to the specified fixture file on within the fixture bundle.
@param fixtureName The name of the fixture file.
@return The full path to the specified fixture file or nil if it cannot be located.
*/
+ (NSString *)pathForFixture:(NSString *)fixtureName;
#if TARGET_OS_IPHONE
/**
Creates and returns an image object by loading the image data from the fixture identified by the specified file name.
@param fixtureName The name of the fixture file.
@return A new image object for the specified fixture, or nil if the method could not initialize the image from the specified file.
*/
+ (UIImage *)imageWithContentsOfFixture:(NSString *)fixtureName;
#endif
/**
Creates and returns a string object by reading data from the fixture identified by the specified file name using UTF-8 encoding.
@param fixtureName The name of the fixture file.
@return A string created by reading data from the specified fixture file using the NSUTF8StringEncoding.
*/
+ (NSString *)stringWithContentsOfFixture:(NSString *)fixtureName;
/**
Creates and returns a data object by reading every byte from the fixture identified by the specified file name.
@param fixtureName The name of the resource file.
@return A data object by reading every byte from the fixture file.
*/
+ (NSData *)dataWithContentsOfFixture:(NSString *)fixtureName;
/**
Returns the MIME Type for the fixture identified by the specified name.
@param fixtureName The name of the fixture file.
@return The MIME Type for the resource file or nil if the file could not be located.
*/
+ (NSString *)MIMETypeForFixture:(NSString *)fixtureName;
/**
Creates and returns an object representation of the data from the fixture identified by the specified file name by reading the
data as a string and parsing it using a parser appropriate for the MIME Type of the file.
@param fixtureName The name of the resource file.
@return A new image object for the specified file, or nil if the method could not initialize the image from the specified file.
@see RKParserRegistry
*/
+ (id)parsedObjectWithContentsOfFixture:(NSString *)fixtureName;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestFixture.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestFixture.m
//
// RKTestFixture.m
// RestKit
//
// Created by Blake Watters on 2/1/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTestFixture.h”
#import “NSBundle+RKAdditions.h”
static NSBundle *fixtureBundle = nil;
@implementation RKTestFixture
+ (NSBundle *)fixtureBundle {
NSAssert(fixtureBundle != nil, @”Bundle for fixture has not been set. Use setFixtureBundle: to set it.”);
return fixtureBundle;
}
+ (void)setFixtureBundle:(NSBundle *)bundle {
NSAssert(bundle != nil, @”Bundle for fixture cannot be nil.”);
[bundle retain];
[fixtureBundle release];
fixtureBundle = bundle;
}
+ (NSString *)pathForFixture:(NSString *)fixtureName {
return [[self fixtureBundle] pathForResource:fixtureName ofType:nil];
}
#if TARGET_OS_IPHONE
+ (UIImage *)imageWithContentsOfFixture:(NSString *)fixtureName {
return [[self fixtureBundle] imageWithContentsOfResource:fixtureName withExtension:nil];
}
#endif
+ (NSString *)stringWithContentsOfFixture:(NSString *)fixtureName {
return [[self fixtureBundle] stringWithContentsOfResource:fixtureName withExtension:nil encoding:NSUTF8StringEncoding];
}
+ (NSData *)dataWithContentsOfFixture:(NSString *)fixtureName {
return [[self fixtureBundle] dataWithContentsOfResource:fixtureName withExtension:nil];
}
+ (NSString *)MIMETypeForFixture:(NSString *)fixtureName {
return [[self fixtureBundle] MIMETypeForResource:fixtureName withExtension:nil];
}
+ (id)parsedObjectWithContentsOfFixture:(NSString *)fixtureName {
return [[self fixtureBundle] parsedObjectWithContentsOfResource:fixtureName withExtension:nil];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestFixture.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestNotificationObserver.h
//
// RKTestNotificationObserver.h
// RestKit
//
// Created by Jeff Arena on 8/23/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
/**
An RKTestNotificationObserver object provides support for awaiting a notification
to be posted as the result of an asynchronous operation by spinning the run loop. This
enables a straight-forward unit testing workflow by blocking execution of the test until
a notification is posted.
*/
@interface RKTestNotificationObserver : NSObject
/**
The name of the notification the receiver is awaiting.
*/
@property (nonatomic, copy) NSString* name;
/**
The object expected to post the notification the receiver is awaiting.
Can be nil.
*/
@property (nonatomic, assign) id object;
/**
The timeout interval, in seconds, to wait for the notification to be posted.
**Default**: 3 seconds
*/
@property (nonatomic, assign) NSTimeInterval timeout;
/**
Creates and initializes a notification obsercer object.
@return The newly created notification observer.
*/
+ (RKTestNotificationObserver *)notificationObserver;
/**
Instantiate a notification observer for the given notification name and object
@param notificationName The name of the NSNotification we want to watch for
@param notificationSender The source object of the NSNotification we want to watch for
@return The newly created notification observer initialized with notificationName and notificationSender.
*/
+ (RKTestNotificationObserver *)notificationObserverForName:(NSString *)notificationName object:(id)notificationSender;
/**
Instantiate a notification observer for the given notification name
@param notificationName The name of the NSNotification we want to watch for
*/
+ (RKTestNotificationObserver *)notificationObserverForName:(NSString *)notificationName;
/**
Wait for a notification matching the name and source object we are observing to be posted.
This method will block by spinning the runloop waiting for an appropriate notification matching
our observed name and object to be posted or the timeout configured is exceeded.
*/
– (void)waitForNotification;
/*** @name Block Helpers */
/**
Configures a notification observer to wait for the a notification with the given name to be posted
by the source object during execution of the block.
@param name The name of the notification we are waiting for
@param notificationSender The object we are waiting to post the notification
@param block A block to invoke to trigger the notification activity
*/
+ (void)waitForNotificationWithName:(NSString *)name object:(id)notificationSender usingBlock:(void(^)())block;
/**
Configures a notification observer to wait for the a notification with the given name to be posted
during execution of the block.
@param name The name of the notification we are waiting for
@param block A block to invoke to trigger the notification activity
*/
+ (void)waitForNotificationWithName:(NSString *)name usingBlock:(void(^)())block;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestNotificationObserver.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestNotificationObserver.m
//
// RKTestNotificationObserver.m
// RestKit
//
// Created by Jeff Arena on 8/23/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKTestNotificationObserver.h”
@interface RKTestNotificationObserver ()
@property (nonatomic, assign, getter = isAwaitingNotification) BOOL awaitingNotification;
@end
@implementation RKTestNotificationObserver
@synthesize object;
@synthesize name;
@synthesize timeout;
@synthesize awaitingNotification;
+ (void)waitForNotificationWithName:(NSString *)name object:(id)object usingBlock:(void(^)())block {
RKTestNotificationObserver *observer = [RKTestNotificationObserver notificationObserverForName:name object:object];
block();
[observer waitForNotification];
}
+ (void)waitForNotificationWithName:(NSString *)name usingBlock:(void(^)())block {
[self waitForNotificationWithName:name object:nil usingBlock:block];
}
+ (RKTestNotificationObserver *)notificationObserver {
return [[[self alloc] init] autorelease];
}
+ (RKTestNotificationObserver *)notificationObserverForName:(NSString *)notificationName object:(id)object {
RKTestNotificationObserver *notificationObserver = [self notificationObserver];
notificationObserver.object = object;
notificationObserver.name = notificationName;
return notificationObserver;
}
+ (RKTestNotificationObserver *)notificationObserverForName:(NSString *)notificationName {
return [self notificationObserverForName:notificationName object:nil];
}
– (id)init {
self = [super init];
if (self) {
timeout = 5;
awaitingNotification = NO;
}
return self;
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
– (void)waitForNotification {
NSAssert(name, @”Notification name cannot be nil”);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processNotification:)
name:self.name
object:self.object];
awaitingNotification = YES;
NSDate *startDate = [NSDate date];
while (self.isAwaitingNotification) {
[[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];
awaitingNotification = NO;
}
}
}
– (void)processNotification:(NSNotification*)notification {
NSAssert([name isEqualToString:notification.name],
@”Received notification (%@) differs from expected notification (%@)”,
notification.name, name);
awaitingNotification = NO;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestNotificationObserver.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestResponseLoader.h
//
// RKTestResponseLoader.h
// RestKit
//
// Created by Blake Watters on 1/14/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectLoader.h”
/**
An RKTestResponseLoader object provides testing support for asynchronously loading an RKRequest or
RKObjectLoader object while blocking the execution of the current thread by spinning the run loop.
This enables a straight-forward unit testing workflow for asynchronous network operations.
RKTestResponseLoader instances are designed to act as as the delegate for an RKObjectLoader or RKRequest
object under test. Once assigned as the delegate to a request and the request has been sent,
waitForResponse: is invoked to block execution until the response is loaded.
*/
@interface RKTestResponseLoader : NSObject
/**
The RKResponse object loaded from the RKRequest or RKObjectLoader the receiver is acting as the delegate for.
**/
@property (nonatomic, retain, readonly) RKResponse *response;
/**
The collection of objects loaded from the RKObjectLoader the receiver is acting as the delegate for.
*/
@property (nonatomic, retain, readonly) NSArray *objects;
/**
A Boolean value that indicates whether a response was loaded successfully.
@return YES if a response was loaded successfully.
*/
@property (nonatomic, readonly, getter = wasSuccessful) BOOL successful;
/**
A Boolean value that indicates whether the RKRequest or RKObjectLoader the receiver is acting as the delegate for was cancelled.
@return YES if the request was cancelled
*/
@property (nonatomic, readonly, getter = wasCancelled) BOOL cancelled;
/**
A Boolean value that indicates if an unexpected response was loaded.
@return YES if the request loaded an unknown response.
@see [RKObjectLoaderDelegate objectLoaderDidLoadUnexpectedResponse:]
*/
@property (nonatomic, readonly, getter = loadedUnexpectedResponse) BOOL unexpectedResponse;
/**
An NSError value that was loaded from the RKRequest or RKObjectLoader the receiver is acting as the delegate for.
@see [RKRequestDelegate request:didFailLoadWithError:]
@see [RKObjectLoaderDelegate objectLoader:didFailWithError:]
*/
@property (nonatomic, copy, readonly) NSError *error;
/**
The timeout interval, in seconds, to wait for a response to load.
The default value is 4 seconds.
@see [RKTestResponseLoader waitForResponse]
*/
@property (nonatomic, assign) NSTimeInterval timeout;
/**
Creates and returns a test response loader object.
@return A new response loader object.
*/
+ (id)responseLoader;
/**
Waits for an asynchronous RKRequest or RKObjectLoader network operation to load a response
by spinning the current run loop to block the current thread of execution.
The wait operation is guarded by a timeout
*/
– (void)waitForResponse;
/**
Returns the localized description error message for the error.
TODO: Why not just move this to NSError+RKAdditions?
@return The localized description of the error or nil.
*/
– (NSString *)errorMessage;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestResponseLoader.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/RKTestResponseLoader.m
//
// RKTestResponseLoader.m
// RestKit
//
// Created by Blake Watters on 1/14/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTestResponseLoader.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitTesting
NSString * const RKTestResponseLoaderTimeoutException = @”RKTestResponseLoaderTimeoutException”;
@interface RKTestResponseLoader ()
@property (nonatomic, assign, getter = isAwaitingResponse) BOOL awaitingResponse;
@property (nonatomic, retain, readwrite) RKResponse *response;
@property (nonatomic, copy, readwrite) NSError *error;
@property (nonatomic, retain, readwrite) NSArray *objects;
@end
@implementation RKTestResponseLoader
@synthesize response;
@synthesize objects;
@synthesize error;
@synthesize successful;
@synthesize timeout;
@synthesize cancelled;
@synthesize unexpectedResponse;
@synthesize awaitingResponse;
+ (RKTestResponseLoader *)responseLoader {
return [[[self alloc] init] autorelease];
}
– (id)init {
self = [super init];
if (self) {
timeout = 4;
awaitingResponse = NO;
}
return self;
}
– (void)dealloc {
[response release];
response = nil;
[error release];
error = nil;
[objects release];
objects = nil;
[super dealloc];
}
– (void)waitForResponse {
awaitingResponse = YES;
NSDate *startDate = [NSDate date];
RKLogTrace(@”%@ Awaiting response loaded from for %f seconds…”, self, self.timeout);
while (awaitingResponse) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
if ([[NSDate date] timeIntervalSinceDate:startDate] > self.timeout) {
[NSException raise:RKTestResponseLoaderTimeoutException format:@”*** Operation timed out after %f seconds…”, self.timeout];
awaitingResponse = NO;
}
}
}
– (void)loadError:(NSError *)theError {
awaitingResponse = NO;
successful = NO;
self.error = theError;
}
– (NSString *)errorMessage {
if (self.error) {
return [[self.error userInfo] valueForKey:NSLocalizedDescriptionKey];
}
return nil;
}
– (void)request:(RKRequest *)request didReceiveResponse:(RKResponse *)response {
// Implemented for expectations
}
– (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)aResponse {
self.response = aResponse;
// If request is an Object Loader, then objectLoader:didLoadObjects:
// will be sent after didLoadResponse:
if (NO == [request isKindOfClass:[RKObjectLoader class]]) {
awaitingResponse = NO;
successful = YES;
}
}
– (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)anError {
// If request is an Object Loader, then objectLoader:didFailWithError:
// will be sent after didFailLoadWithError:
if (NO == [request isKindOfClass:[RKObjectLoader class]]) {
[self loadError:anError];
}
// Ensure we get no further delegate messages
[request cancel];
}
– (void)requestDidCancelLoad:(RKRequest *)request {
awaitingResponse = NO;
successful = NO;
cancelled = YES;
}
– (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)theObjects {
RKLogTrace(@”%@ Loaded response for %@ with body: %@”, self, objectLoader, [objectLoader.response bodyAsString]);
RKLogDebug(@”%@ Loaded objects for %@: %@”, self, objectLoader, objects);
self.objects = theObjects;
awaitingResponse = NO;
successful = YES;
}
– (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)theError {
[self loadError:theError];
}
– (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader *)objectLoader {
RKLogDebug(@”%@ Loaded unexpected response for: %@”, self, objectLoader);
successful = NO;
awaitingResponse = NO;
unexpectedResponse = YES;
}
– (void)objectLoaderDidFinishLoading:(RKObjectLoader *)objectLoader {
// Implemented for expectations
}
#pragma mark – OAuth delegates
– (void)OAuthClient:(RKOAuthClient *)client didAcquireAccessToken:(NSString *)token {
awaitingResponse = NO;
successful = YES;
}
– (void)OAuthClient:(RKOAuthClient *)client didFailWithInvalidGrantError:(NSError *)error {
awaitingResponse = NO;
successful = NO;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._RKTestResponseLoader.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/Testing.h
//
// Testing.h
// RestKit
//
// Created by Blake Watters on 2/1/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKTestFixture.h”
#import “RKTestNotificationObserver.h”
#import “RKTestResponseLoader.h”
#import “RKTestFactory.h”
#import “RKMappingTest.h”
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/Testing/._Testing.h
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._Testing
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKAbstractTableController.h
//
// RKAbstractTableController.h
// RestKit
//
// Created by Jeff Arena on 8/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#import “RKTableViewCellMappings.h”
#import “RKTableItem.h”
#import “RKObjectManager.h”
#import “RKObjectMapping.h”
#import “RKObjectLoader.h”
///—————————————————————————–
/// @name Constants
///—————————————————————————–
/**
Posted when the table controller starts loading.
*/
extern NSString * const RKTableControllerDidStartLoadNotification;
/**
Posted when the table controller finishes loading.
*/
extern NSString * const RKTableControllerDidFinishLoadNotification;
/**
Posted when the table controller has loaded objects into the table view.
*/
extern NSString * const RKTableControllerDidLoadObjectsNotification;
/**
Posted when the table controller has loaded an empty collection of objects into the table view.
*/
extern NSString * const RKTableControllerDidLoadEmptyNotification;
/**
Posted when the table controller has loaded an error.
*/
extern NSString * const RKTableControllerDidLoadErrorNotification;
/**
Posted when the table controller has transitioned from an offline to online state.
*/
extern NSString * const RKTableControllerDidBecomeOnline;
/**
Posted when the table controller has transitioned from an online to an offline state.
*/
extern NSString * const RKTableControllerDidBecomeOffline;
@protocol RKAbstractTableControllerDelegate;
/**
@enum RKTableControllerState
@constant RKTableControllerStateNormal Indicates that the table has
loaded normally and is displaying cell content. It is not loading content,
is not empty, has not loaded an error, and is not offline.
@constant RKTableControllerStateLoading Indicates that the table controller
is loading content from a remote source.
@constant RKTableControllerStateEmpty Indicates that the table controller has
retrieved an empty collection of objects.
@constant RKTableControllerStateError Indicates that the table controller has
encountered an error while attempting to load.
@constant RKTableControllerStateOffline Indicates that the table controller is
offline and cannot perform network access.
@constant RKTableControllerStateNotYetLoaded Indicates that the table controller is
has not yet attempted a load and state is unknown.
*/
enum RKTableControllerState {
RKTableControllerStateNormal = 0,
RKTableControllerStateLoading = 1 << 1,
RKTableControllerStateEmpty = 1 << 2,
RKTableControllerStateError = 1 << 3,
RKTableControllerStateOffline = 1 << 4,
RKTableControllerStateNotYetLoaded = 0xFF000000
};
typedef NSUInteger RKTableControllerState;
/**
RKAbstractTableController is an abstract base class for concrete table controller classes.
A table controller object acts as both the delegate and data source for a UITableView
object and leverages the RestKit object mapping engine to transform local domain models
into UITableViewCell representations. Concrete implementations are provided for the
display of static table views and Core Data backed fetched results controller basied
table views.
*/
@interface RKAbstractTableController : NSObject
///—————————————————————————–
/// @name Configuring the Table Controller
///—————————————————————————–
@property (nonatomic, assign) id
@property (nonatomic, readonly) UIViewController *viewController;
@property (nonatomic, readonly) UITableView *tableView;
@property (nonatomic, assign) UITableViewRowAnimation defaultRowAnimation;
@property (nonatomic, assign) BOOL pullToRefreshEnabled;
@property (nonatomic, assign) BOOL canEditRows;
@property (nonatomic, assign) BOOL canMoveRows;
@property (nonatomic, assign) BOOL autoResizesForKeyboard;
///—————————————————————————–
/// @name Instantiation
///—————————————————————————–
+ (id)tableControllerWithTableView:(UITableView *)tableView
forViewController:(UIViewController *)viewController;
+ (id)tableControllerForTableViewController:(UITableViewController *)tableViewController;
– (id)initWithTableView:(UITableView *)tableView
viewController:(UIViewController *)viewController;
///—————————————————————————–
/// @name Object to Table View Cell Mappings
///—————————————————————————–
@property (nonatomic, retain) RKTableViewCellMappings *cellMappings;
– (void)mapObjectsWithClass:(Class)objectClass toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping;
– (void)mapObjectsWithClassName:(NSString *)objectClassName toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping;
– (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath;
– (RKTableViewCellMapping *)cellMappingForObjectAtIndexPath:(NSIndexPath *)indexPath;
/**
Return the index path of the object within the table
*/
– (NSIndexPath *)indexPathForObject:(id)object;
– (UITableViewCell *)cellForObject:(id)object;
– (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation;
///—————————————————————————–
/// @name Header and Footer Rows
///—————————————————————————–
– (void)addHeaderRowForItem:(RKTableItem *)tableItem;
– (void)addFooterRowForItem:(RKTableItem *)tableItem;
– (void)addHeaderRowWithMapping:(RKTableViewCellMapping *)cellMapping;
– (void)addFooterRowWithMapping:(RKTableViewCellMapping *)cellMapping;
– (void)removeAllHeaderRows;
– (void)removeAllFooterRows;
///—————————————————————————–
/// @name RESTful Table Loading
///—————————————————————————–
/**
The object manager instance this table controller is associated with.
This instance is used for creating object loaders when loading Network
tables and provides the managed object store used for Core Data tables.
Online/offline state is also determined by watching for reachability
notifications generated from the object manager.
**Default**: The shared manager instance `[RKObjectManager sharedManager]`
*/
@property (nonatomic, assign) RKObjectManager *objectManager;
@property (nonatomic, assign) BOOL autoRefreshFromNetwork;
@property (nonatomic, assign) NSTimeInterval autoRefreshRate;
– (void)loadTableWithObjectLoader:(RKObjectLoader *)objectLoader;
– (void)cancelLoad;
– (BOOL)isAutoRefreshNeeded;
///—————————————————————————–
/// @name Inspecting Table State
///—————————————————————————–
/**
The current state of the table controller. Note that the controller may be in more
than one state (e.g. loading | empty).
*/
@property (nonatomic, readonly, assign) RKTableControllerState state;
/**
An error object that was encountered as the result of an attempt to load
the table. Will return a value when the table is in the error state,
otherwise nil.
*/
@property (nonatomic, readonly, retain) NSError *error;
/**
Returns a Boolean value indicating if the table controller is currently
loading content.
*/
– (BOOL)isLoading;
/**
Returns a Boolean value indicating if the table controller has attempted
a load and transitioned into any state.
*/
– (BOOL)isLoaded;
/**
Returns a Boolean value indicating if the table controller has loaded an
empty set of content.
When YES and there is not an empty item configured, the table controller
will optionally display an empty image overlayed on top of the table view.
**NOTE**: It is possible for an empty table controller to display cells
witin the managed table view in the event an empty item or header/footer
rows are configured.
@see imageForEmpty
*/
– (BOOL)isEmpty;
/**
Returns a Boolean value indicating if the table controller is online
and network operations may be performed.
*/
– (BOOL)isOnline;
/**
Returns a Boolean value indicating if the table controller is offline.
When YES, the table controller will optionally display an offline image
overlayed on top of the table view.
@see imageForOffline
*/
– (BOOL)isOffline;
/**
Returns a Boolean value indicating if the table controller encountered
an error while attempting to load.
When YES, the table controller will optionally display an error image
overlayed on top of the table view.
@see imageForError
*/
– (BOOL)isError;
///—————————————————————————–
/// @name Model State Views
///—————————————————————————–
/**
An image to overlay onto the table when the table view
does not have any row data to display. It will be centered
within the table view.
*/
@property (nonatomic, retain) UIImage *imageForEmpty;
/**
An image to overlay onto the table when a load operation
has encountered an error. It will be centered
within the table view.
*/
@property (nonatomic, retain) UIImage *imageForError;
/**
An image to overlay onto the table with when the user does
not have connectivity to the Internet.
@see RKReachabilityObserver
*/
@property (nonatomic, retain) UIImage *imageForOffline;
/**
A UIView to add to the table overlay during loading. It
will be positioned directly in the center of the table view.
The loading view is always presented non-modally.
*/
@property (nonatomic, retain) UIView *loadingView;
/**
Returns the image, if any, configured for display when the table controller
is in the given state.
**NOTE** This method accepts a single state value.
@param state The table controller state
@return The image for the specified state, else nil. Always returns nil for
RKTableControllerStateNormal, RKTableControllerStateLoading and RKTableControllerStateLoading.
*/
– (UIImage *)imageForState:(RKTableControllerState)state;
/**
A rectangle configuring the dimensions for the overlay view that is
applied to the table view during display of the loading view and
state overlay images (offline/error/empty). By default, the overlay
view will be auto-sized to cover the entire table. This can result in
an inaccessible table UI if you have embedded controls within the header
or footer views of your table. You can adjust the frame of the overlay
precisely by configuring the overlayFrame property.
*/
@property (nonatomic, assign) CGRect overlayFrame;
/**
The image currently displayed within the overlay view.
*/
@property (nonatomic, readonly) UIImage *overlayImage;
/**
When YES, the image view added to the table overlay for displaying table
state (i.e. for offline, error and empty) will be displayed modally
and prevent any interaction with the table.
**Default**: YES
*/
@property (nonatomic, assign) BOOL showsOverlayImagesModally;
// Default NO
@property (nonatomic, assign) BOOL variableHeightRows;
@property (nonatomic, assign) BOOL showsHeaderRowsWhenEmpty;
@property (nonatomic, assign) BOOL showsFooterRowsWhenEmpty;
@property (nonatomic, retain) RKTableItem *emptyItem;
///—————————————————————————–
/// @name Managing Sections
///—————————————————————————–
/**
The number of sections in the table.
*/
@property (nonatomic, readonly) NSUInteger sectionCount;
/**
The number of rows across all sections in the model.
*/
@property (nonatomic, readonly) NSUInteger rowCount;
/**
Returns the number of rows in the section at the given index.
@param index The index of the section to return the row count for.
@returns The number of rows contained within the section with the given index.
@raises NSInvalidArgumentException Raised if index is greater than or
equal to the total number of sections in the table.
*/
– (NSUInteger)numberOfRowsInSection:(NSUInteger)index;
/**
Returns the UITableViewCell created by applying the specified
mapping operation to the object identified by indexPath.
@param indexPath The indexPath in the tableView for which a cell is needed.
*/
– (UITableViewCell *)cellForObjectAtIndexPath:(NSIndexPath *)indexPath;
///—————————————————————————–
/// @name Managing Swipe View
///—————————————————————————–
@property (nonatomic, assign) BOOL cellSwipeViewsEnabled;
@property (nonatomic, retain) UIView *cellSwipeView;
@property (nonatomic, readonly) UITableViewCell *swipeCell;
@property (nonatomic, readonly) id swipeObject;
@property (nonatomic, readonly) BOOL animatingCellSwipe;
@property (nonatomic, readonly) UISwipeGestureRecognizerDirection swipeDirection;
– (void)addSwipeViewTo:(UITableViewCell *)cell withObject:(id)object direction:(UISwipeGestureRecognizerDirection)direction;
– (void)removeSwipeView:(BOOL)animated;
@end
@protocol RKAbstractTableControllerDelegate
@optional
// Network
– (void)tableController:(RKAbstractTableController *)tableController willLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader;
– (void)tableController:(RKAbstractTableController *)tableController didLoadTableWithObjectLoader:(RKObjectLoader *)objectLoader;
// Basic States
– (void)tableControllerDidStartLoad:(RKAbstractTableController *)tableController;
/**
Sent when the table view has transitioned out of the loading state regardless of outcome
*/
– (void)tableControllerDidFinishLoad:(RKAbstractTableController *)tableController;
– (void)tableController:(RKAbstractTableController *)tableController didFailLoadWithError:(NSError *)error;
– (void)tableControllerDidCancelLoad:(RKAbstractTableController *)tableController;
/**
Sent to the delegate when the controller is really and truly finished loading/updating, whether from the network or from Core Data,
or from static data, … this happens in didFinishLoading
*/
– (void)tableControllerDidFinalizeLoad:(RKAbstractTableController *)tableController;
/**
Sent to the delegate when the content of the table view has become empty
*/
– (void)tableControllerDidBecomeEmpty:(RKAbstractTableController *)tableController;
/**
Sent to the delegate when the table controller has transitioned from offline to online
*/
– (void)tableControllerDidBecomeOnline:(RKAbstractTableController *)tableController;
/**
Sent to the delegate when the table controller has transitioned from online to offline
*/
– (void)tableControllerDidBecomeOffline:(RKAbstractTableController *)tableController;
// Objects
– (void)tableController:(RKAbstractTableController *)tableController didInsertObject:(id)object atIndexPath:(NSIndexPath *)indexPath;
– (void)tableController:(RKAbstractTableController *)tableController didUpdateObject:(id)object atIndexPath:(NSIndexPath *)indexPath;
– (void)tableController:(RKAbstractTableController *)tableController didDeleteObject:(id)object atIndexPath:(NSIndexPath *)indexPath;
// Editing
– (void)tableController:(RKAbstractTableController *)tableController willBeginEditing:(id)object atIndexPath:(NSIndexPath *)indexPath;
– (void)tableController:(RKAbstractTableController *)tableController didEndEditing:(id)object atIndexPath:(NSIndexPath *)indexPath;
// Swipe Views
– (void)tableController:(RKAbstractTableController *)tableController willAddSwipeView:(UIView *)swipeView toCell:(UITableViewCell *)cell forObject:(id)object;
– (void)tableController:(RKAbstractTableController *)tableController willRemoveSwipeView:(UIView *)swipeView fromCell:(UITableViewCell *)cell forObject:(id)object;
// Cells
– (void)tableController:(RKAbstractTableController *)tableController willDisplayCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath;
– (void)tableController:(RKAbstractTableController *)tableController didSelectCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(NSIndexPath *)indexPath;
@end
#endif // TARGET_OS_IPHONE
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKAbstractTableController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKAbstractTableController.m
//
// RKAbstractTableController.m
// RestKit
//
// Created by Jeff Arena on 8/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKAbstractTableController.h”
#import “RKAbstractTableController_Internals.h”
#import “RKObjectMappingOperation.h”
#import “RKLog.h”
#import “RKErrors.h”
#import “RKReachabilityObserver.h”
#import “UIView+FindFirstResponder.h”
#import “RKRefreshGestureRecognizer.h”
#import “RKTableSection.h”
// Define logging component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
/**
Bounce pixels define how many pixels the cell swipe view is
moved during the bounce animation
*/
#define BOUNCE_PIXELS 5.0
NSString * const RKTableControllerDidStartLoadNotification = @”RKTableControllerDidStartLoadNotification”;
NSString * const RKTableControllerDidFinishLoadNotification = @”RKTableControllerDidFinishLoadNotification”;
NSString * const RKTableControllerDidLoadObjectsNotification = @”RKTableControllerDidLoadObjectsNotification”;
NSString * const RKTableControllerDidLoadEmptyNotification = @”RKTableControllerDidLoadEmptyNotification”;
NSString * const RKTableControllerDidLoadErrorNotification = @”RKTableControllerDidLoadErrorNotification”;
NSString * const RKTableControllerDidBecomeOnline = @”RKTableControllerDidBecomeOnline”;
NSString * const RKTableControllerDidBecomeOffline = @”RKTableControllerDidBecomeOffline”;
static NSString * lastUpdatedDateDictionaryKey = @”lastUpdatedDateDictionaryKey”;
@implementation RKAbstractTableController
@synthesize delegate = _delegate;
@synthesize viewController = _viewController;
@synthesize tableView = _tableView;
@synthesize defaultRowAnimation = _defaultRowAnimation;
@synthesize objectLoader = _objectLoader;
@synthesize objectManager = _objectManager;
@synthesize cellMappings = _cellMappings;
@synthesize autoRefreshFromNetwork = _autoRefreshFromNetwork;
@synthesize autoRefreshRate = _autoRefreshRate;
@synthesize state = _state;
@synthesize error = _error;
@synthesize imageForEmpty = _imageForEmpty;
@synthesize imageForError = _imageForError;
@synthesize imageForOffline = _imageForOffline;
@synthesize loadingView = _loadingView;
@synthesize variableHeightRows = _variableHeightRows;
@synthesize showsHeaderRowsWhenEmpty = _showsHeaderRowsWhenEmpty;
@synthesize showsFooterRowsWhenEmpty = _showsFooterRowsWhenEmpty;
@synthesize pullToRefreshEnabled = _pullToRefreshEnabled;
@synthesize headerItems = _headerItems;
@synthesize footerItems = _footerItems;
@synthesize canEditRows = _canEditRows;
@synthesize canMoveRows = _canMoveRows;
@synthesize autoResizesForKeyboard = _autoResizesForKeyboard;
@synthesize emptyItem = _emptyItem;
@synthesize cellSwipeViewsEnabled = _cellSwipeViewsEnabled;
@synthesize cellSwipeView = _cellSwipeView;
@synthesize swipeCell = _swipeCell;
@synthesize animatingCellSwipe = _animatingCellSwipe;
@synthesize swipeDirection = _swipeDirection;
@synthesize swipeObject = _swipeObject;
@synthesize showsOverlayImagesModally = _modalOverlay;
@synthesize overlayFrame = _overlayFrame;
@synthesize tableOverlayView = _tableOverlayView;
@synthesize stateOverlayImageView = _stateOverlayImageView;
@synthesize cache = _cache;
@synthesize pullToRefreshHeaderView = _pullToRefreshHeaderView;
#pragma mark – Instantiation
+ (id)tableControllerWithTableView:(UITableView *)tableView
forViewController:(UIViewController *)viewController {
return [[[self alloc] initWithTableView:tableView viewController:viewController] autorelease];
}
+ (id)tableControllerForTableViewController:(UITableViewController *)tableViewController {
return [self tableControllerWithTableView:tableViewController.tableView
forViewController:tableViewController];
}
– (id)initWithTableView:(UITableView *)theTableView viewController:(UIViewController *)theViewController {
NSAssert(theTableView, @”Cannot initialize a table view model with a nil tableView”);
NSAssert(theViewController, @”Cannot initialize a table view model with a nil viewController”);
self = [self init];
if (self) {
self.tableView = theTableView;
_viewController = theViewController; // Assign directly to avoid side-effect of overloaded accessor method
self.variableHeightRows = NO;
self.defaultRowAnimation = UITableViewRowAnimationFade;
self.overlayFrame = CGRectZero;
self.showsOverlayImagesModally = YES;
}
return self;
}
– (id)init {
self = [super init];
if (self) {
if ([self isMemberOfClass:[RKAbstractTableController class]]) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”%@ is abstract. Instantiate one its subclasses instead.”,
NSStringFromClass([self class])]
userInfo:nil];
}
self.state = RKTableControllerStateNotYetLoaded;
self.objectManager = [RKObjectManager sharedManager];
_cellMappings = [RKTableViewCellMappings new];
_headerItems = [NSMutableArray new];
_footerItems = [NSMutableArray new];
_showsHeaderRowsWhenEmpty = YES;
_showsFooterRowsWhenEmpty = YES;
// Setup autoRefreshRate to (effectively) never
_autoRefreshFromNetwork = NO;
_autoRefreshRate = NSTimeIntervalSince1970;
// Setup key-value observing
[self addObserver:self
forKeyPath:@”state”
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
[self addObserver:self
forKeyPath:@”error”
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
}
return self;
}
– (void)dealloc {
// Disconnect from the tableView
if (_tableView.delegate == self) _tableView.delegate = nil;
if (_tableView.dataSource == self) _tableView.dataSource = nil;
_tableView = nil;
// Remove overlay and pull-to-refresh subviews
[_stateOverlayImageView removeFromSuperview];
[_stateOverlayImageView release];
_stateOverlayImageView = nil;
[_tableOverlayView removeFromSuperview];
[_tableOverlayView release];
_tableOverlayView = nil;
// Remove observers
[self removeObserver:self forKeyPath:@”state”];
[self removeObserver:self forKeyPath:@”error”];
[[NSNotificationCenter defaultCenter] removeObserver:self];
// TODO: WTF? Get UI crashes when enabled…
// [_objectManager.requestQueue abortRequestsWithDelegate:self];
_objectLoader.delegate = nil;
[_objectLoader release];
_objectLoader = nil;
[_cellMappings release];
[_headerItems release];
[_footerItems release];
[_cellSwipeView release];
[_swipeCell release];
[_swipeObject release];
[_emptyItem release];
[super dealloc];
}
– (void)setTableView:(UITableView *)tableView {
NSAssert(tableView, @”Cannot assign a nil tableView to the model”);
_tableView = tableView;
_tableView.delegate = self;
_tableView.dataSource = self;
}
– (void)setViewController:(UIViewController *)viewController {
if ([viewController isKindOfClass:[UITableViewController class]]) {
self.tableView = [(UITableViewController*)viewController tableView];
}
}
– (void)setObjectManager:(RKObjectManager *)objectManager {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
// Remove observers
if (_objectManager) {
[notificationCenter removeObserver:self
name:RKObjectManagerDidBecomeOfflineNotification
object:_objectManager];
[notificationCenter removeObserver:self
name:RKObjectManagerDidBecomeOnlineNotification
object:_objectManager];
}
_objectManager = objectManager;
if (objectManager) {
// Set observers
[notificationCenter addObserver:self
selector:@selector(objectManagerConnectivityDidChange:)
name:RKObjectManagerDidBecomeOnlineNotification
object:objectManager];
[notificationCenter addObserver:self
selector:@selector(objectManagerConnectivityDidChange:)
name:RKObjectManagerDidBecomeOfflineNotification
object:objectManager];
// Initialize online/offline state (if it is known)
if (objectManager.networkStatus != RKObjectManagerNetworkStatusUnknown) {
if (objectManager.isOnline) {
self.state &= ~RKTableControllerStateOffline;
} else {
self.state |= RKTableControllerStateOffline;
}
}
}
}
– (void)setAutoResizesForKeyboard:(BOOL)autoResizesForKeyboard {
if (_autoResizesForKeyboard != autoResizesForKeyboard) {
_autoResizesForKeyboard = autoResizesForKeyboard;
if (_autoResizesForKeyboard) {
// Register for Keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(resizeTableViewForKeyboard:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(resizeTableViewForKeyboard:)
name:UIKeyboardWillHideNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
}
– (void)setAutoRefreshFromNetwork:(BOOL)autoRefreshFromNetwork {
if (_autoRefreshFromNetwork != autoRefreshFromNetwork) {
_autoRefreshFromNetwork = autoRefreshFromNetwork;
if (_autoRefreshFromNetwork) {
NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent:@”RKAbstractTableControllerCache”];
_cache = [[RKCache alloc] initWithPath:cachePath subDirectories:nil];
} else {
if (_cache) {
[_cache invalidateAll];
[_cache release];
_cache = nil;
}
}
}
}
– (void)setLoading:(BOOL)loading {
if (loading) {
self.state |= RKTableControllerStateLoading;
} else {
self.state &= ~RKTableControllerStateLoading;
}
}
// NOTE: The loaded flag is handled specially. When loaded becomes NO,
// we clear all other flags. In practice this should not happen outside of init.
– (void)setLoaded:(BOOL)loaded {
if (loaded) {
self.state &= ~RKTableControllerStateNotYetLoaded;
} else {
self.state = RKTableControllerStateNotYetLoaded;
}
}
– (void)setEmpty:(BOOL)empty {
if (empty) {
self.state |= RKTableControllerStateEmpty;
} else {
self.state &= ~RKTableControllerStateEmpty;
}
}
– (void)setOffline:(BOOL)offline {
if (offline) {
self.state |= RKTableControllerStateOffline;
} else {
self.state &= ~RKTableControllerStateOffline;
}
}
– (void)setErrorState:(BOOL)error {
if (error) {
self.state |= RKTableControllerStateError;
} else {
self.state &= ~RKTableControllerStateError;
}
}
– (void)objectManagerConnectivityDidChange:(NSNotification *)notification {
RKLogTrace(@”%@ received network status change notification: %@”, self, [notification name]);
[self setOffline:!self.objectManager.isOnline];
}
#pragma mark – Abstract Methods
– (BOOL)isConsideredEmpty {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (NSUInteger)sectionCount {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (NSUInteger)rowCount {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (NSIndexPath *)indexPathForObject:(id)object {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (NSUInteger)numberOfRowsInSection:(NSUInteger)index {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
– (UITableViewCell *)cellForObjectAtIndexPath:(NSIndexPath *)indexPath {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@”You must override %@ in a subclass”, NSStringFromSelector(_cmd)]
userInfo:nil];
}
#pragma mark – Cell Mappings
– (void)mapObjectsWithClass:(Class)objectClass toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping {
// TODO: Should we raise an exception/throw a warning if you are doing class mapping for a type
// that implements a cellMapping instance method? Maybe a class declaration overrides
[_cellMappings setCellMapping:cellMapping forClass:objectClass];
}
– (void)mapObjectsWithClassName:(NSString *)objectClassName toTableCellsWithMapping:(RKTableViewCellMapping *)cellMapping {
[self mapObjectsWithClass:NSClassFromString(objectClassName) toTableCellsWithMapping:cellMapping];
}
– (RKTableViewCellMapping *)cellMappingForObjectAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(indexPath, @”Cannot lookup cell mapping for object with a nil indexPath”);
id object = [self objectForRowAtIndexPath:indexPath];
return [self.cellMappings cellMappingForObject:object];
}
– (UITableViewCell *)cellForObject:(id)object {
NSIndexPath *indexPath = [self indexPathForObject:object];
return indexPath ? [self cellForObjectAtIndexPath:indexPath] : nil;
}
#pragma mark – Header and Footer Rows
– (void)addHeaderRowForItem:(RKTableItem *)tableItem {
[_headerItems addObject:tableItem];
}
– (void)addFooterRowForItem:(RKTableItem *)tableItem {
[_footerItems addObject:tableItem];
}
– (void)addHeaderRowWithMapping:(RKTableViewCellMapping *)cellMapping {
RKTableItem *tableItem = [RKTableItem tableItem];
tableItem.cellMapping = cellMapping;
[self addHeaderRowForItem:tableItem];
}
– (void)addFooterRowWithMapping:(RKTableViewCellMapping *)cellMapping {
RKTableItem *tableItem = [RKTableItem tableItem];
tableItem.cellMapping = cellMapping;
[self addFooterRowForItem:tableItem];
}
– (void)removeAllHeaderRows {
[_headerItems removeAllObjects];
}
– (void)removeAllFooterRows {
[_footerItems removeAllObjects];
}
#pragma mark – UITableViewDataSource methods
– (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:cellForRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
UITableViewCell *cell = [self cellForObjectAtIndexPath:indexPath];
RKLogTrace(@”%@ cellForRowAtIndexPath:%@ = %@”, self, indexPath, cell);
return cell;
}
– (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
[NSException raise:@”Must be implemented in a subclass!” format:@”sectionCount must be implemented with a subclass”];
return 0;
}
#pragma mark – UITableViewDelegate methods
– (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:didSelectRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
RKLogTrace(@”%@: Row at indexPath %@ selected for tableView %@”, self, indexPath, theTableView);
id object = [self objectForRowAtIndexPath:indexPath];
// NOTE: Do NOT use cellForObjectAtIndexPath here. See https://gist.github.com/eafbb641d37bb7137759
UITableViewCell *cell = [theTableView cellForRowAtIndexPath:indexPath];
RKTableViewCellMapping *cellMapping = [_cellMappings cellMappingForObject:object];
// NOTE: Handle deselection first as the onSelectCell processing may result in the tableView
// being reloaded and our instances invalidated
if (cellMapping.deselectsRowOnSelection) {
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if (cellMapping.onSelectCell) {
cellMapping.onSelectCell();
}
if (cellMapping.onSelectCellForObjectAtIndexPath) {
RKLogTrace(@”%@: Invoking onSelectCellForObjectAtIndexPath block with cellMapping %@ for object %@ at indexPath = %@”, self, cell, object, indexPath);
cellMapping.onSelectCellForObjectAtIndexPath(cell, object, indexPath);
}
if ([self.delegate respondsToSelector:@selector(tableController:didSelectCell:forObject:atIndexPath:)]) {
[self.delegate tableController:self didSelectCell:cell forObject:object atIndexPath:indexPath];
}
}
– (void)tableView:(UITableView *)theTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:didSelectRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
cell.hidden = NO;
id mappableObject = [self objectForRowAtIndexPath:indexPath];
RKTableViewCellMapping *cellMapping = [self.cellMappings cellMappingForObject:mappableObject];
if (cellMapping.onCellWillAppearForObjectAtIndexPath) {
cellMapping.onCellWillAppearForObjectAtIndexPath(cell, mappableObject, indexPath);
}
if ([self.delegate respondsToSelector:@selector(tableController:willDisplayCell:forObject:atIndexPath:)]) {
[self.delegate tableController:self willDisplayCell:cell forObject:mappableObject atIndexPath:indexPath];
}
// Informal protocol
// TODO: Needs documentation!!!
SEL willDisplaySelector = @selector(willDisplayInTableViewCell:);
if ([mappableObject respondsToSelector:willDisplaySelector]) {
[mappableObject performSelector:willDisplaySelector withObject:cell];
}
// Handle hiding header/footer rows when empty
if ([self isEmpty]) {
if (! self.showsHeaderRowsWhenEmpty && [_headerItems containsObject:mappableObject]) {
cell.hidden = YES;
}
if (! self.showsFooterRowsWhenEmpty && [_footerItems containsObject:mappableObject]) {
cell.hidden = YES;
}
} else {
if (self.emptyItem && [self.emptyItem isEqual:mappableObject]) {
cell.hidden = YES;
}
}
}
// Variable height support
– (CGFloat)tableView:(UITableView *)theTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.variableHeightRows) {
RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath];
if (cellMapping.heightOfCellForObjectAtIndexPath) {
id object = [self objectForRowAtIndexPath:indexPath];
CGFloat height = cellMapping.heightOfCellForObjectAtIndexPath(object, indexPath);
RKLogTrace(@”Variable row height configured for tableView. Height via block invocation for row at indexPath ‘%@’ = %f”, indexPath, cellMapping.rowHeight);
return height;
} else {
RKLogTrace(@”Variable row height configured for tableView. Height for row at indexPath ‘%@’ = %f”, indexPath, cellMapping.rowHeight);
return cellMapping.rowHeight;
}
}
RKLogTrace(@”Uniform row height configured for tableView. Table view row height = %f”, self.tableView.rowHeight);
return self.tableView.rowHeight;
}
– (void)tableView:(UITableView *)theTableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath];
if (cellMapping.onTapAccessoryButtonForObjectAtIndexPath) {
RKLogTrace(@”Found a block for tableView:accessoryButtonTappedForRowWithIndexPath: Executing…”);
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath];
id object = [self objectForRowAtIndexPath:indexPath];
cellMapping.onTapAccessoryButtonForObjectAtIndexPath(cell, object, indexPath);
}
}
– (NSString *)tableView:(UITableView *)theTableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath];
if (cellMapping.titleForDeleteButtonForObjectAtIndexPath) {
RKLogTrace(@”Found a block for tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: Executing…”);
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath];
id object = [self objectForRowAtIndexPath:indexPath];
return cellMapping.titleForDeleteButtonForObjectAtIndexPath(cell, object, indexPath);
}
return NSLocalizedString(@”Delete”, nil);
}
– (UITableViewCellEditingStyle)tableView:(UITableView *)theTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (_canEditRows) {
RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:indexPath];
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:indexPath];
if (cellMapping.editingStyleForObjectAtIndexPath) {
RKLogTrace(@”Found a block for tableView:editingStyleForRowAtIndexPath: Executing…”);
id object = [self objectForRowAtIndexPath:indexPath];
return cellMapping.editingStyleForObjectAtIndexPath(cell, object, indexPath);
}
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
– (void)tableView:(UITableView *)theTableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.delegate respondsToSelector:@selector(tableController:didEndEditing:atIndexPath:)]) {
id object = [self objectForRowAtIndexPath:indexPath];
[self.delegate tableController:self didEndEditing:object atIndexPath:indexPath];
}
}
– (void)tableView:(UITableView *)theTableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.delegate respondsToSelector:@selector(tableController:willBeginEditing:atIndexPath:)]) {
id object = [self objectForRowAtIndexPath:indexPath];
[self.delegate tableController:self willBeginEditing:object atIndexPath:indexPath];
}
}
– (NSIndexPath *)tableView:(UITableView *)theTableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
if (_canMoveRows) {
RKTableViewCellMapping *cellMapping = [self cellMappingForObjectAtIndexPath:sourceIndexPath];
if (cellMapping.targetIndexPathForMove) {
RKLogTrace(@”Found a block for tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: Executing…”);
UITableViewCell *cell = [self tableView:self.tableView cellForRowAtIndexPath:sourceIndexPath];
id object = [self objectForRowAtIndexPath:sourceIndexPath];
return cellMapping.targetIndexPathForMove(cell, object, sourceIndexPath, proposedDestinationIndexPath);
}
}
return proposedDestinationIndexPath;
}
– (NSIndexPath *)tableView:(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self removeSwipeView:YES];
return indexPath;
}
#pragma mark – Network Table Loading
– (void)cancelLoad {
[self.objectLoader cancel];
}
– (NSDate *)lastUpdatedDate {
if (! self.objectLoader) {
return nil;
}
if (_autoRefreshFromNetwork) {
NSAssert(_cache, @”Found a nil cache when trying to read our last loaded time”);
NSDictionary *lastUpdatedDates = [_cache dictionaryForCacheKey:lastUpdatedDateDictionaryKey];
RKLogTrace(@”Last updated dates dictionary retrieved from tableController cache: %@”, lastUpdatedDates);
if (lastUpdatedDates) {
NSString *absoluteURLString = [self.objectLoader.URL absoluteString];
NSNumber *lastUpdatedTimeIntervalSince1970 = (NSNumber *)[lastUpdatedDates objectForKey:absoluteURLString];
if (absoluteURLString && lastUpdatedTimeIntervalSince1970) {
return [NSDate dateWithTimeIntervalSince1970:[lastUpdatedTimeIntervalSince1970 doubleValue]];
}
}
}
return nil;
}
– (BOOL)isAutoRefreshNeeded {
BOOL isAutoRefreshNeeded = NO;
if (_autoRefreshFromNetwork) {
isAutoRefreshNeeded = YES;
NSDate *lastUpdatedDate = [self lastUpdatedDate];
RKLogTrace(@”Last updated: %@”, lastUpdatedDate);
if (lastUpdatedDate) {
RKLogTrace(@”-timeIntervalSinceNow=%f, autoRefreshRate=%f”,
-[lastUpdatedDate timeIntervalSinceNow], _autoRefreshRate);
isAutoRefreshNeeded = (-[lastUpdatedDate timeIntervalSinceNow] > _autoRefreshRate);
}
}
return isAutoRefreshNeeded;
}
#pragma mark – RKRequestDelegate & RKObjectLoaderDelegate methods
– (void)requestDidStartLoad:(RKRequest *)request {
RKLogTrace(@”tableController %@ started loading.”, self);
[self didStartLoad];
}
– (void)requestDidCancelLoad:(RKRequest *)request {
RKLogTrace(@”tableController %@ cancelled loading.”, self);
self.loading = NO;
if ([self.delegate respondsToSelector:@selector(tableControllerDidCancelLoad:)]) {
[self.delegate tableControllerDidCancelLoad:self];
}
}
– (void)requestDidTimeout:(RKRequest *)request {
RKLogTrace(@”tableController %@ timed out while loading.”, self);
self.loading = NO;
}
– (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
RKLogTrace(@”tableController %@ finished loading.”, self);
// Updated the lastUpdatedDate dictionary using the URL of the request
if (self.autoRefreshFromNetwork) {
NSAssert(_cache, @”Found a nil cache when trying to save our last loaded time”);
NSMutableDictionary *lastUpdatedDates = [[_cache dictionaryForCacheKey:lastUpdatedDateDictionaryKey] mutableCopy];
if (lastUpdatedDates) {
[_cache invalidateEntry:lastUpdatedDateDictionaryKey];
} else {
lastUpdatedDates = [[NSMutableDictionary alloc] init];
}
NSNumber *timeIntervalSince1970 = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
RKLogTrace(@”Setting timeIntervalSince1970=%@ for URL %@”, timeIntervalSince1970, [request.URL absoluteString]);
[lastUpdatedDates setObject:timeIntervalSince1970
forKey:[request.URL absoluteString]];
[_cache writeDictionary:lastUpdatedDates withCacheKey:lastUpdatedDateDictionaryKey];
[lastUpdatedDates release];
}
}
– (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
RKLogError(@”tableController %@ failed network load with error: %@”, self, error);
[self didFailLoadWithError:error];
}
– (void)objectLoaderDidFinishLoading:(RKObjectLoader *)objectLoader {
if ([self.delegate respondsToSelector:@selector(tableController:didLoadTableWithObjectLoader:)]) {
[self.delegate tableController:self didLoadTableWithObjectLoader:objectLoader];
}
[objectLoader reset];
[self didFinishLoad];
}
– (void)didStartLoad {
self.loading = YES;
}
– (void)didFailLoadWithError:(NSError *)error {
self.error = error;
[self didFinishLoad];
}
– (void)didFinishLoad {
self.empty = [self isConsideredEmpty];
self.loading = [self.objectLoader isLoading]; // Mutate loading state after we have adjusted empty
self.loaded = YES;
if (![self isEmpty] && ![self isLoading]) {
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadObjectsNotification object:self];
}
if (self.delegate && [_delegate respondsToSelector:@selector(tableControllerDidFinalizeLoad:)]) {
[self.delegate performSelector:@selector(tableControllerDidFinalizeLoad:) withObject:self];
}
}
#pragma mark – Table Overlay Views
– (UIImage *)imageForState:(RKTableControllerState)state {
switch (state) {
case RKTableControllerStateNormal:
case RKTableControllerStateLoading:
case RKTableControllerStateNotYetLoaded:
break;
case RKTableControllerStateEmpty:
return self.imageForEmpty;
break;
case RKTableControllerStateError:
return self.imageForError;
break;
case RKTableControllerStateOffline:
return self.imageForOffline;
break;
default:
break;
}
return nil;
}
– (UIImage *)overlayImage {
return _stateOverlayImageView.image;
}
// Adds an overlay view above the table
– (void)addToOverlayView:(UIView *)view modally:(BOOL)modally {
if (! _tableOverlayView) {
CGRect overlayFrame = CGRectIsEmpty(self.overlayFrame) ? self.tableView.frame : self.overlayFrame;
_tableOverlayView = [[UIView alloc] initWithFrame:overlayFrame];
_tableOverlayView.autoresizesSubviews = YES;
_tableOverlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
NSInteger tableIndex = [_tableView.superview.subviews indexOfObject:_tableView];
if (tableIndex != NSNotFound) {
[_tableView.superview addSubview:_tableOverlayView];
}
}
// When modal, we enable user interaction to catch & discard events on the overlay and its subviews
_tableOverlayView.userInteractionEnabled = modally;
view.userInteractionEnabled = modally;
if (CGRectIsEmpty(view.frame)) {
view.frame = _tableOverlayView.bounds;
// Center it in the overlay
view.center = _tableOverlayView.center;
}
[_tableOverlayView addSubview:view];
}
– (void)resetOverlayView {
if (_stateOverlayImageView && _stateOverlayImageView.image == nil) {
[_stateOverlayImageView removeFromSuperview];
}
if (_tableOverlayView && _tableOverlayView.subviews.count == 0) {
[_tableOverlayView removeFromSuperview];
[_tableOverlayView release];
_tableOverlayView = nil;
}
}
– (void)addSubviewOverTableView:(UIView *)view {
NSInteger tableIndex = [_tableView.superview.subviews
indexOfObject:_tableView];
if (NSNotFound != tableIndex) {
[_tableView.superview addSubview:view];
}
}
– (BOOL)removeImageFromOverlay:(UIImage *)image {
if (image && _stateOverlayImageView.image == image) {
_stateOverlayImageView.image = nil;
return YES;
}
return NO;
}
– (void)showImageInOverlay:(UIImage *)image {
NSAssert(self.tableView, @”Cannot add an overlay image to a nil tableView”);
if (! _stateOverlayImageView) {
_stateOverlayImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
_stateOverlayImageView.opaque = YES;
_stateOverlayImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
_stateOverlayImageView.contentMode = UIViewContentModeCenter;
}
_stateOverlayImageView.image = image;
[self addToOverlayView:_stateOverlayImageView modally:self.showsOverlayImagesModally];
}
– (void)removeImageOverlay {
_stateOverlayImageView.image = nil;
[_stateOverlayImageView removeFromSuperview];
[self resetOverlayView];
}
– (void)setImageForEmpty:(UIImage *)imageForEmpty {
[imageForEmpty retain];
BOOL imageRemoved = [self removeImageFromOverlay:_imageForEmpty];
[_imageForEmpty release];
_imageForEmpty = imageForEmpty;
if (imageRemoved) [self showImageInOverlay:_imageForEmpty];
}
– (void)setImageForError:(UIImage *)imageForError {
[imageForError retain];
BOOL imageRemoved = [self removeImageFromOverlay:_imageForError];
[_imageForError release];
_imageForError = imageForError;
if (imageRemoved) [self showImageInOverlay:_imageForError];
}
– (void)setImageForOffline:(UIImage *)imageForOffline {
[imageForOffline retain];
BOOL imageRemoved = [self removeImageFromOverlay:_imageForOffline];
[_imageForOffline release];
_imageForOffline = imageForOffline;
if (imageRemoved) [self showImageInOverlay:_imageForOffline];
}
– (void)setLoadingView:(UIView *)loadingView {
[loadingView retain];
BOOL viewRemoved = (_loadingView.superview != nil);
[_loadingView removeFromSuperview];
[self resetOverlayView];
[_loadingView release];
_loadingView = loadingView;
if (viewRemoved) [self addToOverlayView:_loadingView modally:NO];
}
#pragma mark – KVO & Table States
– (BOOL)isLoading {
return (self.state & RKTableControllerStateLoading) != 0;
}
– (BOOL)isLoaded {
return (self.state & RKTableControllerStateNotYetLoaded) == 0;
// return self.state != RKTableControllerStateNotYetLoaded;
}
– (BOOL)isOffline {
return (self.state & RKTableControllerStateOffline) != 0;
}
– (BOOL)isOnline {
return ![self isOffline];
}
– (BOOL)isError {
return (self.state & RKTableControllerStateError) != 0;
}
– (BOOL)isEmpty {
return (self.state & RKTableControllerStateEmpty) != 0;
}
– (void)isLoadingDidChange {
if ([self isLoading]) {
if ([self.delegate respondsToSelector:@selector(tableControllerDidStartLoad:)]) {
[self.delegate tableControllerDidStartLoad:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidStartLoadNotification object:self];
if (self.loadingView) {
[self addToOverlayView:self.loadingView modally:NO];
}
} else {
if ([self.delegate respondsToSelector:@selector(tableControllerDidFinishLoad:)]) {
[self.delegate tableControllerDidFinishLoad:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidFinishLoadNotification object:self];
if (self.loadingView) {
[self.loadingView removeFromSuperview];
[self resetOverlayView];
}
[self resetPullToRefreshRecognizer];
}
// We don’t want any image overlays applied until loading is finished
_stateOverlayImageView.hidden = [self isLoading];
}
– (void)isLoadedDidChange {
if ([self isLoaded]) {
RKLogDebug(@”%@: is now loaded.”, self);
} else {
RKLogDebug(@”%@: is NOT loaded.”, self);
}
}
– (void)isErrorDidChange {
if ([self isError]) {
if ([self.delegate respondsToSelector:@selector(tableController:didFailLoadWithError:)]) {
[self.delegate tableController:self didFailLoadWithError:self.error];
}
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.error forKey:RKErrorNotificationErrorKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadErrorNotification object:self userInfo:userInfo];
}
}
– (void)isEmptyDidChange {
if ([self isEmpty]) {
if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeEmpty:)]) {
[self.delegate tableControllerDidBecomeEmpty:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidLoadEmptyNotification object:self];
}
}
– (void)isOnlineDidChange {
if ([self isOnline]) {
// We just transitioned to online
if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeOnline:)]) {
[self.delegate tableControllerDidBecomeOnline:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidBecomeOnline object:self];
} else {
// We just transitioned to offline
if ([self.delegate respondsToSelector:@selector(tableControllerDidBecomeOffline:)]) {
[self.delegate tableControllerDidBecomeOffline:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:RKTableControllerDidBecomeOffline object:self];
}
}
– (void)updateTableViewForStateChange:(NSDictionary *)change {
RKTableControllerState oldState = [[change valueForKey:NSKeyValueChangeOldKey] integerValue];
RKTableControllerState newState = [[change valueForKey:NSKeyValueChangeNewKey] integerValue];
// Determine state transitions
BOOL loadedChanged = ((oldState ^ newState) & RKTableControllerStateNotYetLoaded);
BOOL emptyChanged = ((oldState ^ newState) & RKTableControllerStateEmpty);
BOOL offlineChanged = ((oldState ^ newState) & RKTableControllerStateOffline);
BOOL loadingChanged = ((oldState ^ newState) & RKTableControllerStateLoading);
BOOL errorChanged = ((oldState ^ newState) & RKTableControllerStateError);
if (loadedChanged) [self isLoadedDidChange];
if (emptyChanged) [self isEmptyDidChange];
if (offlineChanged) [self isOnlineDidChange];
if (errorChanged) [self isErrorDidChange];
if (loadingChanged) [self isLoadingDidChange];
// Clear the image from the overlay
_stateOverlayImageView.image = nil;
// Determine the appropriate overlay image to display (if any)
if (self.state == RKTableControllerStateNormal) {
[self removeImageOverlay];
} else {
if ([self isLoading]) {
// During a load we don’t adjust the overlay
return;
}
// Though the table can be in more than one state, we only
// want to display a single overlay image.
if ([self isOffline] && self.imageForOffline) {
[self showImageInOverlay:self.imageForOffline];
} else if ([self isError] && self.imageForError) {
[self showImageInOverlay:self.imageForError];
} else if ([self isEmpty] && self.imageForEmpty) {
[self showImageInOverlay:self.imageForEmpty];
}
}
// Remove the overlay if no longer in use
[self resetOverlayView];
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@”state”]) {
[self updateTableViewForStateChange:change];
} else if ([keyPath isEqualToString:@”error”]) {
[self setErrorState:(self.error != nil)];
}
}
#pragma mark – Pull to Refresh
– (RKRefreshGestureRecognizer *)pullToRefreshGestureRecognizer {
RKRefreshGestureRecognizer *refreshRecognizer = nil;
for (RKRefreshGestureRecognizer *recognizer in self.tableView.gestureRecognizers) {
if ([recognizer isKindOfClass:[RKRefreshGestureRecognizer class]]) {
refreshRecognizer = recognizer;
break;
}
}
return refreshRecognizer;
}
– (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled {
RKRefreshGestureRecognizer *recognizer = nil;
if (pullToRefreshEnabled) {
recognizer = [[[RKRefreshGestureRecognizer alloc] initWithTarget:self action:@selector(pullToRefreshStateChanged:)] autorelease];
[self.tableView addGestureRecognizer:recognizer];
}
else {
recognizer = [self pullToRefreshGestureRecognizer];
if (recognizer)
[self.tableView removeGestureRecognizer:recognizer];
}
_pullToRefreshEnabled = pullToRefreshEnabled;
}
– (void)pullToRefreshStateChanged:(UIGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateRecognized) {
if ([self pullToRefreshDataSourceIsLoading:gesture])
return;
RKLogDebug(@”%@: pull to refresh triggered from gesture: %@”, self, gesture);
if (self.objectLoader) {
[self.objectLoader reset];
[self.objectLoader send];
}
}
}
– (void)resetPullToRefreshRecognizer {
RKRefreshGestureRecognizer *recognizer = [self pullToRefreshGestureRecognizer];
if (recognizer)
[recognizer setRefreshState:RKRefreshIdle];
}
– (BOOL)pullToRefreshDataSourceIsLoading:(UIGestureRecognizer *)gesture {
// If we have already been loaded and we are loading again, a refresh is taking place…
return [self isLoaded] && [self isLoading] && [self isOnline];
}
– (NSDate *)pullToRefreshDataSourceLastUpdated:(UIGestureRecognizer *)gesture {
NSDate *dataSourceLastUpdated = [self lastUpdatedDate];
return dataSourceLastUpdated ? dataSourceLastUpdated : [NSDate date];
}
#pragma mark – Cell Swipe Menu Methods
– (void)setupSwipeGestureRecognizers {
// Setup a right swipe gesture recognizer
UISwipeGestureRecognizer *rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];
rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.tableView addGestureRecognizer:rightSwipeGestureRecognizer];
[rightSwipeGestureRecognizer release];
// Setup a left swipe gesture recognizer
UISwipeGestureRecognizer *leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];
leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[self.tableView addGestureRecognizer:leftSwipeGestureRecognizer];
[leftSwipeGestureRecognizer release];
}
– (void)removeSwipeGestureRecognizers {
for (UIGestureRecognizer *recognizer in self.tableView.gestureRecognizers) {
if ([recognizer isKindOfClass:[UISwipeGestureRecognizer class]]) {
[self.tableView removeGestureRecognizer:recognizer];
}
}
}
– (void)setCanEditRows:(BOOL)canEditRows {
NSAssert(!_cellSwipeViewsEnabled, @”Table model cannot be made editable when cell swipe menus are enabled”);
_canEditRows = canEditRows;
}
– (void)setCellSwipeViewsEnabled:(BOOL)cellSwipeViewsEnabled {
NSAssert(!_canEditRows, @”Cell swipe menus cannot be enabled for editable tableModels”);
if (cellSwipeViewsEnabled) {
[self setupSwipeGestureRecognizers];
} else {
[self removeSwipeView:YES];
[self removeSwipeGestureRecognizers];
}
_cellSwipeViewsEnabled = cellSwipeViewsEnabled;
}
– (void)swipe:(UISwipeGestureRecognizer *)recognizer direction:(UISwipeGestureRecognizerDirection)direction {
if (_cellSwipeViewsEnabled && recognizer && recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint location = [recognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
id object = [self objectForRowAtIndexPath:indexPath];
if (cell.frame.origin.x != 0) {
[self removeSwipeView:YES];
return;
}
[self removeSwipeView:NO];
if (cell != _swipeCell && !_animatingCellSwipe) {
[self addSwipeViewTo:cell withObject:object direction:direction];
}
}
}
– (void)swipeLeft:(UISwipeGestureRecognizer *)recognizer {
[self swipe:recognizer direction:UISwipeGestureRecognizerDirectionLeft];
}
– (void)swipeRight:(UISwipeGestureRecognizer *)recognizer {
[self swipe:recognizer direction:UISwipeGestureRecognizerDirectionRight];
}
– (void)addSwipeViewTo:(UITableViewCell *)cell withObject:(id)object direction:(UISwipeGestureRecognizerDirection)direction {
if (_cellSwipeViewsEnabled) {
NSAssert(cell, @”Cannot process swipe view with nil cell”);
NSAssert(object, @”Cannot process swipe view with nil object”);
_cellSwipeView.frame = cell.frame;
if ([self.delegate respondsToSelector:@selector(tableController:willAddSwipeView:toCell:forObject:)]) {
[self.delegate tableController:self
willAddSwipeView:_cellSwipeView
toCell:cell
forObject:object];
}
[self.tableView insertSubview:_cellSwipeView belowSubview:cell];
_swipeCell = [cell retain];
_swipeObject = [object retain];
_swipeDirection = direction;
CGRect cellFrame = cell.frame;
_cellSwipeView.frame = CGRectMake(0, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height);
_animatingCellSwipe = YES;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStopAddingSwipeView:finished:context:)];
cell.frame = CGRectMake(direction == UISwipeGestureRecognizerDirectionRight ? cellFrame.size.width : -cellFrame.size.width, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height);
[UIView commitAnimations];
}
}
– (void)animationDidStopAddingSwipeView:(NSString *)animationID finished:(NSNumber *)finished context:(void*)context {
_animatingCellSwipe = NO;
}
– (void)removeSwipeView:(BOOL)animated {
if (!_cellSwipeViewsEnabled || !_swipeCell || _animatingCellSwipe) {
RKLogTrace(@”Exiting early with _cellSwipeViewsEnabled=%d, _swipCell=%@, _animatingCellSwipe=%d”,
_cellSwipeViewsEnabled, _swipeCell, _animatingCellSwipe);
return;
}
if ([self.delegate respondsToSelector:@selector(tableController:willRemoveSwipeView:fromCell:forObject:)]) {
[self.delegate tableController:self
willRemoveSwipeView:_cellSwipeView
fromCell:_swipeCell
forObject:_swipeObject];
}
if (animated) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) {
_swipeCell.frame = CGRectMake(BOUNCE_PIXELS, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
} else {
_swipeCell.frame = CGRectMake(-BOUNCE_PIXELS, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
}
_animatingCellSwipe = YES;
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStopOne:finished:context:)];
[UIView commitAnimations];
} else {
[_cellSwipeView removeFromSuperview];
_swipeCell.frame = CGRectMake(0,_swipeCell.frame.origin.y,_swipeCell.frame.size.width, _swipeCell.frame.size.height);
[_swipeCell release];
_swipeCell = nil;
}
}
– (void)animationDidStopOne:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) {
_swipeCell.frame = CGRectMake(BOUNCE_PIXELS*2, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
} else {
_swipeCell.frame = CGRectMake(-BOUNCE_PIXELS*2, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
}
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStopTwo:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView commitAnimations];
}
– (void)animationDidStopTwo:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[UIView commitAnimations];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
if (_swipeDirection == UISwipeGestureRecognizerDirectionRight) {
_swipeCell.frame = CGRectMake(0, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
} else {
_swipeCell.frame = CGRectMake(0, _swipeCell.frame.origin.y, _swipeCell.frame.size.width, _swipeCell.frame.size.height);
}
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStopThree:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView commitAnimations];
}
– (void)animationDidStopThree:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
_animatingCellSwipe = NO;
[_swipeCell release];
_swipeCell = nil;
[_cellSwipeView removeFromSuperview];
}
#pragma mark UIScrollViewDelegate methods
– (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self removeSwipeView:YES];
}
– (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
[self removeSwipeView:NO];
return YES;
}
#pragma mark – Keyboard Notification methods
– (void)resizeTableViewForKeyboard:(NSNotification *)notification {
NSAssert(_autoResizesForKeyboard, @”Errantly receiving keyboard notifications while autoResizesForKeyboard=NO”);
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardEndFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat heightForViewShift = keyboardEndFrame.size.height;
RKLogTrace(@”keyboardEndFrame.size.height=%f, heightForViewShift=%f”,
keyboardEndFrame.size.height, heightForViewShift);
CGFloat bottomBarOffset = 0.0;
UINavigationController *navigationController = self.viewController.navigationController;
if (navigationController && navigationController.toolbar && !navigationController.toolbarHidden) {
bottomBarOffset += navigationController.toolbar.frame.size.height;
RKLogTrace(@”Found a visible toolbar. Reducing size of heightForViewShift by=%f”, bottomBarOffset);
}
UITabBarController *tabBarController = self.viewController.tabBarController;
if (tabBarController && tabBarController.tabBar && !self.viewController.hidesBottomBarWhenPushed) {
bottomBarOffset += tabBarController.tabBar.frame.size.height;
RKLogTrace(@”Found a visible tabBar. Reducing size of heightForViewShift by=%f”, bottomBarOffset);
}
if ([[notification name] isEqualToString:UIKeyboardWillShowNotification]) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, (heightForViewShift – bottomBarOffset), 0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
CGRect nonKeyboardRect = self.tableView.frame;
nonKeyboardRect.size.height -= heightForViewShift;
RKLogTrace(@”Searching for a firstResponder not inside our nonKeyboardRect (%f, %f, %f, %f)”,
nonKeyboardRect.origin.x, nonKeyboardRect.origin.y,
nonKeyboardRect.size.width, nonKeyboardRect.size.height);
UIView *firstResponder = [self.tableView findFirstResponder];
if (firstResponder) {
CGRect firstResponderFrame = firstResponder.frame;
RKLogTrace(@”Found firstResponder=%@ at (%f, %f, %f, %f)”, firstResponder,
firstResponderFrame.origin.x, firstResponderFrame.origin.y,
firstResponderFrame.size.width, firstResponderFrame.size.width);
if (![firstResponder.superview isEqual:self.tableView]) {
firstResponderFrame = [firstResponder.superview convertRect:firstResponderFrame toView:self.tableView];
RKLogTrace(@”firstResponder (%@) frame is not in tableView’s coordinate system. Coverted to (%f, %f, %f, %f)”,
firstResponder, firstResponderFrame.origin.x, firstResponderFrame.origin.y,
firstResponderFrame.size.width, firstResponderFrame.size.height);
}
if (!CGRectContainsPoint(nonKeyboardRect, firstResponderFrame.origin)) {
RKLogTrace(@”firstResponder (%@) is underneath keyboard. Beginning scroll of tableView to show”, firstResponder);
[self.tableView scrollRectToVisible:firstResponderFrame animated:YES];
}
}
[UIView commitAnimations];
} else if ([[notification name] isEqualToString:UIKeyboardWillHideNotification]) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
[UIView commitAnimations];
}
}
– (void)loadTableWithObjectLoader:(RKObjectLoader *)theObjectLoader {
NSAssert(theObjectLoader, @”Cannot perform a network load without an object loader”);
if (! [self.objectLoader isEqual:theObjectLoader]) {
if (self.objectLoader) {
RKLogDebug(@”Cancelling in progress table load: asked to load with a new object loader.”);
[self.objectLoader.queue cancelRequest:self.objectLoader];
}
theObjectLoader.delegate = self;
self.objectLoader = theObjectLoader;
}
if ([self.delegate respondsToSelector:@selector(tableController:willLoadTableWithObjectLoader:)]) {
[self.delegate tableController:self willLoadTableWithObjectLoader:self.objectLoader];
}
if (self.objectLoader.queue && ![self.objectLoader.queue containsRequest:self.objectLoader]) {
[self.objectLoader.queue addRequest:self.objectLoader];
}
}
– (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation {
NSIndexPath *indexPath = [self indexPathForObject:object];
if (indexPath) {
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:rowAnimation];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKAbstractTableController.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKAbstractTableController_Internals.h
//
// RKAbstractTableController_Internals.h
// RestKit
//
// Created by Jeff Arena on 8/11/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKRefreshGestureRecognizer.h”
/*
A private continuation class for subclass implementations of RKAbstractTableController
*/
@interface RKAbstractTableController ()
@property (nonatomic, readwrite, assign) UITableView *tableView;
@property (nonatomic, readwrite, assign) UIViewController *viewController;
@property (nonatomic, assign, readwrite) RKTableControllerState state;
@property (nonatomic, readwrite, retain) RKObjectLoader *objectLoader;
@property (nonatomic, readwrite, retain) NSError *error;
@property (nonatomic, readwrite, retain) NSMutableArray *headerItems;
@property (nonatomic, readwrite, retain) NSMutableArray *footerItems;
@property (nonatomic, readonly) UIView *tableOverlayView;
@property (nonatomic, readonly) UIImageView *stateOverlayImageView;
@property (nonatomic, readonly) RKCache *cache;
@property (nonatomic, retain) UIView *pullToRefreshHeaderView;
#pragma mark – Subclass Load Event Hooks
– (void)didStartLoad;
/**
Must be invoked when the table controller has finished loading.
Responsible for finalizing loading, empty, and loaded states
and cleaning up the table overlay view.
*/
– (void)didFinishLoad;
– (void)didFailLoadWithError:(NSError *)error;
#pragma mark – Table View Overlay
– (void)addToOverlayView:(UIView *)view modally:(BOOL)modally;
– (void)resetOverlayView;
– (void)addSubviewOverTableView:(UIView *)view;
– (BOOL)removeImageFromOverlay:(UIImage *)image;
– (void)showImageInOverlay:(UIImage *)image;
– (void)removeImageOverlay;
#pragma mark – Pull to Refresh Private Methods
– (void)pullToRefreshStateChanged:(UIGestureRecognizer *)gesture;
– (void)resetPullToRefreshRecognizer;
/**
Returns a Boolean value indicating if the table controller
should be considered empty and transitioned into the empty state.
Used by the abstract table controller to trigger state transitions.
**NOTE**: This is an abstract method that MUST be implemented with
a subclass.
*/
– (BOOL)isConsideredEmpty;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKAbstractTableController_Internals.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKControlTableItem.h
//
// RKControlTableItem.h
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableItem.h”
// TODO: Add note that any cell class used with an RKControlTableItem
// must have a control property to be auto-linked to the control in the table item
@interface RKControlTableItem : RKTableItem
@property (nonatomic, retain) UIControl *control;
/** @name Convenience Accessors */
@property (nonatomic, readonly) UIButton *button;
@property (nonatomic, readonly) UITextField *textField;
@property (nonatomic, readonly) UISwitch *switchControl;
@property (nonatomic, readonly) UISlider *slider;
@property (nonatomic, readonly) UILabel *label;
+ (id)tableItemWithControl:(UIControl *)control;
/**
Return the value from the control as an object. This will wrap
any primitive values into an appropriate object for use in mapping.
*/
– (id)controlValue;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKControlTableItem.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKControlTableItem.m
//
// RKControlTableItem.m
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKControlTableItem.h”
#import “RKTableViewCellMapping.h”
#import “RKControlTableViewCell.h”
@implementation RKControlTableItem
@synthesize control = _control;
+ (id)tableItemWithControl:(UIControl *)control {
RKControlTableItem *tableItem = [self tableItem];
tableItem.control = control;
return tableItem;
}
– (id)init {
self = [super init];
if (self) {
self.cellMapping.selectionStyle = UITableViewCellSelectionStyleNone;
self.cellMapping.accessoryType = UITableViewCellAccessoryNone;
self.cellMapping.cellClass = [RKControlTableViewCell class];
// Link the UITableViewCell for this table item with the control
[self.cellMapping addPrepareCellBlock:^(UITableViewCell *cell) {
if ([cell respondsToSelector:@selector(setControl:)]) {
[cell setValue:self.control forKey:@”control”];
}
}];
}
return self;
}
– (void)dealloc {
[_control release];
[super dealloc];
}
– (void)setControl:(UIControl *)control {
NSAssert(control, @”Cannot add a nil control to a RKControlTableItem”);
[control retain];
[_control release];
_control = control;
}
#pragma mark – Convenience Accessors
– (UIButton *)button {
return ([self.control isKindOfClass:[UIButton class]]) ? (UIButton *) self.control : nil;
}
– (UITextField *)textField {
return ([self.control isKindOfClass:[UITextField class]]) ? (UITextField *) self.control : nil;
}
– (UISwitch *)switchControl {
return ([self.control isKindOfClass:[UISwitch class]]) ? (UISwitch *) self.control : nil;
}
– (UISlider *)slider {
return ([self.control isKindOfClass:[UISlider class]]) ? (UISlider *) self.control : nil;
}
– (UILabel *)label {
return ([self.control isKindOfClass:[UILabel class]]) ? (UILabel *) self.control : nil;
}
// TODO: What if we replace this with a protocol that enables KVC
// via the ‘controlValue’ property for the common types to allow pluggability?
– (id)controlValue {
if ([self.control isKindOfClass:[UIButton class]]) {
return nil;
} else if ([self.control isKindOfClass:[UITextField class]]) {
return self.textField.text;
} else if ([self.control isKindOfClass:[UISlider class]]) {
return [NSNumber numberWithFloat:self.slider.value];
} else if ([self.control isKindOfClass:[UISwitch class]]) {
return [NSNumber numberWithBool:self.switchControl.isOn];
}
return nil;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKControlTableItem.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKControlTableViewCell.h
//
// RKControlTableViewCell.h
// RestKit
//
// Created by Blake Watters on 8/24/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@interface RKControlTableViewCell : UITableViewCell
@property (nonatomic, retain) UIControl *control;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKControlTableViewCell.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKControlTableViewCell.m
//
// RKControlTableViewCell.m
// RestKit
//
// Created by Blake Watters on 8/24/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKControlTableViewCell.h”
@implementation RKControlTableViewCell
@synthesize control;
– (void)layoutSubviews {
[super layoutSubviews];
if (self.control.superview != self.contentView) {
[self.control removeFromSuperview];
[self.contentView addSubview:self.control];
}
// If the control has not been sized, we assume you want it to
// take up the entire row of space
if (!self.control.frame.size.height) {
[self.control sizeToFit];
CGFloat contentWidth = self.contentView.frame.size.width;
CGFloat contentHeight = self.contentView.frame.size.height;
CGFloat controlHeight = self.control.frame.size.height;
self.control.frame = CGRectMake(8, floor(contentHeight/2 – controlHeight/2),
contentWidth – 8, controlHeight);
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKControlTableViewCell.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKFetchedResultsTableController.h
//
// RKFetchedResultsTableController.h
// RestKit
//
// Created by Blake Watters on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKAbstractTableController.h”
typedef UIView *(^RKFetchedResultsTableViewViewForHeaderInSectionBlock)(NSUInteger sectionIndex, NSString *sectionTitle);
@class RKFetchedResultsTableController;
@protocol RKFetchedResultsTableControllerDelegate
@optional
// Sections
– (void)tableController:(RKFetchedResultsTableController *)tableController didInsertSectionAtIndex:(NSUInteger)sectionIndex;
– (void)tableController:(RKFetchedResultsTableController *)tableController didDeleteSectionAtIndex:(NSUInteger)sectionIndex;
@end
/**
Instances of RKFetchedResultsTableController provide an interface for driving a UITableView
*/
@interface RKFetchedResultsTableController : RKAbstractTableController
@private
NSFetchedResultsController *_fetchedResultsController;
BOOL _showsSectionIndexTitles;
NSArray *_arraySortedFetchedObjects;
BOOL _isEmptyBeforeAnimation;
}
@property (nonatomic, assign) id
@property (nonatomic, retain, readonly) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, copy) NSString *resourcePath;
@property (nonatomic, retain) NSFetchRequest *fetchRequest;
@property (nonatomic, assign) CGFloat heightForHeaderInSection;
@property (nonatomic, copy) RKFetchedResultsTableViewViewForHeaderInSectionBlock onViewForHeaderInSection;
@property (nonatomic, retain) NSPredicate *predicate;
@property (nonatomic, retain) NSArray *sortDescriptors;
@property (nonatomic, copy) NSString *sectionNameKeyPath;
@property (nonatomic, copy) NSString *cacheName;
@property (nonatomic, assign) BOOL showsSectionIndexTitles;
@property (nonatomic, assign) SEL sortSelector;
@property (nonatomic, copy) NSComparator sortComparator;
– (void)setObjectMappingForClass:(Class)objectClass;
– (void)loadTable;
– (void)loadTableFromNetwork;
– (NSIndexPath *)indexPathForObject:(id)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKFetchedResultsTableController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKFetchedResultsTableController.m
//
// RKFetchedResultsTableController.m
// RestKit
//
// Created by Blake Watters on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKFetchedResultsTableController.h”
#import “RKAbstractTableController_Internals.h”
#import “RKManagedObjectStore.h”
#import “NSManagedObject+ActiveRecord.h”
#import “RKObjectMappingOperation.h”
#import “RKManagedObjectMapping.h”
#import “RKLog.h”
#import “RKObjectMappingProvider+CoreData.h”
// Define logging component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
@interface RKFetchedResultsTableController ()
@property (nonatomic, retain, readwrite) NSFetchedResultsController *fetchedResultsController;
– (BOOL)performFetch:(NSError **)error;
– (void)updateSortedArray;
@end
@implementation RKFetchedResultsTableController
@dynamic delegate;
@synthesize fetchedResultsController = _fetchedResultsController;
@synthesize resourcePath = _resourcePath;
@synthesize heightForHeaderInSection = _heightForHeaderInSection;
@synthesize onViewForHeaderInSection = _onViewForHeaderInSection;
@synthesize predicate = _predicate;
@synthesize sortDescriptors = _sortDescriptors;
@synthesize sectionNameKeyPath = _sectionNameKeyPath;
@synthesize cacheName = _cacheName;
@synthesize showsSectionIndexTitles = _showsSectionIndexTitles;
@synthesize sortSelector = _sortSelector;
@synthesize sortComparator = _sortComparator;
@synthesize fetchRequest = _fetchRequest;
– (void)dealloc {
_fetchedResultsController.delegate = nil;
[_fetchedResultsController release];
_fetchedResultsController = nil;
[_resourcePath release];
_resourcePath = nil;
[_predicate release];
_predicate = nil;
[_sortDescriptors release];
_sortDescriptors = nil;
[_sectionNameKeyPath release];
_sectionNameKeyPath = nil;
[_cacheName release];
_cacheName = nil;
[_arraySortedFetchedObjects release];
_arraySortedFetchedObjects = nil;
[_fetchRequest release];
_fetchRequest = nil;
Block_release(_onViewForHeaderInSection);
Block_release(_sortComparator);
[super dealloc];
}
#pragma mark – Helpers
– (BOOL)performFetch:(NSError **)error {
// TODO: We could be doing a KVO on the predicate/sortDescriptors/sectionKeyPath and intelligently deleting the cache
[NSFetchedResultsController deleteCacheWithName:_fetchedResultsController.cacheName];
BOOL success = [_fetchedResultsController performFetch:error];
if (!success) {
RKLogError(@”performFetch failed with error: %@”, [*error localizedDescription]);
return NO;
} else {
RKLogTrace(@”performFetch completed successfully”);
for (NSUInteger index = 0; index < [self sectionCount]; index++) {
if ([self.delegate respondsToSelector:@selector(tableController:didInsertSectionAtIndex:)]) {
[self.delegate tableController:self didInsertSectionAtIndex:index];
}
if ([self.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) {
for (NSUInteger row = 0; row < [self numberOfRowsInSection:index]; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:index];
id object = [self objectForRowAtIndexPath:indexPath];
[self.delegate tableController:self didInsertObject:object atIndexPath:indexPath];
}
}
}
}
return YES;
}
- (void)updateSortedArray {
[_arraySortedFetchedObjects release];
_arraySortedFetchedObjects = nil;
if (_sortSelector || _sortComparator) {
if (_sortSelector) {
_arraySortedFetchedObjects = [[_fetchedResultsController.fetchedObjects sortedArrayUsingSelector:_sortSelector] retain];
} else if (_sortComparator) {
_arraySortedFetchedObjects = [[_fetchedResultsController.fetchedObjects sortedArrayUsingComparator:_sortComparator] retain];
}
NSAssert(_arraySortedFetchedObjects.count == _fetchedResultsController.fetchedObjects.count,
@"sortSelector or sortComparator sort resulted in fewer objects than expected");
}
}
- (BOOL)isHeaderSection:(NSUInteger)section {
return (section == 0);
}
- (BOOL)isHeaderRow:(NSUInteger)row {
BOOL isHeaderRow = NO;
NSUInteger headerItemCount = [self.headerItems count];
if ([self isEmpty] && self.emptyItem) {
isHeaderRow = (row > 0 && row <= headerItemCount);
} else {
isHeaderRow = (row < headerItemCount);
}
return isHeaderRow;
}
- (BOOL)isFooterSection:(NSUInteger)section {
return (section == ([self sectionCount] - 1));
}
- (BOOL)isFooterRow:(NSUInteger)row {
NSUInteger sectionIndex = ([self sectionCount] - 1);
id
NSUInteger nonFooterRowCount = [sectionInfo numberOfObjects];
if (sectionIndex == 0) {
nonFooterRowCount += (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0;
nonFooterRowCount += ([self isEmpty] && self.emptyItem) ? 1 : 0;
}
return (row > (nonFooterRowCount – 1));
}
– (BOOL)isHeaderIndexPath:(NSIndexPath *)indexPath {
return ((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) &&
[self.headerItems count] > 0 &&
[self isHeaderSection:indexPath.section] &&
[self isHeaderRow:indexPath.row]);
}
– (BOOL)isFooterIndexPath:(NSIndexPath *)indexPath {
return ((! [self isEmpty] || self.showsFooterRowsWhenEmpty) &&
[self.footerItems count] > 0 &&
[self isFooterSection:indexPath.section] &&
[self isFooterRow:indexPath.row]);
}
– (BOOL)isEmptySection:(NSUInteger)section {
return (section == 0);
}
– (BOOL)isEmptyRow:(NSUInteger)row {
return (row == 0);
}
– (BOOL)isEmptyItemIndexPath:(NSIndexPath *)indexPath {
return ([self isEmpty] && self.emptyItem &&
[self isEmptySection:indexPath.section] &&
[self isEmptyRow:indexPath.row]);
}
– (NSIndexPath *)emptyItemIndexPath {
return [NSIndexPath indexPathForRow:0 inSection:0];
}
– (NSIndexPath *)fetchedResultsIndexPathForIndexPath:(NSIndexPath *)indexPath {
if (([self isEmpty] && self.emptyItem &&
[self isEmptySection:indexPath.section] &&
! [self isEmptyRow:indexPath.row]) ||
((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) &&
[self.headerItems count] > 0 &&
[self isHeaderSection:indexPath.section] &&
! [self isHeaderRow:indexPath.row])) {
NSUInteger adjustedRowIndex = indexPath.row;
if (![self isEmpty] || self.showsHeaderRowsWhenEmpty) {
adjustedRowIndex -= [self.headerItems count];
}
adjustedRowIndex -= ([self isEmpty] && self.emptyItem) ? 1 : 0;
return [NSIndexPath indexPathForRow:adjustedRowIndex
inSection:indexPath.section];
}
return indexPath;
}
– (NSIndexPath *)indexPathForFetchedResultsIndexPath:(NSIndexPath *)indexPath {
if (([self isEmpty] && self.emptyItem &&
[self isEmptySection:indexPath.section] &&
! [self isEmptyRow:indexPath.row]) ||
((! [self isEmpty] || self.showsHeaderRowsWhenEmpty) &&
[self.headerItems count] > 0 &&
[self isHeaderSection:indexPath.section])) {
NSUInteger adjustedRowIndex = indexPath.row;
if (![self isEmpty] || self.showsHeaderRowsWhenEmpty) {
adjustedRowIndex += [self.headerItems count];
}
adjustedRowIndex += ([self isEmpty] && self.emptyItem) ? 1 : 0;
return [NSIndexPath indexPathForRow:adjustedRowIndex
inSection:indexPath.section];
}
return indexPath;
}
#pragma mark – Public
– (NSFetchRequest *)fetchRequest {
return _fetchRequest ? _fetchRequest : _fetchedResultsController.fetchRequest;
}
– (void)loadTable {
NSFetchRequest *fetchRequest = nil;
if (_resourcePath) {
fetchRequest = [self.objectManager.mappingProvider fetchRequestForResourcePath:self.resourcePath];
} else {
fetchRequest = _fetchRequest;
}
NSAssert(fetchRequest != nil, @”Attempted to load RKFetchedResultsTableController with nil fetchRequest for resourcePath %@, fetchRequest %@”, _resourcePath, _fetchRequest);
if (_predicate) {
[fetchRequest setPredicate:_predicate];
}
if (_sortDescriptors) {
[fetchRequest setSortDescriptors:_sortDescriptors];
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[NSManagedObjectContext contextForCurrentThread]
sectionNameKeyPath:_sectionNameKeyPath
cacheName:_cacheName];
_fetchedResultsController.delegate = self;
// Perform the load
NSError *error;
[self didStartLoad];
BOOL success = [self performFetch:&error];
if (! success) {
[self didFailLoadWithError:error];
}
[self updateSortedArray];
[self.tableView reloadData];
[self didFinishLoad];
if ([self isAutoRefreshNeeded] && [self isOnline] &&
![self.objectLoader isLoading] &&
![self.objectLoader.queue containsRequest:self.objectLoader]) {
[self performSelector:@selector(loadTableFromNetwork) withObject:nil afterDelay:0];
}
}
– (void)setSortSelector:(SEL)sortSelector {
NSAssert(_sectionNameKeyPath == nil, @”Attempted to sort fetchedObjects across multiple sections”);
NSAssert(_sortComparator == nil, @”Attempted to sort fetchedObjects with a sortSelector when a sortComparator already exists”);
_sortSelector = sortSelector;
}
– (void)setSortComparator:(NSComparator)sortComparator {
NSAssert(_sectionNameKeyPath == nil, @”Attempted to sort fetchedObjects across multiple sections”);
NSAssert(_sortSelector == nil, @”Attempted to sort fetchedObjects with a sortComparator when a sortSelector already exists”);
if (_sortComparator) {
Block_release(_sortComparator);
_sortComparator = nil;
}
_sortComparator = Block_copy(sortComparator);
}
– (void)setSectionNameKeyPath:(NSString*)sectionNameKeyPath {
NSAssert(_sortSelector == nil, @”Attempted to create a sectioned fetchedResultsController when a sortSelector is present”);
NSAssert(_sortComparator == nil, @”Attempted to create a sectioned fetchedResultsController when a sortComparator is present”);
[sectionNameKeyPath retain];
[_sectionNameKeyPath release];
_sectionNameKeyPath = sectionNameKeyPath;
}
– (void)setResourcePath:(NSString*)resourcePath {
[_resourcePath release];
_resourcePath = [resourcePath copy];
self.objectLoader = [self.objectManager loaderWithResourcePath:_resourcePath];
self.objectLoader.delegate = self;
}
– (void)setObjectMappingForClass:(Class)objectClass {
NSParameterAssert(objectClass != NULL);
NSAssert(self.objectLoader != NULL, @”Resource path (and thus object loader) must be set before setting object mapping.”);
NSAssert(self.objectManager != NULL, @”Object manager must exist before setting object mapping.”);
self.objectLoader.objectMapping = [self.objectManager.mappingProvider objectMappingForClass:objectClass];
}
#pragma mark – Managing Sections
– (NSUInteger)sectionCount {
return [[_fetchedResultsController sections] count];
}
– (NSUInteger)rowCount {
NSUInteger fetchedItemCount = [[_fetchedResultsController fetchedObjects] count];
NSUInteger nonFetchedItemCount = 0;
if (fetchedItemCount == 0) {
nonFetchedItemCount += self.emptyItem ? 1 : 0;
nonFetchedItemCount += self.showsHeaderRowsWhenEmpty ? [self.headerItems count] : 0;
nonFetchedItemCount += self.showsFooterRowsWhenEmpty ? [self.footerItems count] : 0;
} else {
nonFetchedItemCount += [self.headerItems count];
nonFetchedItemCount += [self.footerItems count];
}
return (fetchedItemCount + nonFetchedItemCount);
}
– (UITableViewCell *)cellForObjectAtIndexPath:(NSIndexPath *)indexPath {
id mappableObject = [self objectForRowAtIndexPath:indexPath];
NSAssert(mappableObject, @”Cannot build a tableView cell without an object”);
RKTableViewCellMapping* cellMapping = [self.cellMappings cellMappingForObject:mappableObject];
NSAssert(cellMapping, @”Cannot build a tableView cell for object %@: No cell mapping defined for objects of type ‘%@'”, mappableObject, NSStringFromClass([mappableObject class]));
UITableViewCell* cell = [cellMapping mappableObjectForData:self.tableView];
NSAssert(cell, @”Cell mapping failed to dequeue or allocate a tableViewCell for object: %@”, mappableObject);
// Map the object state into the cell
RKObjectMappingOperation* mappingOperation = [[RKObjectMappingOperation alloc] initWithSourceObject:mappableObject destinationObject:cell mapping:cellMapping];
NSError* error = nil;
BOOL success = [mappingOperation performMapping:&error];
[mappingOperation release];
// NOTE: If there is no mapping work performed, but no error is generated then
// we consider the operation a success. It is common for table cells to not contain
// any dynamically mappable content (i.e. header/footer rows, banners, etc.)
if (success == NO && error != nil) {
RKLogError(@”Failed to generate table cell for object: %@”, error);
return nil;
}
return cell;
}
– (NSIndexPath *)indexPathForObject:(id)object {
if ([object isKindOfClass:[NSManagedObject class]]) {
return [self indexPathForFetchedResultsIndexPath:[_fetchedResultsController indexPathForObject:object]];
}
return nil;
}
– (UITableViewCell *)cellForObject:(id)object {
return [self cellForObjectAtIndexPath:[self indexPathForObject:object]];
}
#pragma mark – UITableViewDataSource methods
– (NSInteger)numberOfSectionsInTableView:(UITableView*)theTableView {
NSAssert(theTableView == self.tableView, @”numberOfSectionsInTableView: invoked with inappropriate tableView: %@”, theTableView);
RKLogTrace(@”numberOfSectionsInTableView: %d (%@)”, [[_fetchedResultsController sections] count], [[_fetchedResultsController sections] valueForKey:@”name”]);
return [[_fetchedResultsController sections] count];
}
– (NSInteger)tableView:(UITableView*)theTableView numberOfRowsInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”tableView:numberOfRowsInSection: invoked with inappropriate tableView: %@”, theTableView);
RKLogTrace(@”%@ numberOfRowsInSection:%d = %d”, self, section, self.sectionCount);
id
NSUInteger numberOfRows = [sectionInfo numberOfObjects];
if ([self isHeaderSection:section]) {
numberOfRows += (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0;
numberOfRows += ([self isEmpty] && self.emptyItem) ? 1 : 0;
} else if ([self isFooterSection:section]) {
numberOfRows += [self.footerItems count];
}
return numberOfRows;
}
– (NSString*)tableView:(UITableView*)theTableView titleForHeaderInSection:(NSInteger)section {
id
return [sectionInfo name];
}
– (NSString*)tableView:(UITableView*)theTableView titleForFooterInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”tableView:titleForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
return nil;
}
– (NSArray*)sectionIndexTitlesForTableView:(UITableView*)theTableView {
if (theTableView.style == UITableViewStylePlain && self.showsSectionIndexTitles) {
return [_fetchedResultsController sectionIndexTitles];
}
return nil;
}
– (NSInteger)tableView:(UITableView*)theTableView sectionForSectionIndexTitle:(NSString*)title atIndex:(NSInteger)index {
if (theTableView.style == UITableViewStylePlain && self.showsSectionIndexTitles) {
return [_fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}
return 0;
}
– (void)tableView:(UITableView*)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:commitEditingStyle:forRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
if (self.canEditRows && editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject* managedObject = [self objectForRowAtIndexPath:indexPath];
RKObjectMapping* mapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[managedObject class]];
if ([mapping isKindOfClass:[RKManagedObjectMapping class]]) {
RKManagedObjectMapping* managedObjectMapping = (RKManagedObjectMapping*)mapping;
NSString* primaryKeyAttribute = managedObjectMapping.primaryKeyAttribute;
if ([managedObject valueForKeyPath:primaryKeyAttribute]) {
RKLogTrace(@”About to fire a delete request for managedObject: %@”, managedObject);
[[RKObjectManager sharedManager] deleteObject:managedObject delegate:self];
} else {
RKLogTrace(@”About to locally delete managedObject: %@”, managedObject);
[managedObject.managedObjectContext deleteObject:managedObject];
NSError* error = nil;
[managedObject.managedObjectContext save:&error];
if (error) {
RKLogError(@”Failed to save managedObjectContext after a delete with error: %@”, error);
}
}
}
}
}
– (void)tableView:(UITableView*)theTableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destIndexPath {
NSAssert(theTableView == self.tableView, @”tableView:moveRowAtIndexPath:toIndexPath: invoked with inappropriate tableView: %@”, theTableView);
}
– (BOOL)tableView:(UITableView*)theTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:canEditRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
return self.canEditRows && [self isOnline] && !([self isHeaderIndexPath:indexPath] || [self isFooterIndexPath:indexPath] || [self isEmptyItemIndexPath:indexPath]);
}
– (BOOL)tableView:(UITableView*)theTableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:canMoveRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
return self.canMoveRows && !([self isHeaderIndexPath:indexPath] || [self isFooterIndexPath:indexPath] || [self isEmptyItemIndexPath:indexPath]);
}
#pragma mark – UITableViewDelegate methods
– (CGFloat)tableView:(UITableView*)theTableView heightForHeaderInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”heightForHeaderInSection: invoked with inappropriate tableView: %@”, theTableView);
return _heightForHeaderInSection;
}
– (CGFloat)tableView:(UITableView*)theTableView heightForFooterInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”heightForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
return 0;
}
– (UIView*)tableView:(UITableView*)theTableView viewForHeaderInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”viewForHeaderInSection: invoked with inappropriate tableView: %@”, theTableView);
if (_onViewForHeaderInSection) {
NSString* sectionTitle = [self tableView:self.tableView titleForHeaderInSection:section];
if (sectionTitle) {
return _onViewForHeaderInSection(section, sectionTitle);
}
}
return nil;
}
– (UIView*)tableView:(UITableView*)theTableView viewForFooterInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”viewForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
return nil;
}
#pragma mark – Cell Mappings
– (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self isEmptyItemIndexPath:indexPath]) {
return self.emptyItem;
} else if ([self isHeaderIndexPath:indexPath]) {
NSUInteger row = ([self isEmpty] && self.emptyItem) ? (indexPath.row – 1) : indexPath.row;
return [self.headerItems objectAtIndex:row];
} else if ([self isFooterIndexPath:indexPath]) {
id
NSUInteger footerRow = (indexPath.row – sectionInfo.numberOfObjects);
if (indexPath.section == 0) {
footerRow -= (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0;
footerRow -= ([self isEmpty] && self.emptyItem) ? 1 : 0;
}
return [self.footerItems objectAtIndex:footerRow];
} else if (_sortSelector || _sortComparator) {
return [_arraySortedFetchedObjects objectAtIndex:[self fetchedResultsIndexPathForIndexPath:indexPath].row];
}
return [_fetchedResultsController objectAtIndexPath:[self fetchedResultsIndexPathForIndexPath:indexPath]];
}
#pragma mark – Network Table Loading
– (void)loadTableFromNetwork {
NSAssert(self.objectManager, @”Cannot perform a network load without an object manager”);
NSAssert(self.objectLoader, @”Cannot perform a network load when a network load is already in-progress”);
RKLogTrace(@”About to loadTableWithObjectLoader…”);
[self loadTableWithObjectLoader:self.objectLoader];
}
#pragma mark – KVO & Model States
– (BOOL)isConsideredEmpty {
NSUInteger fetchedObjectsCount = [[_fetchedResultsController fetchedObjects] count];
BOOL isEmpty = (fetchedObjectsCount == 0);
RKLogTrace(@”Determined isEmpty = %@. fetchedObjects count = %d”, isEmpty ? @”YES” : @”NO”, fetchedObjectsCount);
return isEmpty;
}
#pragma mark – NSFetchedResultsControllerDelegate methods
– (void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
RKLogTrace(@”Beginning updates for fetchedResultsController (%@). Current section count = %d (resource path: %@)”, controller, [[controller sections] count], _resourcePath);
if (_sortSelector) return;
[self.tableView beginUpdates];
_isEmptyBeforeAnimation = [self isEmpty];
}
– (void)controller:(NSFetchedResultsController*)controller
didChangeSection:(id
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type {
if (_sortSelector) return;
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
if ([self.delegate respondsToSelector:@selector(tableController:didInsertSectionAtIndex:)]) {
[self.delegate tableController:self didInsertSectionAtIndex:sectionIndex];
}
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
if ([self.delegate respondsToSelector:@selector(tableController:didDeleteSectionAtIndex:)]) {
[self.delegate tableController:self didDeleteSectionAtIndex:sectionIndex];
}
break;
default:
RKLogTrace(@”Encountered unexpected section changeType: %d”, type);
break;
}
}
– (void)controller:(NSFetchedResultsController*)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
if (_sortSelector) return;
NSIndexPath* adjIndexPath = [self indexPathForFetchedResultsIndexPath:indexPath];
NSIndexPath* adjNewIndexPath = [self indexPathForFetchedResultsIndexPath:newIndexPath];
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:adjNewIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:adjIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
/**
TODO: Missing a call to a replacement for configureCell:atIndexPath: which updates
the contents of a given cell with the information from a managed object
at a given index path in the fetched results controller
*/
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:adjIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:adjNewIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
default:
RKLogTrace(@”Encountered unexpected object changeType: %d”, type);
break;
}
}
– (void)controllerDidChangeContent:(NSFetchedResultsController*)controller {
RKLogTrace(@”Ending updates for fetchedResultsController (%@). New section count = %d (resource path: %@)”,
controller, [[controller sections] count], _resourcePath);
if (self.emptyItem && ![self isEmpty] && _isEmptyBeforeAnimation) {
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[self emptyItemIndexPath]]
withRowAnimation:UITableViewRowAnimationFade];
}
[self updateSortedArray];
if (_sortSelector) {
[self.tableView reloadData];
} else {
[self.tableView endUpdates];
}
[self didFinishLoad];
}
#pragma mark – UITableViewDataSource methods
– (UITableViewCell *)tableView:(UITableView*)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:cellForRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
UITableViewCell* cell = [self cellForObjectAtIndexPath:indexPath];
RKLogTrace(@”%@ cellForRowAtIndexPath:%@ = %@”, self, indexPath, cell);
return cell;
}
– (NSUInteger)numberOfRowsInSection:(NSUInteger)index {
return [self tableView:self.tableView numberOfRowsInSection:index];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKFetchedResultsTableController.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKForm.h
//
// RKForm.h
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKControlTableItem.h”
typedef enum {
// RKFormControlTypeAutodetect, // TODO: Might be nice to support auto-selection of control type
RKFormControlTypeTextField,
RKFormControlTypeTextFieldSecure,
RKFormControlTypeSwitch,
RKFormControlTypeSlider,
RKFormControlTypeLabel,
RKFormControlTypeUnknown = 1000
} RKFormControlType;
typedef void(^RKFormBlock)();
@class RKTableController;
@class RKFormSection;
@interface RKForm : NSObject {
@private
NSMutableArray *_sections;
NSMutableArray *_observedAttributes;
}
/**
The object we are constructing a form for
*/
@property (nonatomic, readonly) id object;
// The table view we are bound to. not retained.
@property (nonatomic, readonly) RKTableController* tableController;
//@property (nonatomic, assign) id delegate;
@property (nonatomic, copy) RKFormBlock onSubmit;
// delegates…
// formDidSumbit, formWillSubmit, formWillValidate, formDidValidateSuccessfully, formDidFailValidation:withErrors:
+ (id)formForObject:(id)object;
+ (id)formForObject:(id)object usingBlock:(void (^)(RKForm *form))block;
– (id)initWithObject:(id)object;
/** @name Table Item Management */
@property (nonatomic, readonly) NSArray *sections;
@property (nonatomic, readonly) NSArray *tableItems;
– (void)addSection:(RKFormSection *)section;
– (void)addSectionUsingBlock:(void (^)(RKFormSection *section))block;
/** @name Single Section Forms */
/**
Adds a specific table item to the form
*/
– (void)addTableItem:(RKTableItem *)tableItem; // TODO: maybe addRowWithTableItem???
/** @name Key Path to Control Mapping */
// TODO: All of these method signatures should be carefully evaluated…
// TODO: Consider renaming to addControlForAttribute: | addControlTableItemForAttribute:
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType;
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType usingBlock:(void (^)(RKControlTableItem *tableItem))block;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control usingBlock:(void (^)(RKControlTableItem *tableItem))block;
// TODO: Should there be a flavor that accepts UIView* and yields an RKTableItem? This would avoid needing to cast to (UIControl *)
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass usingBlock:(void (^)(RKTableItem *tableItem))block;
– (RKTableItem *)tableItemForAttribute:(NSString *)attributeKeyPath;
– (RKControlTableItem *)controlTableItemForAttribute:(NSString *)attributeKeyPath;
– (UIControl *)controlForAttribute:(NSString *)attributeKeyPath;
/** @name Actions */
// serializes the values back out of the form and into the object…
– (BOOL)commitValuesToObject; // TODO: Better method signature??? mapFormToObject..
/**
Submits the form b
*/
– (void)submit;
/**
Validates the object state as represented in the form. Returns
YES if the object is state if valid.
*/
// TODO: Implement me…
//- (BOOL)validate:(NSArray**)errors;
– (void)willLoadInTableController:(RKTableController *)tableController;
– (void)didLoadInTableController:(RKTableController *)tableController;
// Sent from the form section
– (void)formSection:(RKFormSection *)formSection didAddTableItem:(RKTableItem *)tableItem forAttributeAtKeyPath:(NSString *)attributeKeyPath;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKForm.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKForm.m
//
// RKForm.m
// RestKit
//
// Created by Blake Watters on 8/22/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKForm.h”
#import “RKFormSection.h”
#import “RKTableViewCellMapping.h”
#import “RKTableController.h”
#import “RKObjectMappingOperation.h”
#import “RKLog.h”
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
@interface RKForm (Private)
– (void)removeObserverForAttributes;
@end
@implementation RKForm
@synthesize tableController = _tableController;
@synthesize object = _object;
@synthesize onSubmit = _onSubmit;
+ (id)formForObject:(id)object {
return [[[self alloc] initWithObject:object] autorelease];
}
+ (id)formForObject:(id)object usingBlock:(void (^)(RKForm *))block {
id form = [self formForObject:object];
if (block) block(form);
return form;
}
– (id)initWithObject:(id)object {
if (! object) {
[NSException raise:NSInvalidArgumentException format:@”%@ – cannot initialize a form with a nil object”,
NSStringFromSelector(_cmd)];
}
self = [self init];
if (self) {
_object = [object retain];
if ([_object isKindOfClass:[NSManagedObject class]]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadObjectOnContextDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:[(NSManagedObject *)_object managedObjectContext]];
}
}
return self;
}
– (id)init {
self = [super init];
if (self) {
_sections = [NSMutableArray new];
_observedAttributes = [NSMutableArray new];
}
return self;
}
– (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self removeObserverForAttributes];
_tableController = nil;
[_object release];
[_sections release];
[_observedAttributes release];
Block_release(_onSubmit);
[super dealloc];
}
– (void)addSection:(RKFormSection *)section {
[_sections addObject:section];
}
– (void)addSectionUsingBlock:(void (^)(RKFormSection *section))block {
RKFormSection *section = [RKFormSection sectionInForm:self];
block(section);
[self addSection:section];
}
#pragma mark – Table Item Management
– (NSArray *)sections {
return [NSArray arrayWithArray:_sections];
}
– (RKFormSection *)returnOrInstantiateFirstSection {
if ([_sections count] > 0) {
return [_sections objectAtIndex:0];
}
RKFormSection *section = [RKFormSection sectionInForm:self];
[self addSection:section];
return section;
}
– (NSArray *)tableItems {
NSMutableArray *tableItems = [NSMutableArray array];
for (RKFormSection *section in _sections) {
[tableItems addObjectsFromArray:section.objects];
}
return [NSArray arrayWithArray:tableItems];
}
#pragma mark – Proxies for Section 0
– (void)addTableItem:(RKTableItem *)tableItem {
[[self returnOrInstantiateFirstSection] addTableItem:tableItem];
}
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType usingBlock:(void (^)(RKControlTableItem *tableItem))block {
[[self returnOrInstantiateFirstSection] addRowForAttribute:attributeKeyPath withControlType:controlType usingBlock:block];
}
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType {
[self addRowForAttribute:attributeKeyPath withControlType:controlType usingBlock:nil];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control usingBlock:(void (^)(RKControlTableItem *tableItem))block {
[[self returnOrInstantiateFirstSection] addRowMappingAttribute:attributeKeyPath toKeyPath:controlKeyPath onControl:control usingBlock:block];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control {
[self addRowMappingAttribute:attributeKeyPath toKeyPath:controlKeyPath onControl:control usingBlock:nil];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass usingBlock:(void (^)(RKTableItem *tableItem))block {
[[self returnOrInstantiateFirstSection] addRowMappingAttribute:attributeKeyPath toKeyPath:cellKeyPath onCellWithClass:cellClass usingBlock:block];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass {
[self addRowMappingAttribute:attributeKeyPath toKeyPath:cellKeyPath onCellWithClass:cellClass usingBlock:nil];
}
– (RKTableItem *)tableItemForAttribute:(NSString *)attributeKeyPath {
for (RKTableItem *tableItem in self.tableItems) {
if ([[tableItem.userData valueForKey:@”__RestKit__attributeKeyPath”] isEqualToString:attributeKeyPath]) {
return tableItem;
}
}
return nil;
}
– (RKControlTableItem *)controlTableItemForAttribute:(NSString *)attributeKeyPath {
RKTableItem *tableItem = [self tableItemForAttribute:attributeKeyPath];
return [tableItem isKindOfClass:[RKControlTableItem class]] ? (RKControlTableItem *) tableItem : nil;
}
– (UIControl *)controlForAttribute:(NSString *)attributeKeyPath {
RKControlTableItem *tableItem = [self controlTableItemForAttribute:attributeKeyPath];
return tableItem.control;
}
#pragma mark – Actions
// TODO: This needs thorough unit testing…
/**
TODO: There is an alternate approach for the implementation here. What we may want to do instead of tracking
the mapping like this is use KVO on the control and/or table cells that are tracking attributes and maintain an internal
dictionary of the attribute names -> values currently set on the controls. We would then just fire up the mapping operation
instead of doing this. It may be cleaner…
*/
– (BOOL)commitValuesToObject {
// Serialize the data out of the form
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self.object class]];
NSMutableDictionary *controlValues = [NSMutableDictionary dictionaryWithCapacity:[self.tableItems count]];
for (RKTableItem *tableItem in self.tableItems) {
RKObjectAttributeMapping *controlMapping = [tableItem.userData objectForKey:@”__RestKit__attributeToControlMapping”];
if (controlMapping) {
id controlValue = nil;
NSString *attributeKeyPath = attributeKeyPath = [controlMapping.sourceKeyPath stringByReplacingOccurrencesOfString:@”userData.__RestKit__object.” withString:@””];
NSString *controlValueKeyPath = controlMapping.destinationKeyPath;
// TODO: Another informal protocol. Document me…
if ([tableItem isKindOfClass:[RKControlTableItem class]]) {
// Get the value out of the control and store it on the dictionary
controlValue = [tableItem performSelector:@selector(controlValue)];
if (! controlValue) {
RKLogTrace(@”Unable to directly fetch controlValue from table item. Asking tableItem for valueForKeyPath: %@”, controlValueKeyPath);
controlValue = [tableItem valueForKeyPath:controlValueKeyPath];
}
} else {
// We are not a control cell, so we need to get the value directly from the table cell
UITableViewCell *cell = [self.tableController cellForObject:tableItem];
NSAssert(cell, @”Attempted to serialize value out of nil table cell”);
NSAssert([cell isKindOfClass:[UITableViewCell class]], @”Expected cellForObject to return a UITableViewCell, but got a %@”, NSStringFromClass([cell class]));
RKLogTrace(@”Asking cell %@ for valueForKeyPath:%@”, cell, controlValueKeyPath);
controlValue = [cell valueForKeyPath:controlValueKeyPath];
}
RKLogTrace(@”Extracted form value for attribute ‘%@’: %@”, attributeKeyPath, controlValue);
if (controlValue) {
[controlValues setValue:controlValue forKey:attributeKeyPath];
}
[objectMapping mapAttributes:attributeKeyPath, nil];
} else {
// TODO: Logging!!
}
}
RKLogTrace(@”Object mapping form state into target object ‘%@’ with values: %@”, self.object, controlValues);
objectMapping.performKeyValueValidation = NO; // TODO: Temporary…
RKObjectMappingOperation *operation = [RKObjectMappingOperation mappingOperationFromObject:controlValues toObject:self.object withMapping:objectMapping];
NSError *error = nil;
BOOL success = [operation performMapping:&error];
if (!success) {
RKLogWarning(@”Serialization to the target object failed with error: %@”, error);
}
return success;
}
– (void)submit {
if ([self commitValuesToObject]) {
// TODO: Add validations?
if (self.onSubmit) self.onSubmit();
} else {
// TODO: What to do…
}
}
– (void)validate {
// TODO: Implement me at some point…
}
#pragma mark – Subclass Hooks
– (void)willLoadInTableController:(RKTableController *)tableController {
}
– (void)didLoadInTableController:(RKTableController *)tableController {
_tableController = tableController;
}
#pragma mark – Key Value Observing
– (void)addObserverForAttribute:(NSString *)attributeKeyPath {
if (! [_observedAttributes containsObject:attributeKeyPath]) {
[self.object addObserver:self forKeyPath:attributeKeyPath options:NSKeyValueObservingOptionNew context:nil];
[_observedAttributes addObject:attributeKeyPath];
}
}
– (void)removeObserverForAttribute:(NSString *)attributeKeyPath {
if ([_observedAttributes containsObject:attributeKeyPath]) {
[self.object removeObserver:self forKeyPath:attributeKeyPath];
[_observedAttributes removeObject:attributeKeyPath];
}
}
– (void)removeObserverForAttributes {
for (NSString *keyPath in _observedAttributes) { [self.object removeObserver:self forKeyPath:keyPath]; };
[_observedAttributes removeAllObjects];
}
– (void)formSection:(RKFormSection *)formSection didAddTableItem:(RKTableItem *)tableItem forAttributeAtKeyPath:(NSString *)attributeKeyPath {
[self addObserverForAttribute:attributeKeyPath];
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSAssert(object == self.object, @”Received unexpected KVO message for object that form is not bound to: %@”, object);
RKLogTrace(@”Received KVO message for keyPath (%@) for object (%@)”, keyPath, object);
// TODO: We should use a notification to tell the table view about the attribute change.
// I don’t like that the form knows about the tableController…
// TODO: Need to let you configure the row animations…
RKTableItem *tableItem = [self tableItemForAttribute:keyPath];
[self.tableController reloadRowForObject:tableItem withRowAnimation:UITableViewRowAnimationFade];
}
– (void)reloadObjectOnContextDidSaveNotification:(NSNotification *)notification {
NSManagedObjectContext *context = (NSManagedObjectContext *) notification.object;
NSSet *deletedObjects = [notification.userInfo objectForKey:NSDeletedObjectsKey];
NSSet *updatedObjects = [notification.userInfo objectForKey:NSUpdatedObjectsKey];
if ([deletedObjects containsObject:self.object]) {
RKLogWarning(@”Object was deleted while being display in a RKForm. Interface may no longer function as expected.”);
[self removeObserverForAttributes];
[_object release];
_object = nil;
} else if ([updatedObjects containsObject:self.object]) {
RKLogDebug(@”Object was updated while being displayed in a RKForm. Refreshing…”);
[context refreshObject:_object mergeChanges:YES];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKForm.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKFormSection.h
//
// RKFormSection.h
// RestKit
//
// Created by Blake Watters on 8/23/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableSection.h”
#import “RKForm.h”
@interface RKFormSection : RKTableSection
@property (nonatomic, assign) RKForm *form;
@property (nonatomic, readonly) id object;
+ (id)sectionInForm:(RKForm *)form;
– (id)initWithForm:(RKForm *)form;
– (void)addTableItem:(RKTableItem *)tableItem;
// TODO: We could get rid of the block forms and just pass nil?
// TODO: These should probably be addTableItem for clarity???
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType;
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType usingBlock:(void (^)(RKControlTableItem *tableItem))block;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control usingBlock:(void (^)(RKControlTableItem *tableItem))block;
// Map an attribute to a keyPath on a particular cell class
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass;
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass usingBlock:(void (^)(RKTableItem *tableItem))block;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKFormSection.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKFormSection.m
//
// RKFormSection.m
// RestKit
//
// Created by Blake Watters on 8/23/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKFormSection.h”
@implementation RKFormSection
@synthesize form = _form;
+ (id)sectionInForm:(RKForm *)form {
return [[[self alloc] initWithForm:form] autorelease];
}
– (id)initWithForm:(RKForm *)form {
self = [super init];
if (self) {
self.form = form;
}
return self;
}
– (id)object {
return self.form.object;
}
– (void)addTableItem:(RKTableItem *)tableItem {
// We assume if you haven’t configured any mappings by
// the time the item is added to the section, you probably want the defaults
if ([tableItem.cellMapping.attributeMappings count] == 0) {
[tableItem.cellMapping addDefaultMappings];
}
// TODO: WTF? _objects is declared @protected but using _objects here fails to build…
[(NSMutableArray*)self.objects addObject:tableItem];
}
– (UIControl *)controlWithType:(RKFormControlType)controlType {
UIControl *control = nil;
switch (controlType) {
case RKFormControlTypeTextField:
case RKFormControlTypeTextFieldSecure:;
UITextField *textField = [[[UITextField alloc] init] autorelease];
textField.secureTextEntry = (controlType == RKFormControlTypeTextFieldSecure);
control = (UIControl *) textField;
break;
case RKFormControlTypeSwitch:;
control = [(UIControl *) [UISwitch new] autorelease];
break;
case RKFormControlTypeSlider:;
control = [(UIControl *) [UISlider new] autorelease];
break;
case RKFormControlTypeLabel:;
control = [(UIControl *) [UILabel new] autorelease];
break;
case RKFormControlTypeUnknown:
default:
break;
}
control.backgroundColor = [UIColor clearColor];
return control;
}
– (NSString *)keyPathForControl:(UIControl *)control {
if ([control isKindOfClass:[UITextField class]] ||
[control isKindOfClass:[UILabel class]]) {
return @”text”;
} else if ([control isKindOfClass:[UISwitch class]]) {
return @”on”;
} else if ([control isKindOfClass:[UISlider class]]) {
return @”value”;
} else {
[NSException raise:NSInvalidArgumentException format:@”*** -[%@ %@]: unable to define mapping for control type %@”, NSStringFromClass([self class]), NSStringFromSelector(_cmd), NSStringFromClass([control class])];
}
return nil;
}
– (void)addAttributeMapping:(RKObjectAttributeMapping *)attributeMapping forKeyPath:(NSString *)attributeKeyPath toTableItem:(RKTableItem *)tableItem {
[tableItem.cellMapping addAttributeMapping:attributeMapping];
// Use KVC storage to associate the table item with object being mapped
// TODO: Move these to constants…
[tableItem.userData setValue:self.object forKey:@”__RestKit__object”];
[tableItem.userData setValue:attributeKeyPath forKey:@”__RestKit__attributeKeyPath”];
[tableItem.userData setValue:attributeMapping forKey:@”__RestKit__attributeToControlMapping”];
[self.form formSection:self didAddTableItem:tableItem forAttributeAtKeyPath:attributeKeyPath];
[self addTableItem:tableItem];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control usingBlock:(void (^)(RKControlTableItem *tableItem))block {
RKControlTableItem *tableItem = [RKControlTableItem tableItemWithControl:control];
RKObjectAttributeMapping *attributeMapping = [[RKObjectAttributeMapping new] autorelease];
attributeMapping.sourceKeyPath = [NSString stringWithFormat:@”userData.__RestKit__object.%@”, attributeKeyPath];
attributeMapping.destinationKeyPath = [NSString stringWithFormat:@”control.%@”, controlKeyPath];
[self addAttributeMapping:attributeMapping forKeyPath:attributeKeyPath toTableItem:tableItem];
if (block) block(tableItem);
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)controlKeyPath onControl:(UIControl *)control {
[self addRowMappingAttribute:attributeKeyPath toKeyPath:controlKeyPath onControl:control usingBlock:nil];
}
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType usingBlock:(void (^)(RKControlTableItem *tableItem))block {
id control = [self controlWithType:controlType];
NSString *controlKeyPath = [self keyPathForControl:control];
[self addRowMappingAttribute:attributeKeyPath toKeyPath:controlKeyPath onControl:control usingBlock:block];
}
– (void)addRowForAttribute:(NSString *)attributeKeyPath withControlType:(RKFormControlType)controlType {
[self addRowForAttribute:attributeKeyPath withControlType:controlType usingBlock:nil];
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass usingBlock:(void (^)(RKTableItem *tableItem))block {
RKTableItem *tableItem = [RKTableItem tableItem];
tableItem.cellMapping.cellClass = cellClass;
RKObjectAttributeMapping *attributeMapping = [[RKObjectAttributeMapping new] autorelease];
attributeMapping.sourceKeyPath = [NSString stringWithFormat:@”userData.__RestKit__object.%@”, attributeKeyPath];
attributeMapping.destinationKeyPath = cellKeyPath;
[self addAttributeMapping:attributeMapping forKeyPath:attributeKeyPath toTableItem:tableItem];
if (block) block(tableItem);
}
– (void)addRowMappingAttribute:(NSString *)attributeKeyPath toKeyPath:(NSString *)cellKeyPath onCellWithClass:(Class)cellClass {
[self addRowMappingAttribute:attributeKeyPath toKeyPath:cellKeyPath onCellWithClass:cellClass usingBlock:nil];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKFormSection.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKObjectManager+RKTableController.h
//
// RKObjectManager+RKTableController.h
// RestKit
//
// Created by Blake Watters on 2/23/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectManager.h”
#if TARGET_OS_IPHONE
@class RKTableController, RKFetchedResultsTableController;
/**
Provides extensions to RKObjectManager for instantiating RKTableController instances
*/
@interface RKObjectManager (RKTableController)
/**
Creates and returns a table controller object capable of loading remote object representations
into a UITableView using the RestKit object mapping engine for a given table view controller.
@param tableViewController A UITableViewController to instantiate a table controller for
@return An RKTableController instance ready to drive the table view for the provided tableViewController.
*/
– (RKTableController *)tableControllerForTableViewController:(UITableViewController *)tableViewController;
/**
Creates and returns a table controller object capable of loading remote object representations
into a UITableView using the RestKit object mapping engine for a given table view and view controller.
@param tableView The UITableView object that table controller with acts as the delegate and data source for.
@param viewController The UIViewController that owns the specified tableView.
@return An RKTableController instance ready to drive the table view for the provided tableViewController.
*/
– (RKTableController *)tableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController;
/**
Creates and returns a fetched results table controller object capable of loading remote object representations
stored in Core Data into a UITableView using the RestKit object mapping engine for a given table view controller.
@param tableViewController A UITableViewController to instantiate a table controller for
@return An RKFetchedResultsTableController instance ready to drive the table view for the provided tableViewController.
*/
– (RKFetchedResultsTableController *)fetchedResultsTableControllerForTableViewController:(UITableViewController *)tableViewController;
/**
Creates and returns a table controller object capable of loading remote object representations
stored in Core Data into a UITableView using the RestKit object mapping engine for a given table view and view controller.
@param tableView The UITableView object that table controller with acts as the delegate and data source for.
@param viewController The UIViewController that owns the specified tableView.
@return An RKFetchedResultsTableController instance ready to drive the table view for the provided tableViewController.
*/
– (RKFetchedResultsTableController *)fetchedResultsTableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController;
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKObjectManager+RKTableController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKObjectManager+RKTableController.m
//
// RKObjectManager+RKTableController.m
// RestKit
//
// Created by Blake Watters on 2/23/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “RKObjectManager+RKTableController.h”
#if TARGET_OS_IPHONE
#import “RKTableController.h”
#import “RKFetchedResultsTableController.h”
@implementation RKObjectManager (RKTableController)
– (RKTableController *)tableControllerForTableViewController:(UITableViewController *)tableViewController {
RKTableController *tableController = [RKTableController tableControllerForTableViewController:tableViewController];
tableController.objectManager = self;
return tableController;
}
– (RKTableController *)tableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController {
RKTableController *tableController = [RKTableController tableControllerWithTableView:tableView forViewController:viewController];
tableController.objectManager = self;
return tableController;
}
– (RKFetchedResultsTableController *)fetchedResultsTableControllerForTableViewController:(UITableViewController *)tableViewController {
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:tableViewController];
tableController.objectManager = self;
return tableController;
}
– (RKFetchedResultsTableController *)fetchedResultsTableControllerWithTableView:(UITableView *)tableView forViewController:(UIViewController *)viewController {
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerWithTableView:tableView forViewController:viewController];
return tableController;
}
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKObjectManager+RKTableController.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKRefreshGestureRecognizer.h
// RKRefreshGestureRecognizer.h
// RestKit
//
// Based on PHRefreshTriggerView by Pier-Olivier Thibault
// Adapted by Gregory S. Combs on 1/13/2012
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#import “RKRefreshTriggerView.h”
typedef enum {
RKRefreshIdle = 0,
RKRefreshTriggered,
RKRefreshLoading
} RKRefreshState;
@protocol RKRefreshTriggerProtocol
@optional
– (NSDate*)pullToRefreshDataSourceLastUpdated:(UIGestureRecognizer*)recognizer;
– (BOOL)pullToRefreshDataSourceIsLoading:(UIGestureRecognizer*)recognizer;
@end
@interface RKRefreshGestureRecognizer : UIGestureRecognizer
@property (nonatomic, assign) RKRefreshState refreshState; // You can force a gesture state by modifying this value.
@property (nonatomic, readonly) UIScrollView *scrollView;
@property (nonatomic, readonly, retain) RKRefreshTriggerView *triggerView;
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKRefreshGestureRecognizer.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKRefreshGestureRecognizer.m
// RKRefreshGestureRecognizer.m
// RestKit
//
// Based on PHRefreshTriggerView by Pier-Olivier Thibault
// Adapted by Gregory S. Combs on 1/13/2012
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#import
#import “RKRefreshGestureRecognizer.h”
NSString * const RKRefreshGestureAnimationKey = @”RKRefreshGestureAnimationKey”;
NSString * const RKRefreshResetGestureAnimationKey = @”RKRefreshResetGestureAnimationKey”;
static CGFloat const kFlipArrowAnimationTime = 0.18f;
static CGFloat const kDefaultTriggerViewHeight = 64.f;
@interface RKRefreshGestureRecognizer ()
– (CABasicAnimation *)triggeredAnimation;
– (CABasicAnimation *)idlingAnimation;
@property (nonatomic, retain, readwrite) RKRefreshTriggerView *triggerView;
@property (nonatomic, assign) BOOL isBoundToScrollView;
@property (nonatomic, retain) NSDateFormatter *dateFormatter;
@end
@implementation RKRefreshGestureRecognizer
#pragma mark – Synthesizers
@synthesize triggerView = _triggerView;
@synthesize refreshState = _refreshState;
@synthesize isBoundToScrollView = _isBoundToScrollView;
@synthesize dateFormatter = _dateFormatter;
#pragma mark – Life Cycle
– (id)initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
_triggerView = [[RKRefreshTriggerView alloc] initWithFrame:CGRectZero];
_triggerView.titleLabel.text = NSLocalizedString(@”Pull down to refresh…”, @”Pull down to refresh status”);
_dateFormatter = [[NSDateFormatter alloc] init];
[_dateFormatter setDateStyle:NSDateFormatterShortStyle];
[_dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[self addObserver:self forKeyPath:@”view” options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
– (void)dealloc {
[self removeObserver:self forKeyPath:@”view”];
if (self.triggerView)
[self.triggerView removeFromSuperview];
self.triggerView = nil;
[super dealloc];
}
#pragma mark – Utilities
– (void)refreshLastUpdatedDate {
SEL lastUpdatedSelector = @selector(pullToRefreshDataSourceLastUpdated:);
if (self.scrollView.delegate && [self.scrollView.delegate respondsToSelector:lastUpdatedSelector]) {
NSDate *date = [self.scrollView.delegate performSelector:lastUpdatedSelector withObject:self];
if (!date)
return;
NSString *lastUpdatedText = [NSString stringWithFormat:@”Last Updated: %@”, [self.dateFormatter stringFromDate:date]];
self.triggerView.lastUpdatedLabel.text = lastUpdatedText;
} else {
self.triggerView.lastUpdatedLabel.text = nil;
}
}
– (void)setRefreshState:(RKRefreshState)refreshState {
if (refreshState == _refreshState)
return;
__block UIScrollView *bScrollView = self.scrollView;
switch (refreshState) {
case RKRefreshTriggered: {
if (![self.triggerView.arrowView.layer animationForKey:RKRefreshGestureAnimationKey])
[self.triggerView.arrowView.layer addAnimation:[self triggeredAnimation] forKey:RKRefreshGestureAnimationKey];
self.triggerView.titleLabel.text = NSLocalizedString(@”Release to refresh…”, @”Release to refresh status”);
}
break;
case RKRefreshIdle: {
if (_refreshState == RKRefreshLoading) {
[UIView animateWithDuration:0.2 animations:^{
bScrollView.contentInset = UIEdgeInsetsMake(0,
bScrollView.contentInset.left,
bScrollView.contentInset.bottom,
bScrollView.contentInset.right);
}];
[self.triggerView.arrowView.layer removeAllAnimations];
[self.triggerView.activityView removeFromSuperview];
[self.triggerView.activityView stopAnimating];
[self.triggerView addSubview:self.triggerView.arrowView];
} else if (_refreshState == RKRefreshTriggered) {
if ([self.triggerView.arrowView.layer animationForKey:RKRefreshGestureAnimationKey]) {
[self.triggerView.arrowView.layer addAnimation:[self idlingAnimation] forKey:RKRefreshResetGestureAnimationKey];
}
}
[self refreshLastUpdatedDate];
self.triggerView.titleLabel.text = NSLocalizedString(@”Pull down to refresh…”, @”Pull down to refresh status”);
}
break;
case RKRefreshLoading: {
[UIView animateWithDuration:0.2 animations:^{
bScrollView.contentInset = UIEdgeInsetsMake(kDefaultTriggerViewHeight,
bScrollView.contentInset.left,
bScrollView.contentInset.bottom,
bScrollView.contentInset.right);
}];
self.triggerView.titleLabel.text = NSLocalizedString(@”Loading…”, @”Loading Status”);
[self.triggerView.arrowView removeFromSuperview];
[self.triggerView addSubview:self.triggerView.activityView];
[self.triggerView.activityView startAnimating];
}
break;
}
_refreshState = refreshState;
}
– (CABasicAnimation *)triggeredAnimation {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@”transform.rotation.z”];
animation.duration = kFlipArrowAnimationTime;
animation.toValue = [NSNumber numberWithDouble:M_PI];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
return animation;
}
– (CABasicAnimation *)idlingAnimation {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@”transform.rotation.z”];
animation.delegate = self;
animation.duration = kFlipArrowAnimationTime;
animation.toValue = [NSNumber numberWithDouble:0];
animation.removedOnCompletion = YES;
return animation;
}
– (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
[self.triggerView.arrowView.layer removeAllAnimations];
}
– (UIScrollView *)scrollView {
return (UIScrollView *)self.view;
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
id obj = [object valueForKeyPath:keyPath];
if (NO == [obj isKindOfClass:[UIScrollView class]]) {
self.isBoundToScrollView = NO;
return;
}
self.isBoundToScrollView = YES;
self.triggerView.frame = CGRectMake(0, -kDefaultTriggerViewHeight, CGRectGetWidth(self.view.frame), kDefaultTriggerViewHeight);
[obj addSubview:self.triggerView];
}
#pragma mark UIGestureRecognizer
– (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer {
return NO;
}
– (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer {
return NO;
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (!self.isBoundToScrollView)
return;
if (self.state < UIGestureRecognizerStateBegan) {
self.state = UIGestureRecognizerStateBegan;
}
if (self.scrollView.contentOffset.y < -kDefaultTriggerViewHeight) {
self.refreshState = RKRefreshTriggered;
self.state = UIGestureRecognizerStateChanged;
} else if (self.state != UIGestureRecognizerStateRecognized) {
self.refreshState = RKRefreshIdle;
self.state = UIGestureRecognizerStateChanged;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (!self.isBoundToScrollView) {
self.state = UIGestureRecognizerStateFailed;
return;
}
if (self.refreshState == RKRefreshTriggered) {
self.refreshState = RKRefreshLoading;
self.state = UIGestureRecognizerStateRecognized;
return;
}
self.state = UIGestureRecognizerStateCancelled;
self.refreshState = RKRefreshIdle;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
self.state = UIGestureRecognizerStateCancelled;
}
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKRefreshGestureRecognizer.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKRefreshTriggerView.h
// RKRefreshTriggerView.h
// RestKit
//
// Based on PHRefreshTriggerView by Pier-Olivier Thibault
// Adapted by Gregory S. Combs on 1/13/2012
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
@interface RKRefreshTriggerView : UIView
@property (nonatomic, retain) UILabel *titleLabel;
@property (nonatomic, retain) UILabel *lastUpdatedLabel;
@property (nonatomic, retain) UIImageView *arrowView;
@property (nonatomic, retain) UIActivityIndicatorView *activityView;
#ifdef UI_APPEARANCE_SELECTOR
@property (nonatomic,assign) UIImage *arrowImage UI_APPEARANCE_SELECTOR;
@property (nonatomic,assign) UIActivityIndicatorViewStyle activityIndicatorStyle UI_APPEARANCE_SELECTOR;
@property (nonatomic,assign) UIFont *titleFont UI_APPEARANCE_SELECTOR;
@property (nonatomic,assign) UIColor *titleColor UI_APPEARANCE_SELECTOR;
@property (nonatomic,assign) UIFont *lastUpdatedFont UI_APPEARANCE_SELECTOR;
@property (nonatomic,assign) UIColor *lastUpdatedColor UI_APPEARANCE_SELECTOR;
@property (nonatomic,retain) UIColor *refreshBackgroundColor UI_APPEARANCE_SELECTOR;
#endif
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKRefreshTriggerView.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKRefreshTriggerView.m
// RKRefreshTriggerView.h
// RestKit
//
// Based on PHRefreshTriggerView by Pier-Olivier Thibault
// Adapted by Gregory S. Combs on 1/13/2012
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// TODO: Figure out how to automatically install RestKitResources.bundle and use that bundle path for arrow images
#import “RKRefreshTriggerView.h”
#if TARGET_OS_IPHONE
#define DEFAULT_REFRESH_TITLE_FONT [UIFont boldSystemFontOfSize:13.0f]
#define DEFAULT_REFRESH_TITLE_COLOR [UIColor darkGrayColor]
#define DEFAULT_REFRESH_UPDATED_FONT [UIFont systemFontOfSize:12.0f]
#define DEFAULT_REFRESH_UPDATED_COLOR [UIColor lightGrayColor]
#define DEFAULT_REFRESH_ARROW_IMAGE [UIImage imageNamed:@”blueArrow”]
#define DEFAULT_REFRESH_ACTIVITY_STYLE UIActivityIndicatorViewStyleWhite
@interface RKRefreshTriggerView ()
@end
@implementation RKRefreshTriggerView
@synthesize titleLabel = _titleLabel;
@synthesize activityView = _activityView;
@synthesize arrowView = _arrowView;
@synthesize lastUpdatedLabel = _lastUpdatedLabel;
– (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = [UIColor clearColor];
_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_titleLabel.textAlignment = UITextAlignmentCenter;
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.font = DEFAULT_REFRESH_TITLE_FONT;
_titleLabel.textColor = DEFAULT_REFRESH_TITLE_COLOR;
[self addSubview:_titleLabel];
_lastUpdatedLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_lastUpdatedLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_lastUpdatedLabel.backgroundColor = [UIColor clearColor];
_lastUpdatedLabel.textAlignment = UITextAlignmentCenter;
_lastUpdatedLabel.font = DEFAULT_REFRESH_UPDATED_FONT;
_lastUpdatedLabel.textColor = DEFAULT_REFRESH_UPDATED_COLOR;
[self addSubview:_lastUpdatedLabel];
_arrowView = [[UIImageView alloc] initWithImage:DEFAULT_REFRESH_ARROW_IMAGE];
_arrowView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
[self addSubview:_arrowView];
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:DEFAULT_REFRESH_ACTIVITY_STYLE];
_activityView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
}
return self;
}
– (void)dealloc {
self.titleLabel = nil;
self.arrowView = nil;
self.activityView = nil;
self.lastUpdatedLabel = nil;
[super dealloc];
}
– (void)layoutSubviews {
CGPoint imageCenter = CGPointMake(30, CGRectGetMidY(self.bounds));
self.arrowView.center = imageCenter;
self.arrowView.frame = CGRectIntegral(self.arrowView.frame);
self.activityView.center = imageCenter;
self.titleLabel.frame = CGRectIntegral(CGRectMake(0.0f, ( CGRectGetHeight(self.bounds) * .25f ), CGRectGetWidth(self.bounds), 20.0f));
self.lastUpdatedLabel.frame = CGRectOffset(self.titleLabel.frame, 0.f, 18.f );
}
#ifdef UI_APPEARANCE_SELECTOR
#pragma mark – Proxy Accessors for UIAppearance
– (UIImage *)arrowImage {
if (!self.arrowView)
return DEFAULT_REFRESH_ARROW_IMAGE;
return _arrowView.image;
}
– (void)setArrowImage:(UIImage *)image {
if (!self.arrowView)
return;
self.arrowView.image = image;
}
– (UIActivityIndicatorViewStyle)activityIndicatorStyle {
if (!self.activityView)
return DEFAULT_REFRESH_ACTIVITY_STYLE;
return self.activityView.activityIndicatorViewStyle;
}
– (void)setActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style {
if (!self.activityView)
return;
self.activityView.activityIndicatorViewStyle = style;
}
– (UIFont *)titleFont {
if (!self.titleLabel)
return DEFAULT_REFRESH_TITLE_FONT;
return self.titleLabel.font;
}
– (void)setTitleFont:(UIFont *)font {
if (!self.titleLabel)
return;
self.titleLabel.font = font;
}
– (UIColor *)titleColor {
if (!self.titleLabel)
return DEFAULT_REFRESH_TITLE_COLOR;
return self.titleLabel.textColor;
}
– (void)setTitleColor:(UIColor *)color {
if (!self.titleLabel)
return;
self.titleLabel.textColor = color;
}
– (UIFont *)lastUpdatedFont {
if (!self.lastUpdatedLabel)
return DEFAULT_REFRESH_UPDATED_FONT;
return self.lastUpdatedLabel.font;
}
– (void)setLastUpdatedFont:(UIFont *)font {
if (!self.lastUpdatedLabel)
return;
self.lastUpdatedLabel.font = font;
}
– (UIColor *)lastUpdatedColor {
if (!self.lastUpdatedLabel)
return DEFAULT_REFRESH_UPDATED_COLOR;
return self.lastUpdatedLabel.textColor;
}
– (void)setLastUpdatedColor:(UIColor *)color {
if (!self.lastUpdatedLabel)
return;
self.lastUpdatedLabel.textColor = color;
}
– (UIColor *)refreshBackgroundColor {
return self.backgroundColor;
}
– (void)setRefreshBackgroundColor:(UIColor *)backgroundColor {
[self setBackgroundColor:backgroundColor];
}
#endif
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKRefreshTriggerView.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableController.h
//
// RKTableController.h
// RestKit
//
// Created by Blake Watters on 8/1/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#if TARGET_OS_IPHONE
#import
#import “RKAbstractTableController.h”
#import “RKTableSection.h”
#import “RKTableViewCellMappings.h”
#import “RKTableItem.h”
#import “RKForm.h”
#import “RKObjectManager.h”
#import “RKObjectMapping.h”
#import “RKObjectLoader.h”
@protocol RKTableControllerDelegate
@optional
– (void)tableController:(RKTableController *)tableController didLoadObjects:(NSArray *)objects inSection:(RKTableSection *)section;
@end
@interface RKTableController : RKAbstractTableController
@property (nonatomic, assign) id
///—————————————————————————–
/// @name Static Tables
///—————————————————————————–
– (void)loadObjects:(NSArray *)objects;
– (void)loadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex;
– (void)loadEmpty;
/**
Load an array of RKTableItems into table cells of the specified class. A table cell
mapping will be constructed on your behalf and yielded to the block for configuration.
After the block is invoked, the objects will be loaded into the specified section.
*/
// TODO: Update comments…
– (void)loadTableItems:(NSArray *)tableItems withMapping:(RKTableViewCellMapping *)cellMapping;
– (void)loadTableItems:(NSArray *)tableItems
inSection:(NSUInteger)sectionIndex
withMapping:(RKTableViewCellMapping *)cellMapping;
/**
Load an array of RKTableItem objects into the table using the default
RKTableViewCellMapping. An instance of the cell mapping will be created on your
behalf and configured with the default table view cell attribute mappings.
@param tableItems An array of RKTableItem instances to load into the table
@see RKTableItem
@see [RKTableViewCellMapping addDefaultMappings]
*/
– (void)loadTableItems:(NSArray *)tableItems;
/**
Load an array of RKTableItem objects into the specified section with the table using the default
RKTableViewCellMapping. An instance of the cell mapping will be created on your
behalf and configured with the default table view cell attribute mappings.
@param tableItems An array of RKTableItem instances to load into the table
@param sectionIndex The section to load the table items into. Must be less than sectionCount.
@see RKTableItem
@see [RKTableViewCellMapping addDefaultMappings]
*/
– (void)loadTableItems:(NSArray *)tableItems inSection:(NSUInteger)sectionIndex;
///—————————————————————————–
/** @name Network Tables */
///—————————————————————————–
– (void)loadTableFromResourcePath:(NSString *)resourcePath;
– (void)loadTableFromResourcePath:(NSString *)resourcePath usingBlock:(void (^)(RKObjectLoader *objectLoader))block;
///—————————————————————————–
/** @name Forms */
///—————————————————————————–
/**
The form that the table has been loaded with (if any)
*/
@property (nonatomic, retain, readonly) RKForm *form;
/**
Loads the table with the contents of the specified form object.
Forms are used to build content entry and editing interfaces for objects.
@see RKForm
*/
– (void)loadForm:(RKForm *)form;
///—————————————————————————–
/// @name Managing Sections
///—————————————————————————–
@property (nonatomic, readonly) NSMutableArray *sections;
/**
The key path on the loaded objects used to determine the section they belong to.
*/
@property(nonatomic, copy) NSString *sectionNameKeyPath;
/**
Returns the section at the specified index.
@param index Must be less than the total number of sections.
*/
– (RKTableSection *)sectionAtIndex:(NSUInteger)index;
/**
Returns the first section with the specified header title.
@param title The header title.
*/
– (RKTableSection *)sectionWithHeaderTitle:(NSString *)title;
/**
Returns the index of the specified section.
@param section Must be a valid non nil RKTableViewSection.
@return The index of the given section if contained within the receiver, otherwise NSNotFound.
*/
– (NSUInteger)indexForSection:(RKTableSection *)section;
// Coalesces a series of table view updates performed within the block into
// a single animation using beginUpdates: and endUpdates: on the table view
// TODO: Move to super-class?
– (void)updateTableViewUsingBlock:(void (^)())block;
/** Adds a new section to the model.
* @param section Must be a valid non nil RKTableViewSection. */
// NOTE: connects cellMappings if section.cellMappings is nil…
– (void)addSection:(RKTableSection *)section;
/** Inserts a new section at the specified index.
* @param section Must be a valid non nil RKTableViewSection.
* @param index Must be less than the total number of sections. */
– (void)insertSection:(RKTableSection *)section atIndex:(NSUInteger)index;
/** Removes the specified section from the model.
* @param section The section to remove. */
– (void)removeSection:(RKTableSection *)section;
/** Removes the section at the specified index from the model.
* @param index Must be less than the total number of section. */
– (void)removeSectionAtIndex:(NSUInteger)index;
/** Removes all sections from the model. */
// NOTE: Adds a new section 0
– (void)removeAllSections;
– (void)removeAllSections:(BOOL)recreateFirstSection;
@end
#endif // TARGET_OS_IPHONE
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableController.m
//
// RKTableController.m
// RestKit
//
// Created by Blake Watters on 8/1/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableController.h”
#import “RKAbstractTableController_Internals.h”
#import “RKLog.h”
#import “RKFormSection.h”
#import “NSArray+RKAdditions.h”
#import “RKObjectMappingOperation.h”
// Define logging component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
@interface RKTableController ()
@property (nonatomic, readwrite) NSMutableArray *sections;
@end
@implementation RKTableController
@dynamic delegate;
@synthesize form = _form;
@synthesize sectionNameKeyPath = _sectionNameKeyPath;
@synthesize sections = _sections;
#pragma mark – Instantiation
– (id)init {
self = [super init];
if (self) {
_sections = [NSMutableArray new];
[self addObserver:self
forKeyPath:@”sections”
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
RKTableSection *section = [RKTableSection section];
[self addSection:section];
}
return self;
}
– (void)dealloc {
[self removeObserver:self forKeyPath:@”sections”];
[_form release];
[_sectionNameKeyPath release];
[_sections release];
[super dealloc];
}
#pragma mark – Managing Sections
// KVO-compliant proxy object for section mutations
– (NSMutableArray *)sectionsProxy {
return [self mutableArrayValueForKey:@”sections”];
}
– (void)addSectionsObject:(id)section {
[self.sections addObject:section];
}
– (void)insertSections:(NSArray *)objects atIndexes:(NSIndexSet *)indexes {
[self.sections insertObjects:objects atIndexes:indexes];
}
– (void)removeSectionsAtIndexes:(NSIndexSet *)indexes {
[self.sections removeObjectsAtIndexes:indexes];
}
– (void)replaceSectionsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects {
[self.sections replaceObjectsAtIndexes:indexes withObjects:objects];
}
– (void)addSection:(RKTableSection *)section {
NSAssert(section, @”Cannot insert a nil section”);
section.tableController = self;
if (! section.cellMappings) {
section.cellMappings = self.cellMappings;
}
[[self sectionsProxy] addObject:section];
}
– (void)removeSection:(RKTableSection *)section {
NSAssert(section, @”Cannot remove a nil section”);
if ([self.sections containsObject:section] && self.sectionCount == 1) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:@”Tables must always have at least one section”
userInfo:nil];
}
[[self sectionsProxy] removeObject:section];
}
– (void)insertSection:(RKTableSection *)section atIndex:(NSUInteger)index {
NSAssert(section, @”Cannot insert a nil section”);
section.tableController = self;
[[self sectionsProxy] insertObject:section atIndex:index];
}
– (void)removeSectionAtIndex:(NSUInteger)index {
if (index < self.sectionCount && self.sectionCount == 1) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:@"Tables must always have at least one section"
userInfo:nil];
}
[[self sectionsProxy] removeObjectAtIndex:index];
}
- (void)removeAllSections:(BOOL)recreateFirstSection {
[[self sectionsProxy] removeAllObjects];
if (recreateFirstSection) {
[self addSection:[RKTableSection section]];
}
}
- (void)removeAllSections {
[self removeAllSections:YES];
}
- (void)updateTableViewUsingBlock:(void (^)())block {
[self.tableView beginUpdates];
block();
[self.tableView endUpdates];
}
#pragma mark - Static Tables
- (NSArray*)objectsWithHeaderAndFooters:(NSArray *)objects forSection:(NSUInteger)sectionIndex {
NSMutableArray* mutableObjects = [objects mutableCopy];
if (sectionIndex == 0) {
if ([self.headerItems count] > 0) {
[mutableObjects insertObjects:self.headerItems atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.headerItems.count)]];
}
if (self.emptyItem) {
[mutableObjects insertObject:self.emptyItem atIndex:0];
}
}
if (sectionIndex == (self.sectionCount – 1) && [self.footerItems count] > 0) {
[mutableObjects addObjectsFromArray:self.footerItems];
}
return [mutableObjects autorelease];
}
// NOTE – Everything currently needs to pass through this method to pick up header/footer rows…
– (void)loadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex {
// Clear any existing error state from the table
self.error = nil;
RKTableSection* section = [self sectionAtIndex:sectionIndex];
section.objects = [self objectsWithHeaderAndFooters:objects forSection:sectionIndex];
for (NSUInteger index = 0; index < [section.objects count]; index++) {
if ([self.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) {
[self.delegate tableController:self
didInsertObject:[section objectAtIndex:index]
atIndexPath:[NSIndexPath indexPathForRow:index inSection:sectionIndex]];
}
}
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:self.defaultRowAnimation];
if ([self.delegate respondsToSelector:@selector(tableController:didLoadObjects:inSection:)]) {
[self.delegate tableController:self didLoadObjects:objects inSection:section];
}
// The load is finalized via network callbacks for
// dynamic table controllers
if (nil == self.objectLoader) {
[self didFinishLoad];
}
}
- (void)loadObjects:(NSArray *)objects {
[self loadObjects:objects inSection:0];
}
- (void)loadEmpty {
[self removeAllSections:YES];
[self loadObjects:[NSArray array]];
}
- (void)loadTableItems:(NSArray *)tableItems inSection:(NSUInteger)sectionIndex {
for (RKTableItem *tableItem in tableItems) {
if ([tableItem.cellMapping.attributeMappings count] == 0) {
[tableItem.cellMapping addDefaultMappings];
}
}
[self loadObjects:tableItems inSection:sectionIndex];
}
- (void)loadTableItems:(NSArray *)tableItems
inSection:(NSUInteger)sectionIndex
withMapping:(RKTableViewCellMapping *)cellMapping {
NSAssert(tableItems, @"Cannot load a nil collection of table items");
NSAssert(sectionIndex < self.sectionCount, @"Cannot load table items into a section that does not exist");
NSAssert(cellMapping, @"Cannot load table items without a cell mapping");
for (RKTableItem* tableItem in tableItems) {
tableItem.cellMapping = cellMapping;
}
[self loadTableItems:tableItems inSection:sectionIndex];
}
- (void)loadTableItems:(NSArray *)tableItems withMapping:(RKTableViewCellMapping *)cellMapping {
[self loadTableItems:tableItems inSection:0 withMapping:cellMapping];
}
- (void)loadTableItems:(NSArray *)tableItems {
[self loadTableItems:tableItems inSection:0];
}
#pragma mark - Network Table Loading
- (void)loadTableFromResourcePath:(NSString*)resourcePath {
NSAssert(self.objectManager, @"Cannot perform a network load without an object manager");
[self loadTableWithObjectLoader:[self.objectManager loaderWithResourcePath:resourcePath]];
}
- (void)loadTableFromResourcePath:(NSString *)resourcePath usingBlock:(void (^)(RKObjectLoader *loader))block {
RKObjectLoader* theObjectLoader = [self.objectManager loaderWithResourcePath:resourcePath];
block(theObjectLoader);
[self loadTableWithObjectLoader:theObjectLoader];
}
#pragma mark - Forms
- (void)loadForm:(RKForm *)form {
[form retain];
[_form release];
_form = form;
// The form replaces the content in the table
[self removeAllSections:NO];
[form willLoadInTableController:self];
for (RKFormSection *section in form.sections) {
NSUInteger sectionIndex = [form.sections indexOfObject:section];
section.objects = [self objectsWithHeaderAndFooters:section.objects forSection:sectionIndex];
[self addSection:(RKTableSection *)section];
}
[self didFinishLoad];
[form didLoadInTableController:self];
}
#pragma mark - UITableViewDataSource methods
- (void)tableView:(UITableView*)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @"tableView:commitEditingStyle:forRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView);
if (self.canEditRows) {
if (editingStyle == UITableViewCellEditingStyleDelete) {
RKTableSection* section = [self.sections objectAtIndex:indexPath.section];
[section removeObjectAtIndex:indexPath.row];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// TODO: Anything we need to do here, since we do not have the object to insert?
}
}
}
- (void)tableView:(UITableView*)theTableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destIndexPath {
NSAssert(theTableView == self.tableView, @"tableView:moveRowAtIndexPath:toIndexPath: invoked with inappropriate tableView: %@", theTableView);
if (self.canMoveRows) {
if (sourceIndexPath.section == destIndexPath.section) {
RKTableSection* section = [self.sections objectAtIndex:sourceIndexPath.section];
[section moveObjectAtIndex:sourceIndexPath.row toIndex:destIndexPath.row];
} else {
[self.tableView beginUpdates];
RKTableSection* sourceSection = [self.sections objectAtIndex:sourceIndexPath.section];
id object = [[sourceSection objectAtIndex:sourceIndexPath.row] retain];
[sourceSection removeObjectAtIndex:sourceIndexPath.row];
RKTableSection* destinationSection = nil;
if (destIndexPath.section < [self sectionCount]) {
destinationSection = [self.sections objectAtIndex:destIndexPath.section];
} else {
destinationSection = [RKTableSection section];
[self insertSection:destinationSection atIndex:destIndexPath.section];
}
[destinationSection insertObject:object atIndex:destIndexPath.row];
[object release];
[self.tableView endUpdates];
}
}
}
#pragma mark - RKRequestDelegate & RKObjectLoaderDelegate methods
- (void)objectLoader:(RKObjectLoader *)loader didLoadObjects:(NSArray *)objects {
// TODO: Could not get the KVO to work without a boolean property...
// TODO: Apply any sorting...
if (self.sectionNameKeyPath) {
NSArray *sectionedObjects = [objects sectionsGroupedByKeyPath:self.sectionNameKeyPath];
if ([sectionedObjects count] == 0) {
[self removeAllSections];
}
for (NSArray *sectionOfObjects in sectionedObjects) {
NSUInteger sectionIndex = [sectionedObjects indexOfObject:sectionOfObjects];
if (sectionIndex >= [self sectionCount]) {
[self addSection:[RKTableSection section]];
}
[self loadObjects:sectionOfObjects inSection:sectionIndex];
}
} else {
[self loadObjects:objects inSection:0];
}
}
– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
if ([keyPath isEqualToString:@”sections”]) {
// No table view to inform…
if (! self.tableView) {
return;
}
NSIndexSet *changedSectionIndexes = [change objectForKey:NSKeyValueChangeIndexesKey];
NSAssert(changedSectionIndexes, @”Received a KVO notification for settings property without an NSKeyValueChangeIndexesKey”);
if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeInsertion) {
// Section(s) Inserted
[self.tableView insertSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation];
// TODO: Add observers on the sections objects…
} else if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeRemoval) {
// Section(s) Deleted
[self.tableView deleteSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation];
// TODO: Remove observers on the sections objects…
} else if ([[change objectForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeReplacement) {
// Section(s) Replaced
[self.tableView reloadSections:changedSectionIndexes withRowAnimation:self.defaultRowAnimation];
// TODO: Remove observers on the sections objects…
}
}
// TODO: KVO should be used for managing the row level manipulations on the table view as well…
}
#pragma mark – Managing Sections
– (NSUInteger)sectionCount {
return [_sections count];
}
– (NSUInteger)rowCount {
return [[_sections valueForKeyPath:@”@sum.rowCount”] intValue];
}
– (RKTableSection *)sectionAtIndex:(NSUInteger)index {
return [_sections objectAtIndex:index];
}
– (NSUInteger)indexForSection:(RKTableSection *)section {
NSAssert(section, @”Cannot return index for a nil section”);
return [_sections indexOfObject:section];
}
– (RKTableSection *)sectionWithHeaderTitle:(NSString *)title {
for (RKTableSection* section in _sections) {
if ([section.headerTitle isEqualToString:title]) {
return section;
}
}
return nil;
}
– (NSUInteger)numberOfRowsInSection:(NSUInteger)index {
return [self sectionAtIndex:index].rowCount;
}
– (UITableViewCell *)cellForObjectAtIndexPath:(NSIndexPath *)indexPath {
RKTableSection* section = [self sectionAtIndex:indexPath.section];
id mappableObject = [section objectAtIndex:indexPath.row];
RKTableViewCellMapping* cellMapping = [self.cellMappings cellMappingForObject:mappableObject];
NSAssert(cellMapping, @”Cannot build a tableView cell for object %@: No cell mapping defined for objects of type ‘%@'”, mappableObject, NSStringFromClass([mappableObject class]));
UITableViewCell* cell = [cellMapping mappableObjectForData:self.tableView];
NSAssert(cell, @”Cell mapping failed to dequeue or allocate a tableViewCell for object: %@”, mappableObject);
// Map the object state into the cell
RKObjectMappingOperation* mappingOperation = [[RKObjectMappingOperation alloc] initWithSourceObject:mappableObject destinationObject:cell mapping:cellMapping];
NSError* error = nil;
BOOL success = [mappingOperation performMapping:&error];
[mappingOperation release];
// NOTE: If there is no mapping work performed, but no error is generated then
// we consider the operation a success. It is common for table cells to not contain
// any dynamically mappable content (i.e. header/footer rows, banners, etc.)
if (success == NO && error != nil) {
RKLogError(@”Failed to generate table cell for object: %@”, error);
return nil;
}
return cell;
}
#pragma mark – Cell Mappings
– (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(indexPath, @”Cannot lookup object with a nil indexPath”);
RKTableSection* section = [self sectionAtIndex:indexPath.section];
return [section objectAtIndex:indexPath.row];
}
#pragma mark – UITableViewDataSource methods
– (NSString*)tableView:(UITableView*)theTableView titleForHeaderInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”tableView:titleForHeaderInSection: invoked with inappropriate tableView: %@”, theTableView);
return [[_sections objectAtIndex:section] headerTitle];
}
– (NSString*)tableView:(UITableView*)theTableView titleForFooterInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”tableView:titleForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
return [[_sections objectAtIndex:section] footerTitle];
}
– (BOOL)tableView:(UITableView*)theTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:canEditRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
return self.canEditRows;
}
– (BOOL)tableView:(UITableView*)theTableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(theTableView == self.tableView, @”tableView:canMoveRowAtIndexPath: invoked with inappropriate tableView: %@”, theTableView);
return self.canMoveRows;
}
– (NSInteger)numberOfSectionsInTableView:(UITableView*)theTableView {
NSAssert(theTableView == self.tableView, @”numberOfSectionsInTableView: invoked with inappropriate tableView: %@”, theTableView);
RKLogTrace(@”%@ numberOfSectionsInTableView = %d”, self, self.sectionCount);
return self.sectionCount;
}
– (NSInteger)tableView:(UITableView*)theTableView numberOfRowsInSection:(NSInteger)section {
NSAssert(theTableView == self.tableView, @”tableView:numberOfRowsInSection: invoked with inappropriate tableView: %@”, theTableView);
RKLogTrace(@”%@ numberOfRowsInSection:%d = %d”, self, section, self.sectionCount);
return [[_sections objectAtIndex:section] rowCount];
}
– (NSIndexPath *)indexPathForObject:(id)object {
NSUInteger sectionIndex = 0;
for (RKTableSection *section in self.sections) {
NSUInteger rowIndex = 0;
for (id rowObject in section.objects) {
if ([rowObject isEqual:object]) {
return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
}
rowIndex++;
}
sectionIndex++;
}
return nil;
}
– (CGFloat)tableView:(UITableView *)theTableView heightForHeaderInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”heightForHeaderInSection: invoked with inappropriate tableView: %@”, theTableView);
RKTableSection *section = [self sectionAtIndex:sectionIndex];
return section.headerHeight;
}
– (CGFloat)tableView:(UITableView *)theTableView heightForFooterInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”heightForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
RKTableSection *section = [self sectionAtIndex:sectionIndex];
return section.footerHeight;
}
– (UIView *)tableView:(UITableView *)theTableView viewForHeaderInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”viewForHeaderInSection: invoked with inappropriate tableView: %@”, theTableView);
RKTableSection *section = [self sectionAtIndex:sectionIndex];
return section.headerView;
}
– (UIView *)tableView:(UITableView *)theTableView viewForFooterInSection:(NSInteger)sectionIndex {
NSAssert(theTableView == self.tableView, @”viewForFooterInSection: invoked with inappropriate tableView: %@”, theTableView);
RKTableSection *section = [self sectionAtIndex:sectionIndex];
return section.footerView;
}
– (BOOL)isConsideredEmpty {
NSUInteger nonRowItemsCount = [self.headerItems count] + [self.footerItems count];
nonRowItemsCount += self.emptyItem ? 1 : 0;
BOOL isEmpty = (self.rowCount – nonRowItemsCount) == 0;
RKLogTrace(@”Determined isConsideredEmpty = %@. self.rowCount = %d with %d nonRowItems in the table”, isEmpty ? @”YES” : @”NO”, self.rowCount, nonRowItemsCount);
return isEmpty;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableController.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableItem.h
//
// RKTableItem.h
// RestKit
//
// Created by Blake Watters on 8/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKMutableBlockDictionary.h”
@class RKTableViewCellMapping;
/**
A generic class for defining vanilla table items when
you do not have local domain items for your table rows. This
is used to implement simple static tables quickly.
*/
@interface RKTableItem : NSObject
@property (nonatomic, retain) NSString *text;
@property (nonatomic, retain) NSString *detailText;
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) NSString *URL;
/**
A dictionary reference for storing ad-hoc KVC data useful in building
table items that require extra information beyond the concrete properties
available on the table item.
Values stored within the userData dictionary can be used to map arbitrary data
into your table cells without resorting to subclassing RKTableItem:
[tableItem.userData setValue:userAvatarImage forKey:@”userAvatarImage”];
[tableItem.cellMapping mapKeyPath:@”userData.userAvatarImage” toKeyPath:@”imageView.image”];
Note that this is an instance of RKMutableBlockDictionary — a dictionary capable of
storing executable block values that will be resolved at mapping time.
For convenience, you can also perform key-value coding operations on instances of RKTableItem
themselves. Any undefined KVC operations will be passed through to the underlying
userData property. This permits you to have alignment on your keyPaths between the
table item and your target cells when defining mappings. Considering the above examples,
we could also write the following code instead:
[tableItem setValue:userAvatarImage forKey:@”userAvatarImage”];
[tableItem.cellMapping mapKeyPath:@”userAvatarImage” toKeyPath:@”imageView.image”];
Or more concretely, if we have a group of properties such as title, description, and publishedDate
on our UITableViewCell destination class, we can configure it quickly via:
[tableItem setValue:@”Some Title” forKey:@”title”];
[tableItem setValue:@”This is an awesome movie.” forKey:@”description”];
[tableItem setValue:[NSDate date] forKey:@”publishedDate”];
[tableItem.cellMapping mapAttributes:@”title”, @”description”, @”publishedDate”, nil];
@see RKMutableBlockDictionary
*/
@property (nonatomic, retain) RKMutableBlockDictionary *userData;
/**
Informal protocol implementation. Any object that responds to the `cellMapping` message
and returns an RKTableViewCellMapping will be mapped into a table view cell according to
the rules in the mapping.
Generally table items are mapped using class -> cell mapping semantics. This is configured
via invocation of [RKTableController mapObjectClass:toTableCellClass:]. Default mappings for
RKTableItem instances are configured on your behalf when you invoke the [RKTableView loadTableItems:]
family of methods.
If you assign a cell mapping to an individual table item then the assigned cell mapping will
be used instead of the class configured ‘default’ mapping.
**Default**: nil
*/
@property (nonatomic, retain) RKTableViewCellMapping *cellMapping;
/**
Return a new array of RKTableItem instances given a nil terminated list of strings.
Each table item will have the text property set to the string provided.
*/
+ (NSArray*)tableItemsFromStrings:(NSString *)firstString, … NS_REQUIRES_NIL_TERMINATION;
/**
Returns a new table item
*/
+ (id)tableItem;
/**
Initialize a new table item and yield it to the block for configuration
*/
+ (id)tableItemUsingBlock:(void (^)(RKTableItem *tableItem))block;
/**
Initialize a new table item with the specified text
*/
+ (id)tableItemWithText:(NSString *)text;
/**
Initialize a new table item with the specified text & details text
*/
+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText;
/**
Construct a new auto-released table item with the specified text, detailText and image
properties.
*/
+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText image:(UIImage *)image;
/**
Construct a new table item with the specified text and yield it to the block for configuration.
This is a convenient mechanism for quickly constructing table items that have been subclassed.
For example:
NSArray* tableItems = [NSArray arrayWithObjects:[MyTableItem tableItemWithText:@”Foo”
usingBlock:^(RKTableItem *tableItem) {
[(MyTableItem *)tableItem setURL:@”app://whatever”];
}], …];
*/
+ (id)tableItemWithText:(NSString *)text usingBlock:(void (^)(RKTableItem *tableItem))block;
/**
Constructs a new table item with the specified text and URL. This is useful if you are working
with Three20 or another library that provides URL dispatching.
*/
+ (id)tableItemWithText:(NSString *)text URL:(NSString *)URL;
/**
Construct a new table item with the specified cell mapping
*/
+ (id)tableItemWithCellMapping:(RKTableViewCellMapping *)cellMapping;
/**
Construct a new table item that will map into an instance of the specified
UITableViewCell subclass. This is helpful if you are constructing a static table
with a handful of different cells and don’t need to configure a full cell mapping.
When invoked, an instance of RKTableViewCellMapping will be created on your behalf
and assigned to the cellMapping property. The objectClass of the cellMapping will be
set to the subclass of UITableViewCell you provided.
@param tableViewCellSubclass A subclass of UITableViewCell to map this item into
*/
+ (id)tableItemWithCellClass:(Class)tableViewCellSubclass;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableItem.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableItem.m
//
// RKTableItem.m
// RestKit
//
// Created by Blake Watters on 8/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableItem.h”
#import “RKTableViewCellMapping.h”
@implementation RKTableItem
@synthesize text = _text;
@synthesize detailText = _detailText;
@synthesize image = _image;
@synthesize cellMapping = _cellMapping;
@synthesize URL = _URL;
@synthesize userData = _userData;
+ (NSArray*)tableItemsFromStrings:(NSString*)firstString, … {
va_list args;
va_start(args, firstString);
NSMutableArray* tableItems = [NSMutableArray array];
for (NSString* string = firstString; string != nil; string = va_arg(args, NSString*)) {
RKTableItem* tableItem = [RKTableItem new];
tableItem.text = string;
[tableItems addObject:tableItem];
[tableItem release];
}
va_end(args);
return [NSArray arrayWithArray:tableItems];
}
+ (id)tableItem {
return [[self new] autorelease];
}
+ (id)tableItemUsingBlock:(void (^)(RKTableItem *))block {
RKTableItem* tableItem = [self tableItem];
block(tableItem);
return tableItem;
}
+ (id)tableItemWithText:(NSString *)text {
return [self tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = text;
}];
}
+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText {
return [self tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = text;
tableItem.detailText = detailText;
}];
}
+ (id)tableItemWithText:(NSString *)text detailText:(NSString *)detailText image:(UIImage*)image {
RKTableItem* tableItem = [self new];
tableItem.text = text;
tableItem.detailText = detailText;
tableItem.image = image;
return [tableItem autorelease];
}
+ (id)tableItemWithText:(NSString *)text usingBlock:(void (^)(RKTableItem *))block {
RKTableItem* tableItem = [[self new] autorelease];
tableItem.text = text;
block(tableItem);
return tableItem;
}
+ (id)tableItemWithText:(NSString *)text URL:(NSString *)URL {
RKTableItem* tableItem = [self tableItem];
tableItem.text = text;
tableItem.URL = URL;
return tableItem;
}
+ (id)tableItemWithCellMapping:(RKTableViewCellMapping *)cellMapping {
RKTableItem *tableItem = [self tableItem];
tableItem.cellMapping = cellMapping;
return tableItem;
}
+ (id)tableItemWithCellClass:(Class)tableViewCellSubclass {
RKTableItem *tableItem = [self tableItem];
tableItem.cellMapping = [RKTableViewCellMapping cellMapping];
tableItem.cellMapping.cellClass = tableViewCellSubclass;
return tableItem;
}
– (id)init {
self = [super init];
if (self) {
_userData = [RKMutableBlockDictionary new];
_cellMapping = [RKTableViewCellMapping new];
}
return self;
}
– (void)dealloc {
[_text release];
[_detailText release];
[_image release];
[_cellMapping release];
[_userData release];
[super dealloc];
}
– (NSString*)description {
return [NSString stringWithFormat:@”<%@: %p text=%@, detailText=%@, image=%p>“, NSStringFromClass([self class]), self, self.text, self.detailText, self.image];
}
#pragma mark – User Data KVC Proxy
– (void)setValue:(id)value forUndefinedKey:(NSString *)key {
[self.userData setValue:value ? value : [NSNull null] forKey:key];
}
– (id)valueForUndefinedKey:(NSString *)key {
return [self.userData valueForKey:key];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableItem.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableSection.h
//
// RKTableViewSection.h
// RestKit
//
// Created by Blake Watters on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMapping.h”
#import “RKTableViewCellMappings.h”
@class RKTableController;
@interface RKTableSection : NSObject {
@protected
NSMutableArray *_objects;
}
// Basics
@property (nonatomic, assign) RKTableController* tableController;
@property (nonatomic, readonly) UITableView* tableView;
// Object Mapping Table Stuff
@property (nonatomic, retain) NSArray* objects;
@property (nonatomic, retain) RKTableViewCellMappings* cellMappings;
// Header & Footer Views, etc.
@property (nonatomic, retain) NSString* headerTitle;
@property (nonatomic, retain) NSString* footerTitle;
@property (nonatomic, assign) CGFloat headerHeight;
@property (nonatomic, assign) CGFloat footerHeight;
@property (nonatomic, retain) UIView* headerView;
@property (nonatomic, retain) UIView* footerView;
// number of cells in the section
@property (nonatomic, readonly) NSUInteger rowCount;
+ (id)section;
+ (id)sectionUsingBlock:(void (^)(RKTableSection *))block;
+ (id)sectionForObjects:(NSArray*)objects withMappings:(RKTableViewCellMappings*)cellMappings;
– (id)objectAtIndex:(NSUInteger)rowIndex;
– (void)insertObject:(id)object atIndex:(NSUInteger)index;
– (void)removeObjectAtIndex:(NSUInteger)index;
– (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object;
– (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableSection.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableSection.m
//
// RKTableViewSection.m
// RestKit
//
// Created by Blake Watters on 8/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableSection.h”
#import “RKTableController.h”
#import “RKTableViewCellMapping.h”
#import “RKLog.h”
// Define logging component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
@implementation RKTableSection
@synthesize objects = _objects;
@synthesize cellMappings = _cellMappings;
@synthesize tableController = _tableController;
@synthesize headerTitle = _headerTitle;
@synthesize footerTitle = _footerTitle;
@synthesize headerHeight = _headerHeight;
@synthesize footerHeight = _footerHeight;
@synthesize headerView = _headerView;
@synthesize footerView = _footerView;
+ (id)section {
return [[self new] autorelease];
}
+ (id)sectionUsingBlock:(void (^)(RKTableSection *))block {
RKTableSection* section = [self section];
block(section);
return section;
}
+ (id)sectionForObjects:(NSArray *)objects withMappings:(RKTableViewCellMappings *)cellMappings {
return [self sectionUsingBlock:^(RKTableSection *section) {
section.objects = objects;
section.cellMappings = cellMappings;
}];
}
– (id)init {
self = [super init];
if (self) {
_objects = [NSMutableArray new];
_headerHeight = 0;
_footerHeight = 0;
}
return self;
}
– (void)dealloc {
[_objects release];
[_cellMappings release];
[_headerTitle release];
[_footerTitle release];
[_headerView release];
[_footerView release];
[super dealloc];
}
– (void)setObjects:(NSArray *)objects {
if (! [objects isMemberOfClass:[NSMutableArray class]]) {
NSMutableArray* mutableObjects = [objects mutableCopy];
[_objects release];
_objects = mutableObjects;
} else {
[objects retain];
[_objects release];
_objects = (NSMutableArray *) objects;
}
}
– (NSUInteger)rowCount {
return [_objects count];
}
– (id)objectAtIndex:(NSUInteger)rowIndex {
return [_objects objectAtIndex:rowIndex];
}
– (UITableView*)tableView {
return _tableController.tableView;
}
– (void)insertObject:(id)object atIndex:(NSUInteger)index {
[(NSMutableArray*)_objects insertObject:object atIndex:index];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:index
inSection:[_tableController indexForSection:self]];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:_tableController.defaultRowAnimation];
if ([_tableController.delegate respondsToSelector:@selector(tableController:didInsertObject:atIndexPath:)]) {
[_tableController.delegate tableController:_tableController didInsertObject:object atIndexPath:indexPath];
}
}
– (void)removeObjectAtIndex:(NSUInteger)index {
id object = [self objectAtIndex:index];
[(NSMutableArray*)_objects removeObjectAtIndex:index];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:index
inSection:[_tableController indexForSection:self]];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:_tableController.defaultRowAnimation];
if ([_tableController.delegate respondsToSelector:@selector(tableController:didDeleteObject:atIndexPath:)]) {
[_tableController.delegate tableController:_tableController didDeleteObject:object atIndexPath:indexPath];
}
}
– (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object {
[(NSMutableArray*)_objects replaceObjectAtIndex:index withObject:object];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:index
inSection:[_tableController indexForSection:self]];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:_tableController.defaultRowAnimation];
if ([_tableController.delegate respondsToSelector:@selector(tableController:didUpdateObject:atIndexPath:)]) {
[_tableController.delegate tableController:_tableController didUpdateObject:object atIndexPath:indexPath];
}
}
– (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex {
[self.tableView beginUpdates];
id object = [[self objectAtIndex:sourceIndex] retain];
[self removeObjectAtIndex:sourceIndex];
[self insertObject:object atIndex:destinationIndex];
[object release];
[self.tableView endUpdates];
// TODO: Should use moveRowAtIndexPath: when on iOS 5
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableSection.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableViewCellMapping.h
//
// RKTableViewCellMapping.h
// RestKit
//
// Created by Blake Watters on 8/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
#import “RKObjectMapping.h”
/** @name Cell Mapping Block Callbacks **/
typedef void(^RKTableViewCellForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath);
typedef CGFloat(^RKTableViewHeightOfCellForObjectAtIndexPathBlock)(id object, NSIndexPath *indexPath);
typedef void(^RKTableViewAccessoryButtonTappedForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath);
typedef NSString*(^RKTableViewTitleForDeleteButtonForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath);
typedef UITableViewCellEditingStyle(^RKTableViewEditingStyleForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath);
typedef NSIndexPath*(^RKTableViewTargetIndexPathForMoveBlock)(UITableViewCell *cell, id object, NSIndexPath *sourceIndexPath, NSIndexPath *destIndexPath);
typedef void(^RKTableViewAnonymousBlock)();
typedef void(^RKTableViewCellBlock)(UITableViewCell *cell);
/**
Defines a RestKit object mapping suitable for mapping generic
objects into UITableViewCell derived classes or cells loaded from
NIBs. The cell mapping leverages RestKit’s object mapping engine to
dynamically map keyPaths in your object model into properties on the
table cell view.
Cell mappings are used to drive table view cells within an RKTableController
derived class. The cell mapping does not require any specific implementation
on the target cell classes beyond exposure of the configurable UIView’s via
KVC properties.
@see RKTableController
*/
@interface RKTableViewCellMapping : RKObjectMapping {
@protected
NSMutableArray *_prepareCellBlocks;
}
/**
The UITableViewCell subclass that this mapping will target. This
is an alias for the objectClass property defined on the base mapping
provided here to make things more explicit.
@default [GGImageButtonTableViewCell class]
@see objectClass
*/
@property (nonatomic, assign) Class cellClass;
/**
Convenience accessor for setting the cellClass attribute via a string
rather than a class instance. This will typically save you from having
to #import the header file for your target cells in your table view controller
@default @”GGImageButtonTableViewCell”
@see cellClass
*/
@property (nonatomic, assign) NSString* cellClassName;
/**
A reuse identifier for cells created using this mapping. These cells will be
dequeued and reused within the table view for optimal performance. By default,
a reuseIdentifier is set for you when you assign an object class to the mapping.
You can override this behavior if you have multiple cells representing the same types
of objects within the table view and need to pool the cells differently.
@default NSStringFromClass(self.objectClass)
*/
@property (nonatomic, retain) NSString* reuseIdentifier;
/**
A Boolean value that determines whether the cell mapping manages basic cell
attributes (accessoryType, selectionStyle, etc.) or defers to a Storyboard/XIB
for defining basic cell attributes.
Setting the accessoryType or selectionStyle will set the value to YES.
**Default**: NO
*/
@property (nonatomic, assign) BOOL managesCellAttributes;
/**
The cell style to use for cells created with this mapping
@default UITableViewCellStyleDefault
*/
@property (nonatomic, assign) UITableViewCellStyle style;
/**
The cell accessory type to use for cells created with this mapping
@default UITableViewCellAccessoryNone
*/
@property (nonatomic, assign) UITableViewCellAccessoryType accessoryType;
/**
The cell selection style to use for cells created with this mapping
@default UITableViewCellSelectionStyleBlue
*/
@property (nonatomic, assign) UITableViewCellSelectionStyle selectionStyle;
/**
Whether the tableController should call deselectRowAtIndexPath:animated:
on the tableView when a cell is selected.
@default YES
*/
@property (nonatomic, assign) BOOL deselectsRowOnSelection;
/**
The row height to use for cells created with this mapping.
Use of this property requires that RKTableController instance you are
using the mapping to build cells for has been configured with variableHeightRows = YES
This value is mutually exclusive of the heightOfCellForObjectAtIndexPath property
and will be ignored if you assign a block to perform dynamic row height calculations.
**Default**: 44
*/
@property (nonatomic, assign) CGFloat rowHeight;
/** @name Cell Events **/
/**
Invoked when the user has touched a cell corresponding to an object. The block
is invoked with a reference to both the UITableViewCell that was touched and the
object the cell is representing.
*/
@property (nonatomic, copy) RKTableViewCellForObjectAtIndexPathBlock onSelectCellForObjectAtIndexPath;
/**
Invoked when the user has touched a cell configured with this mapping. The block is invoked
without any arguments. This is useful for one-off touch events where you do not care about
the content in which the selection took place.
@see onSelectCellForObjectAtIndexPath
*/
@property (nonatomic, copy) RKTableViewAnonymousBlock onSelectCell;
/**
A block to invoke when a table view cell created with this mapping is going to appear in the table.
The block will be invoked with the UITableViewCell, an id reference to the mapped object being
represented in the cell, and the NSIndexPath for the row position the cell will be appearing at.
This is a good moment to perform any customization to the cell before it becomes visible in the table view.
*/
@property (nonatomic, copy) RKTableViewCellForObjectAtIndexPathBlock onCellWillAppearForObjectAtIndexPath;
/**
A block to invoke when the table view is measuring the height of the UITableViewCell.
The block will be invoked with the UITableViewCell, an id reference to the mapped object being
represented in the cell, and the NSIndexPath for the row position the cell will be appearing at.
*/
@property (nonatomic, copy) RKTableViewHeightOfCellForObjectAtIndexPathBlock heightOfCellForObjectAtIndexPath;
/**
A block to invoke when the accessory button for a given cell is tapped by the user.
The block will be invoked with the UITableViewCell, an id reference to the mapped object being
represented in the cell, and the NSIndexPath for the row position the cell will be appearing at.
*/
@property (nonatomic, copy) RKTableViewAccessoryButtonTappedForObjectAtIndexPathBlock onTapAccessoryButtonForObjectAtIndexPath;
/**
A block to invoke when the table view is determining the title for the delete confirmation button.
The block will be invoked with the UITableViewCell, an id reference to the mapped object being
represented in the cell, and the NSIndexPath for the row position the cell will be appearing at.
*/
@property (nonatomic, copy) RKTableViewTitleForDeleteButtonForObjectAtIndexPathBlock titleForDeleteButtonForObjectAtIndexPath;
/**
A block to invoke when the table view is determining the editing style for a given row.
The block will be invoked with the UITableViewCell, an id reference to the mapped object being
represented in the cell, and the NSIndexPath for the row position the cell will be appearing at.
*/
@property (nonatomic, copy) RKTableViewEditingStyleForObjectAtIndexPathBlock editingStyleForObjectAtIndexPath;
@property (nonatomic, copy) RKTableViewTargetIndexPathForMoveBlock targetIndexPathForMove;
/**
Returns a new auto-released mapping targeting UITableViewCell
*/
+ (id)cellMapping;
/**
Returns a new auto-released mapping targeting UITableViewCell with the specified reuseIdentifier
*/
+ (id)cellMappingForReuseIdentifier:(NSString *)reuseIdentifier;
/**
Creates and returns an RKTableCellMapping instance configured with the default cell mappings.
@return An RKTableCellMapping instance with default mappings applied.
@see [RKTableCellMapping addDefaultMappings]
*/
+ (id)defaultCellMapping;
/**
Returns a new auto-released object mapping targeting UITableViewCell. The mapping
will be yielded to the block for configuration.
*/
+ (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping *cellMapping))block;
/**
Sets up default mappings connecting common properties to their UITableViewCell counterparts as follows:
[self mapKeyPath:@”text” toAttribute:@”textLabel.text”];
[self mapKeyPath:@”detailText” toAttribute:@”detailTextLabel.text”];
[self mapKeyPath:@”image” toAttribute:@”imageView.image”];
These properties are exposed on the RKTableItem class for convenience in quickly building static
table views/
@see RKTableItem
*/
– (void)addDefaultMappings;
/**
Configure a block to be invoked whenever a cell is prepared for use with this mapping.
The block will be invoked each time a cell is either initialized or dequeued for reuse.
*/
– (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block;
/** @name Configuring Control Actions */
// TODO: Docs!!!
– (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath;
– (void)addTarget:(id)target action:(SEL)action forTouchEventToControlAtKeyPath:(NSString *)keyPath;
– (void)addBlockAction:(void (^)(id sender))block forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath;
– (void)addBlockAction:(void (^)(id sender))block forTouchEventToControlAtKeyPath:(NSString *)keyPath;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableViewCellMapping.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableViewCellMapping.m
//
// RKTableViewCellMapping.m
// RestKit
//
// Created by Blake Watters on 8/4/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableViewCellMapping.h”
#import “RKLog.h”
// Define logging component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitUI
/**
A simple class for wrapping blocks into target/action
invocations that can be used with UIControl events
*/
typedef void(^RKControlBlockActionBlock)(id sender);
@interface RKControlBlockAction : NSObject {
@private
RKControlBlockActionBlock _actionBlock;
}
@property (nonatomic, readonly) SEL actionSelector;
+ (id)actionWithBlock:(void(^)(id sender))block;
– (id)initWithBlock:(void(^)(id sender))block;
/**
The target action to use when wrapping a block
*/
– (void)actionForControlEvent:(id)sender;
@end
@implementation RKControlBlockAction
+ (id)actionWithBlock:(void(^)(id sender))block {
return [[[self alloc] initWithBlock:block] autorelease];
}
– (id)initWithBlock:(void(^)(id sender))block {
self = [self init];
if (self) {
_actionBlock = Block_copy(block);
}
return self;
}
– (void)actionForControlEvent:(id)sender {
_actionBlock(sender);
}
– (SEL)actionSelector {
return @selector(actionForControlEvent:);
}
– (void)dealloc {
Block_release(_actionBlock);
[super dealloc];
}
@end
@implementation RKTableViewCellMapping
@synthesize reuseIdentifier = _reuseIdentifier;
@synthesize style = _style;
@synthesize accessoryType = _accessoryType;
@synthesize selectionStyle = _selectionStyle;
@synthesize onSelectCellForObjectAtIndexPath = _onSelectCellForObjectAtIndexPath;
@synthesize onSelectCell = _onSelectCell;
@synthesize onCellWillAppearForObjectAtIndexPath = _onCellWillAppearForObjectAtIndexPath;
@synthesize heightOfCellForObjectAtIndexPath = _heightOfCellForObjectAtIndexPath;
@synthesize onTapAccessoryButtonForObjectAtIndexPath = _onTapAccessoryButtonForObjectAtIndexPath;
@synthesize titleForDeleteButtonForObjectAtIndexPath = _titleForDeleteButtonForObjectAtIndexPath;
@synthesize editingStyleForObjectAtIndexPath = _editingStyleForObjectAtIndexPath;
@synthesize targetIndexPathForMove = _targetIndexPathForMove;
@synthesize rowHeight = _rowHeight;
@synthesize deselectsRowOnSelection = _deselectsRowOnSelection;
@synthesize managesCellAttributes;
+ (id)cellMapping {
return [self mappingForClass:[UITableViewCell class]];
}
+ (id)cellMappingForReuseIdentifier:(NSString *)reuseIdentifier {
RKTableViewCellMapping *cellMapping = [self cellMapping];
cellMapping.reuseIdentifier = reuseIdentifier;
return cellMapping;
}
+ (id)defaultCellMapping {
RKTableViewCellMapping *cellMapping = [self cellMapping];
[cellMapping addDefaultMappings];
return cellMapping;
}
+ (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping*))block {
RKTableViewCellMapping* cellMapping = [self cellMapping];
block(cellMapping);
return cellMapping;
}
– (id)init {
self = [super init];
if (self) {
self.cellClass = [UITableViewCell class];
self.style = UITableViewCellStyleDefault;
self.managesCellAttributes = NO;
_accessoryType = UITableViewCellAccessoryNone;
_selectionStyle = UITableViewCellSelectionStyleBlue;
self.rowHeight = 44;
self.deselectsRowOnSelection = YES;
_prepareCellBlocks = [NSMutableArray new];
}
return self;
}
– (void)addDefaultMappings {
[self mapKeyPath:@”text” toAttribute:@”textLabel.text”];
[self mapKeyPath:@”detailText” toAttribute:@”detailTextLabel.text”];
[self mapKeyPath:@”image” toAttribute:@”imageView.image”];
}
– (void)dealloc {
[_reuseIdentifier release];
[_prepareCellBlocks release];
Block_release(_onSelectCell);
Block_release(_onSelectCellForObjectAtIndexPath);
Block_release(_onCellWillAppearForObjectAtIndexPath);
Block_release(_heightOfCellForObjectAtIndexPath);
Block_release(_onTapAccessoryButtonForObjectAtIndexPath);
Block_release(_titleForDeleteButtonForObjectAtIndexPath);
Block_release(_editingStyleForObjectAtIndexPath);
Block_release(_targetIndexPathForMove);
[super dealloc];
}
– (NSMutableArray *)prepareCellBlocks {
return _prepareCellBlocks;
}
– (id)copyWithZone:(NSZone *)zone {
RKTableViewCellMapping *copy = [super copyWithZone:zone];
copy.reuseIdentifier = self.reuseIdentifier;
copy.style = self.style;
copy.accessoryType = self.accessoryType;
copy.selectionStyle = self.selectionStyle;
copy.onSelectCellForObjectAtIndexPath = self.onSelectCellForObjectAtIndexPath;
copy.onSelectCell = self.onSelectCell;
copy.onCellWillAppearForObjectAtIndexPath = self.onCellWillAppearForObjectAtIndexPath;
copy.heightOfCellForObjectAtIndexPath = self.heightOfCellForObjectAtIndexPath;
copy.onTapAccessoryButtonForObjectAtIndexPath = self.onTapAccessoryButtonForObjectAtIndexPath;
copy.titleForDeleteButtonForObjectAtIndexPath = self.titleForDeleteButtonForObjectAtIndexPath;
copy.editingStyleForObjectAtIndexPath = self.editingStyleForObjectAtIndexPath;
copy.targetIndexPathForMove = self.targetIndexPathForMove;
copy.rowHeight = self.rowHeight;
@synchronized(_prepareCellBlocks) {
for (void (^block)(UITableViewCell *) in _prepareCellBlocks) {
void (^blockCopy)(UITableViewCell *cell) = [block copy];
[copy addPrepareCellBlock:blockCopy];
[blockCopy release];
}
}
return copy;
}
– (id)mappableObjectForData:(UITableView *)tableView {
NSAssert([tableView isKindOfClass:[UITableView class]], @”Expected to be invoked with a tableView as the data. Got %@”, tableView);
RKLogTrace(@”About to dequeue reusable cell using self.reuseIdentifier=%@”, self.reuseIdentifier);
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier];
if (! cell) {
cell = [[[self.objectClass alloc] initWithStyle:self.style
reuseIdentifier:self.reuseIdentifier] autorelease];
}
if (self.managesCellAttributes) {
cell.accessoryType = self.accessoryType;
cell.selectionStyle = self.selectionStyle;
}
// Fire the prepare callbacks
for (void (^block)(UITableViewCell *) in _prepareCellBlocks) {
block(cell);
}
return cell;
}
– (void)setSelectionStyle:(UITableViewCellSelectionStyle)selectionStyle {
self.managesCellAttributes = YES;
_selectionStyle = selectionStyle;
}
– (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType {
self.managesCellAttributes = YES;
_accessoryType = accessoryType;
}
– (void)setObjectClass:(Class)objectClass {
NSAssert([objectClass isSubclassOfClass:[UITableViewCell class]], @”Cell mappings can only target classes that inherit from UITableViewCell”);
[super setObjectClass:objectClass];
}
– (void)setCellClass:(Class)cellClass {
[self setObjectClass:cellClass];
}
– (NSString*)cellClassName {
return NSStringFromClass(self.cellClass);
}
– (void)setCellClassName:(NSString *)cellClassName {
self.cellClass = NSClassFromString(cellClassName);
}
– (Class)cellClass {
return [self objectClass];
}
– (NSString *)reuseIdentifier {
return _reuseIdentifier ? _reuseIdentifier : NSStringFromClass(self.objectClass);
}
#pragma mark – Control Action Helpers
– (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block {
void (^blockCopy)(UITableViewCell *cell) = [block copy];
[_prepareCellBlocks addObject:blockCopy];
[blockCopy release];
}
– (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath {
[self addPrepareCellBlock:^(UITableViewCell *cell) {
UIControl *control = [cell valueForKeyPath:keyPath];
if (control) {
[control addTarget:target action:action forControlEvents:controlEvents];
} else {
// TODO: Logging…
}
}];
}
– (void)addTarget:(id)target action:(SEL)action forTouchEventToControlAtKeyPath:(NSString *)keyPath {
[self addTarget:target action:action forControlEvents:UIControlEventTouchUpInside toControlAtKeyPath:keyPath];
}
– (void)addBlockAction:(void (^)(id sender))block forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath {
[self addPrepareCellBlock:^(UITableViewCell *cell) {
RKControlBlockAction *blockAction = [RKControlBlockAction actionWithBlock:block];
UIControl *control = [cell valueForKeyPath:keyPath];
if (control) {
[control addTarget:blockAction action:blockAction.actionSelector forControlEvents:controlEvents];
} else {
// TODO: Logging…
}
}];
}
– (void)addBlockAction:(void (^)(id sender))block forTouchEventToControlAtKeyPath:(NSString *)keyPath {
[self addBlockAction:block forControlEvents:UIControlEventTouchUpInside toControlAtKeyPath:keyPath];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableViewCellMapping.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableViewCellMappings.h
//
// RKTableViewCellMappings.h
// RestKit
//
// Created by Blake Watters on 8/9/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableViewCellMapping.h”
@interface RKTableViewCellMappings : NSObject {
@private
NSMutableDictionary* _cellMappings;
}
+ (id)cellMappings;
– (void)setCellMapping:(RKTableViewCellMapping*)cellMapping forClass:(Class)objectClass;
– (RKTableViewCellMapping*)cellMappingForClass:(Class)objectClass;
– (RKTableViewCellMapping*)cellMappingForObject:(id)object;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableViewCellMappings.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/RKTableViewCellMappings.m
//
// RKTableViewCellMappings.m
// RestKit
//
// Created by Blake Watters on 8/9/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “RKTableViewCellMappings.h”
@implementation RKTableViewCellMappings
+ (id)cellMappings {
return [[self new] autorelease];
}
– (id)init {
self = [super init];
if (self) {
_cellMappings = [NSMutableDictionary new];
}
return self;
}
– (void)setCellMapping:(RKTableViewCellMapping*)cellMapping forClass:(Class)objectClass {
if ([_cellMappings objectForKey:objectClass]) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:[NSString stringWithFormat:@”A tableViewCell mapping has already been registered for objects of type ‘%@'”, NSStringFromClass(objectClass)]
userInfo:nil];
}
[_cellMappings setObject:cellMapping forKey:objectClass];
}
– (RKTableViewCellMapping*)cellMappingForClass:(Class)objectClass {
// Exact match
RKTableViewCellMapping* cellMapping = [_cellMappings objectForKey:objectClass];
if (cellMapping) return cellMapping;
// Subclass match
for (Class cellClass in _cellMappings) {
if ([objectClass isSubclassOfClass:cellClass]) {
return [_cellMappings objectForKey:cellClass];
}
}
return nil;
}
– (RKTableViewCellMapping*)cellMappingForObject:(id)object {
if ([object respondsToSelector:@selector(cellMapping)]) {
// TODO: Trace logging…
// TODO: This needs unit test coverage on the did select row case…
RKTableViewCellMapping* cellMapping = [object cellMapping];
if (cellMapping) return [object cellMapping];
}
return [self cellMappingForClass:[object class]];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._RKTableViewCellMappings.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/UI.h
//
// UI.h
// RestKit
//
// Created by Blake Watters on 8/8/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef RestKit_UI_h
#define RestKit_UI_h
#import “RKTableController.h”
#import “RKTableSection.h”
#import “RKTableItem.h”
#import “RKControlTableItem.h”
#import “RKFetchedResultsTableController.h”
#import “RKForm.h”
#import “RKFormSection.h”
#import “RKRefreshTriggerView.h”
#import “RKObjectManager+RKTableController.h”
#import “UIImage+RKAdditions.h”
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._UI.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/UIImage+RKAdditions.h
//
// UIImage+RKAdditions.h
// RestKit
//
// Created by Blake Watters on 2/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#if TARGET_OS_IPHONE
#import
/**
Provides useful extensions to the UIImage interface.
Resolution indepdence helpers borrowed from:
http://atastypixel.com/blog/uiimage-resolution-independence-and-the-iphone-4s-retina-display/
*/
@interface UIImage (RKAdditions)
/**
Creates and returns an image object by loading the image data from the file at the specified path
appropriate for the resolution of the device.
@param path The full or partial path to the file, possibly including an @2x retina image.
@return A new image object for the specified file, or an image for the @2x version of the specified file,
or nil if the method could not initialize the image from the specified file.
*/
+ (UIImage *)imageWithContentsOfResolutionIndependentFile:(NSString *)path;
/**
Initializes an image object by loading the image data from the file at the specified path
appropriate for the resolution of the device.
@param path The full or partial path to the file, possibly including an @2x retina image.
@return The initialized image object for the specified file, or for the @2x version of the specified file,
or nil if the method could not initialize the image from the specified file.
*/
– (id)initWithContentsOfResolutionIndependentFile:(NSString *)path;
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._UIImage+RKAdditions.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/UIImage+RKAdditions.m
//
// UIImage+RKAdditions.m
// RestKit
//
// Created by Blake Watters on 2/24/12.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import “UIImage+RKAdditions.h”
#if TARGET_OS_IPHONE
@implementation UIImage (RKAdditions)
– (id)initWithContentsOfResolutionIndependentFile:(NSString *)path {
if ( [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0 ) {
NSString *path2x = [[path stringByDeletingLastPathComponent]
stringByAppendingPathComponent:[NSString stringWithFormat:@”%@@2x.%@”,
[[path lastPathComponent] stringByDeletingPathExtension],
[path pathExtension]]];
if ( [[NSFileManager defaultManager] fileExistsAtPath:path2x] ) {
return [self initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:path2x]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
}
}
return [self initWithData:[NSData dataWithContentsOfFile:path]];
}
+ (UIImage *)imageWithContentsOfResolutionIndependentFile:(NSString *)path {
return [[[UIImage alloc] initWithContentsOfResolutionIndependentFile:path] autorelease];
}
@end
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._UIImage+RKAdditions.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/UIView+FindFirstResponder.h
//
// UIView+FindFirstResponder.h
// RestKit
//
// Created by Blake Watters on 8/29/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import
@interface UIView (FindFirstResponder)
– (UIView*)findFirstResponder;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._UIView+FindFirstResponder.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/UIView+FindFirstResponder.m
//
// UIView+FindFirstResponder.m
// RestKit
//
// Created by Blake Watters on 8/29/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an “AS IS” BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import “UIView+FindFirstResponder.h”
@implementation UIView (FindFirstResponder)
– (UIView*)findFirstResponder {
if (self.isFirstResponder) {
return self;
}
for (UIView* subView in self.subviews) {
UIView* firstResponder = [subView findFirstResponder];
if (firstResponder != nil) {
return firstResponder;
}
}
return nil;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/UI/._UIView+FindFirstResponder.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Code/._UI
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Code
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/CREDITS.md
RestKit Credits
===============
RestKit was originally developed in the summer of 2009 under the name OTRestFramework
as a Ruby on Rails specific object mapper for XML data. In early 2010 the framework was
rebranded as RestKit and evolved into a general purpose HTTP toolkit and object mapping
system.
RestKit is available as an Open Source package under the terms of the Apache License (see
LICENSE for details).
## Original Author
* Blake Watters (blakewatters) @blakewatters
## Core Team
* Jeff Arena (jeffarena)
* Gregory Combs (grgcombs)
* Brian Morton (bmorton)
## Web Designer
* Adit Shukla (aditshukla)
## Contributors
#### Version 0.9.3 and earlier
* Jeremy Ellison (jeremyellison)
* Daniel Hammond (danielrhammond)
* Marc Weil (aspir)
* Pat Shields (pashields)
* Tim Kerchmar (timkerchmar)
* Rachit Shukla (rachitshukla)
* Adam Hinz (ahinz)
* Stefan Eletzhofer (seletz)
* Peter Marks (tassock)
* Chad Podoski (chadpod)
* Andras Hatvani (andrashatvani)
* Ed McManus (emcmanus)
#### Version 0.10.0
* Christopher Swasey (endash)
* Aneil Mallavarapu (amallavarapu)
* Rui D Lopes (ruidlopes)
* Robert Altman (inquinity)
* Beat Besmer (besi)
* Scott Penrose (spenrose)
* Charlie Savage (cfis)
* Jawwad Ahmad (jawwad)
* John Stallings (jstallings)
* Bob Spryn (sprynmr)
* Ray Fix (rayfix)
* Marlon Andrade (marlonandrade)
* David Young-Chan Kay (DavidYKay)
* Chethan Reddy (creddy)
* Julien Grimault (juliengrimault)
* Matthias Bartelmeß
* Nolan Waite (nolanw)
* Michael Fleet (fantasticmf)
* Tony Lee (hktonylee)
* Aaron Crespo (aaroncrespo)
* James Sullivan (jsullivanlive)
* Marco Pesenti Gritti (marcopg)
* Brad Phelan (bradphelan)
* Ivan Vučica (ivucica)
* Felix Holmgren (Felixyz)
* Open Thread (OpenFibers)
* Sergej Tatarincev (SevInf)
* Ben Einstein (beinstein)
* Johan Bilien (jobi)
* Björn Jonsson (bjornjonsson)
* Ralf van der Zanden (ralfvdz)
* Parker Boundy (parkerboundy)
* Jeremy Mack (mutewinter)
* Allen Wei (allenwei)
* Robin Eggenkamp (Edubits)
* Emil Wojtaszek (emilwojtaszek)
* Victor Kryukov (victorkryukov)
* Cody Rayment (crayment)
* Arne Harren (aharren)
* Cameron Royal (cammm)
## Honorable Mentions
RestKit would like to thank the following companies for aiding in the support of this product:
* GateGuru – http://www.gateguru.com
* Two Toasters – http://www.twotoasters.com
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._CREDITS.md
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Design/RKCache.txt
RestKit Cache Design
====================
This document outlines the design for a lightweight cache implementation for the RestKit framework. The goals
of the cache are:
* Provide support for offline access to data payloads
* Provide storage of last modification times for etags
* Provide cache policies at the client and request level
* RKResponse should be able to answer – (BOOL)wasLoadedFromCache
* Each RKClient has its own cache (path initialized by Base URL somehow?)
* RKCache should have a storage policy. This should be settable to session (store for the run of the app) or permanently.
Needs to store:
* Key/values
* Settable via NSURL (not resource path)
Concerns:
* Does this need to be harmonized with the managed object cache? Can it be?
* Don’t love how tightly coupled cacheing is in Three20. Want something more orthogonal.
* How are we going to unit test this? Need to identify test cases…
* Where does the cache loading logic go? Request queue? Client? Inside of RKRequest? New class?
References:
* TTURLCache
* ASIDownloadCache
ETags:
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
* Comes across as either “ETag” or “Etag” header
* Should be contained to RKRequest / RKResponse (don’t bleed through into the cache)
* Needs to be added on load via If-None-Match
Request cache policies:
* RKClient should have a default cache policy that gets passed through to requests
* RKRequest will have a cache policy property. This determines when and how to utilize the cache.
* You should be able to bitwise | these together, i.e. RKRequestCachePolicyLoadIfOffline | RKRequestCachePolicyEtag
typedef enum {
RKRequestCachePolicyNone = 0, // Never use the cache
RKRequestCachePolicyLoadIfOffline, // Load from the cache when we are offline
RKRequestCachePolicyLoadOnError, // Load from the cache if we encounter an error
RKRequestCachePolicyEtag, // Load from the cache if we have data stored and the server returns a 304 (not modified) response
RKRequestCachePolicyDefault = RKRequestCachePolicyEtag;
} RKRequestCachePolicy;
###################################################################################
// Proposed Interface
// Returns a cache key for a URL (md5 the full URL after coercing to a string)
// This will let you work with the cache via URL’s pretty easily
– (NSString*)RKCacheKeyForURL:(NSURL*)URL;
// Storage policy. Determines if we clear the cache out when the app is shut down. Cache
// instance needs to register for
typedef enum {
RKCacheStoragePolicyDisabled, // The cache has been disabled. Attempts to store data will silently fail
RKCacheStoragePolicyForDurationOfSession, // Cache data for the length of the session. Clear cache at app exit.
RKCacheStoragePolicyPermanently // Cache data permanently, until explicitly expired or flushed
} RKCacheStoragePolicy;
@interface RKCache : NSObject {
NSString* _cachePath;
RKCacheStoragePolicy _storagePolicy;
}
@property (nonatomic, readonly) NSString* cachePath; // Full path to the cache
@property (nonatomic, assign) RKCacheStoragePolicy storagePolicy; // User can change storage policy.
// Should be initialized with the full path to store it. RKClient should
// figure out the appropriate path when initializing.
– (id)initWithCachePath:(NSString*)cachePath storagePolicy:(RKCacheStoragePolicy)storagePolicy;
// Key/value storage
– (NSString*)pathForKey:(NSString*)key;
– (BOOL)hasDataForKey:(NSString*)key;
– (void)storeData:(NSData*)data forKey:(NSString*)key;
– (NSData*)dataForKey:(NSString*)key;
– (NSData*)dataForKey:(NSString*)key expires:(NSTimeInterval)expirationAge
timestamp:(NSDate**)timestamp;
// Cache Invalidation
– (void)invalidateKey:(NSString*)key;
– (void)invalidateAll;
@end
// RKRequest
Get new properties:
NSString* cacheKey; // When GET, defaults to RKCacheKeyForURL. For POST/PUT, md5 of the serialization data.
RKRequestCachePolicy cachePolicy; // Cache policy inherited from RKClient.
// RKResponse
BOOL wasLoadedFromCache; // YES when the response was built from cached data
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Design/._RKCache.txt
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Design/RKRequestQueue.txt
This document details an extension to the RKRequest queue to make it more general purpose:
1) RestKit currently implements a hard limit on 5 concurrent requests on a queue basis. This should be exposed as a property called concurrentRequestsLimit
2) The sendRequest: method is poorly named. It should probably be called addRequest: or enqueueRequest:
3) You’ll probably want delegate methods to keep track of what’s going on in the Queue. I’ve sketched them below.
4) We may want to make freshly alloc’d queues start in the suspended state.
RKRequestQueue* queue = [[RKRequestQueue alloc] init];
queue.concurrentRequestsLimit = 1;
queue.delegate = self;
RKObjectLoader* loader = [[RKObjectManager sharedManager] objectLoaderWithResourcePath:@”/whatever” delegate:self];
[queue addRequest:loader];
RKRequest* request = [[RKClient sharedClient] requestWithResourcePath:@”/another” delegate:self];
[queue addRequest:request];
[queue start];
// Delegate methods
@optional
– (void)requestQueueDidStart:(RKRequestQueue*)queue; // Sent when queue starts running
– (void)requestQueueDidFinish:(RKRequestQueue*)queue; // Sent when its emptied
– (void)requestQueue:(RKRequestQueue*)queue willSendRequest:(RKRequest*)request;
– (void)requestQueue:(RKRequestQueue*)queue didSendRequest:(RKRequest*)request;
– (void)requestQueue:(RKRequestQueue*)queue didLoadResponse:(RKResponse*)response;
– (void)requestQueue:(RKRequestQueue*)queue didCancelRequest:(RKRequest*)request;
– (void)requestQueue:(RKRequestQueue*)queue didFailRequest:(RKRequest*)request withError:(NSError*)error;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Design/._RKRequestQueue.txt
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._Design
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/01_Select_Project_Settings
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/._01_Select_Project_Settings
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/02_Advanced_Button
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/._02_Advanced_Button
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/03_Select_Build_Location
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/DerivedData/._03_Select_Build_Location
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/._DerivedData
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/01_Add_Submodule
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._01_Add_Submodule
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/02_Add_Project_Dependency
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._02_Add_Project_Dependency
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/03_Add_Header_Search_Path
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._03_Add_Header_Search_Path
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/03_Add_Linker_Flag
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._03_Add_Linker_Flag
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/04_Add_Target_Dependency
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._04_Add_Target_Dependency
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/05_Select_RestKit_Target
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._05_Select_RestKit_Target
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/06_Add_Libraries
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._06_Add_Libraries
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/07_Add_RestKit_Static_Libraries
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._07_Add_RestKit_Static_Libraries
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/08_Add_Required_Frameworks
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._08_Add_Required_Frameworks
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/09_Add_To_AppDelegate
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._09_Add_To_AppDelegate
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/10_Verify_Build
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Installation/._10_Verify_Build
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/._Installation
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Troubleshooting/Clean_Build_Folder
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Troubleshooting/._Clean_Build_Folder
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Troubleshooting/Delete_Derived_Data
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/Troubleshooting/._Delete_Derived_Data
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Images/._Troubleshooting
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._Images
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Advanced RestKit/Advanced_RestKit_Tutorial.mdAdvanced Development with RestKit
—
In this article we will continue our exploration of RestKit, an iOS framework for working with web services. It is assumed that the reader has read Part I and has a working knowledge of RestKit. Building on the foundation we established in the introduction, we will examine the advanced capabilities of the library and learn how to accelerate our iOS development efforts.
## What is covered?
* Advanced Networking: Multi-part requests, reachability, the request queue and background upload/download are all covered.
* Advanced Object Mapping: Key-value coding and relationship mapping.
* Core Data: Integration between the object mapper and Apple’s Core Data persistence framework are discussed at length. This includes configuration, relationship management, database seeding, etc.
* Integration Layers: We’ll briefly touch on the integration points exposed by the library for working with Ruby on Rails backends and interaction with Facebook’s Three20 framework.
## Companion Example Code
To aid the reader in following the concepts presented here, an accompanying example application is provided with the RestKit distribution. Each section of the tutorial will refer you to a specific example in the __RKCatalog__ example, found in the RestKit/Examples/RKCatalog directory.
At the time of this writing, RestKit is currently at version *0.9.2*. Library source and example code can be downloaded from the [RestKit Downloads Page](https://github.com/twotoasters/RestKit/downloads).
## Advanced Networking
We’ve already been introduced to the key players in the RestKit Network layer: RKClient, RKRequest, and RKResponse. These three classes provide a simple, clean API for making requests to a remote web service. In this section we’ll see how RestKit scales up when things get more complicated.
### Request Serialization: Under the Hood
In the introduction to the Network layer, we learned to use RestKit to send requests using the `get`, `post`, `put` and `delete` methods. These methods abstract away the details of constructing a full URL, building a request, populating the request body, and asynchronously sending the request.
We also learned how to embed parameters into our requests by providing an NSDictionary of key/value pairs. Under the covers, RestKit takes this dictionary and constructs a URL encoded HTTP body to attach to the request. The Content-Type header is set to ‘application/x-www-form-urlencoded’ and the request is sent off for processing. This is a great convenience over having to construct the request bodies ourselves and it is this support that forms the basis of the object mapper.
But what about requests that can’t be represented by dictionaries or be loaded into memory all at once? We must look beyond the simplicity afforded by NSDictionary and take a look at two new entities: RKRequestSerializable and RKParams.
Though we often use NSDictionary to represent the parameters for many of our requests, RestKit does not specifically bless NSDictionary. If you looked at the method signature for RKRequest’s params argument, you’ll note that it does not specify NSDictionary at all. Instead you’ll see:
@property(nonatomic, retain) NSObject
Note the RKRequestSerializable protocol here. RKRequestSerializable defines a very lightweight protocol that allows arbitrary classes to serialize themselves for use in the body of an RKRequest. When you import RestKit, it adds a category to NSDictionary providing an implementation of the RKRequestSerializable protocol. RKRequestSerializable defines just a couple of methods that you need to implement to make any object type serializable:
* **HTTPHeaderValueForContentType** – This method returns an NSString value to be used as the Content-Type header for the request. For NSDictionary, we encode the keys/values using form encoding and return ‘application/x-www-form-urlencoded’ for this method.
* **HTTPHeaderValueForContentLength** – This optional method returns an NSUInteger value to be used as the Content-Length header for the request. This is useful in long running upload requests for the purposes of tracking progress.
* **HTTPBody** – This method returns an NSData object containing the data you want to send as the body of the request. For NSDictionary, we walk through the key/value pairs and construct a URL encoded string. The string is then coerced into an NSData by using the NSUTF8StringEncoding encoding. This method is optional if you provide an implementation of **HTTPBodyStream** (see below).
* **HTTPBodyStream** – This method returns an NSStream object that should be used to read data for use in the request body. HTTPBodyStream will be consulted ahead of HTTPBody during request construction. HTTPBodyStream can be used to provide support for uploading files that exist on disk or are too big to fit into main memory. RestKit will efficiently stream the data off the disk and send it for processing.
### RKParams: Sending Multi-part Requests
Now that we understand how RestKit coerces arbitrary objects into serializable representations, we can look at another implementation of RKRequestSerializable that ships with the library: RKParams. RKParams provides a simple interface for building more complex multi-part requests. You can think of RKParams as an HTTP-aware dictionary implementation. In addition to providing simple objects for the values in our parameters, RKParams also allows us to provide NSData and paths to files on disk. We are also able to set the file name and MIME type of each parameter individually. To illustrate how this works, let’s look at some code:
NSString* myFilePath = @”/some/path/to/picture.gif”;
RKParams* params = [RKParams params];
// Set some simple values — just like we would with NSDictionary
[params setValue:@”Blake” forParam:@”name”];
[params setValue:@”” forParam:@”email”];
// Create an Attachment
RKParamsAttachment* attachment = [params setFile:myFilePath forParam:@”image1″];
attachment.MIMEType = @”image/gif”;
attachment.fileName = @”picture.gif”;
// Attach an Image from the App Bundle
UIImage* image = [UIImage imageNamed:@”another_image “];
NSData* imageData = UIImagePNGRepresentation(image);
[params setData:imageData MIMEType:@”image/png” forParam:@”image2″];
// Let’s examine the RKRequestSerializable info…
NSLog(@”RKParams HTTPHeaderValueForContentType = %@”, [params HTTPHeaderValueForContentType]);
NSLog(@”RKParams HTTPHeaderValueForContentLength = %d”, [params HTTPHeaderValueForContentLength]);
// Send a Request!
[[RKClient sharedClient] post:@”/uploadImages” params:params delegate:self];
Essentially what we are doing here is creating a stack of RKParamsAttachment objects that are contained within the RKParams instance. With every call to `setValue`, `setFile`, or `setData` we are instantiating a new instance of RKParamsAttachment and adding it to the stack. Each of these methods returns the RKParamsAttachment object it has created for you so that you can further customize it if need be. We see this used to set the `MIMEType` and `fileName` properties for image. When we assign the params object to the RKRequest, it is serialized into a multipart/form-data document and read as a stream by the underlying NSURLConnection. This streaming behavior allows RKParams to be used for reading very large files off of disk without exhausting memory on an iOS device.
**Example Code** – See [RKParamsExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKParamsExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
### The Request Queue
While you have been happily sending requests and processing responses with RKClient, RKRequest, and RKResponse another part of RestKit has been quietly operating behind the scenes, without your knowledge: RKRequestQueue. The Request Queue is an important support player in the RestKit world and becomes increasingly important as your application grows in scope. RKRequestQueue has three primary responsibilities: managing request memory, ensuring the network does not get overly burdened, and managing request life cycle.
Memory management can become very tiresome in Cocoa applications, as so much work happens asynchronously. RestKit is all about reducing the complexity and ceremony associated with working with web services in Cocoa and as such provides RKRequestQueue to shift the memory management concerns away from the application developer and into the framework. Recall what a typical RestKit request/response looks like:
– (void)sendARequest {
RKRequest* request = [[RKClient sharedClient] get:@”/some/path” delegate:self];
NSLog(@”Sent a request! %@”, request);
}
– (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
if ([response isJSON]) {
NSLog(@”Got a JSON response back!”);
}
}
Notice that there isn’t a single call to retain, release or autorelease anywhere in sight. This is where the request queue comes into play. When we ask to send an RKRequest object, it isn’t immediately dispatched. Instead it is retained by the RKClient’s requestQueue instance and sent as soon as possible. RestKit watches for notifications generated by RKRequest & RKResponse and releases its hold on the request after processing has completed. This allows us to work with web services with very little thought about the memory management.
In addition to retaining & releasing RKRequest instances, RKRequestQueue also serves as a gatekeeper to the network access itself. When the application is first launched or returns from a background state, RestKit uses its integration with the System Configuration Reachability API’s to determine if any network access is available. When talking to a remote server by hostname, there can be a delay between launch and the determination of network availability. During this time, RestKit is in an indeterminate reachability state and RKRequestQueue will defer sending any requests until network reachability can be determined. Once reachability is determined, RKRequestQueue prevents the network from becoming overburdened by limiting the number of concurrent requests to five.
Once your user interfaces begin spanning multiple controllers and users are navigating the controller stack quickly, you may begin generating a number of requests that do not need to be completed because the user has dismissed the view. Here we turn to ___RKRequestQueue___ as well. Let’s imagine that we have a controller that immediately begins loading some data when the view appears. But the controller also has a number of buttons that the user can quickly access to change perspectives, making the request we kicked off no longer of interest. We can either hold on to the instances of RKRequest that we generate or we can let ___RKRequestQueue___ do the work for us. Let’s see how this would work:
– (void)viewWillAppear:(BOOL)animated {
/**
* Ask RKClient to load us some data. This causes an RKRequest object to be created
* transparently pushed onto [RKClient sharedClient].requestQueue instance
*/
[[RKClient sharedClient] get:@”/some/data.json” delegate:self];
}
// We have been dismissed — clean up any open requests
– (void)dealloc {
[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:self];
[super dealloc];
}
// We have been obscured — cancel any pending requests
– (void)viewWillDisappear:(BOOL)animated {
[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:self];
}
Rather than managing the request ourselves and doing the housekeeping, we can just ask RKRequestQueue to cancel any requests that we are the delegate for. If there are none currently processing, no action will be taken.
A requestQueue instance is created for you at RKClient initialization time. It is also possible to create additional ad-hoc queues to manage groups of requests
more granularly. For example, an ad-hoc queue could be useful for downloading or uploading content in the background, while keeping the main shared queue free for responding to user actions. Let’s take a look at an example of using an ad-hoc queue:
– (IBAction)queueRequests {
RKRequestQueue* queue = [[RKRequestQueue alloc] init];
queue.delegate = self;
queue.concurrentRequestsLimit = 1;
queue.showsNetworkActivityIndicatorWhenBusy = YES;
// Queue up 4 requests
[queue addRequest:[[RKClient sharedClient] requestWithResourcePath:@”/RKRequestQueueExample” delegate:self]];
[queue addRequest:[[RKClient sharedClient] requestWithResourcePath:@”/RKRequestQueueExample” delegate:self]];
[queue addRequest:[[RKClient sharedClient] requestWithResourcePath:@”/RKRequestQueueExample” delegate:self]];
[queue addRequest:[[RKClient sharedClient] requestWithResourcePath:@”/RKRequestQueueExample” delegate:self]];
// Start processing!
[queue start];
}
In this example we have created an ad-hoc queue that dispatches one request at a time and spins the system network activity indicator. There are a number of delegate methods available for the request queue to make managing groups of requests easier. Check out the RKRequestQueue example in RKCatalog for detailed examples.
**Example Code** – See [RKRequestQueueExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKRequestQueueExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
### Reachability
As iOS developers, one of the annoying realities we face and must deal with is that of intermittent connectivity. As our users move throughout their world with our applications, connectivity is guaranteed to come and go. Coding for this reality can complicate our logic and distort the intent in our code with conditional logic.
To make matters worse, the SCReachability API’s available to us for monitoring network status are implemented as low level C API’s. To help ease this burden and provide a platform for higher level functionality, RestKit ships with a wrapper around the low level SCReachability API’s: RKReachabilityObserver.
RKReachabilityObserver abstracts away the SCReachability C API’s and instead presents a very straight-forward Objective-C interface for determining network status. Let’s take a look at some code:
– (void)workWithReachability {
/**
* Initialize an observer against a hostname. Note that we can also provide an IP address in the hostname
* string and RestKit will configure the observer to watch the network address instead of the host
*/
RKReachabilityObserver* observer = [RKReachabilityObserver reachabilityObserverWithHostName:@”restkit.org”];
// Let the run-loop execute so reachability can be determined
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
if ([observer isNetworkReachable]) {
NSLog(@”We have network access! Huzzah!”);
if ([observer isConnectionRequired]) {
NSLog(@”Network is available if we open a connection…”);
}
if (RKReachabilityReachableViaWiFi == [observer networkStatus]) {
NSLog(@”Online via WiFi!”);
} else if (RKReachabilityReachableViaWWAN == [observer networkStatus]) {
NSLog(@”Online via 3G or Edge…”);
}
} else {
NSLog(@”No network access.”);
}
}
Now that we’ve seen how to initialize and work with RKReachabilityObserver, it’s worth noting that most of the time we don’t have to! When you initialize RKClient or RKObjectManager with a base URL, RestKit goes ahead and initializes an instance of RKReachabilityObserver targeted at the hostname specified in your base URL. This observer is available to you via the `baseURLReachabilityObserver` property on RKClient. RKReachabilityObserver also emits notifications whenever network state changes. Typically these events are all that you are interested in. Observing the reachability events is easy:
@implementation ReachabilityInterestedClass
– (id)init {
if ((self = [super init])) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:RKReachabilityStateChangedNotification
object:nil];
}
return self;
}
– (void)reachabilityChanged:(NSNotification*)notification {
RKReachabilityObserver* observer = (RKReachabilityObserver*)[notification object];
if ([observer isNetworkReachable]) {
NSLog(@”We’re online!”);
} else {
NSLog(@”We’ve gone offline!”);
}
}
@end
**Example Code** – See [RKReachabilityExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKReachabilityExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
We’ll explore how RestKit leverages Reachability internally to provide transparent offline access in the Core Data object caching section.
### Background Upload/Download
With iOS 4.0, Apple introduced multi-tasking support for applications. The multi-tasking support relies on putting apps into a background state, where they can be quickly restored to full interactive mode, but not consume resources while in the background. This can present a problem for network applications such as those built with RestKit: important long-running requests can be interrupted by the user switching out of the app. Thankfully Apple also provided limited support for extending the life of your process by creating a background task using the `beginBackgroundTaskWithExpirationHandler` method on `UIApplication`. This method accepts an Objective-C block and returns a `UIBackgroundTaskIdentifier` value for the background task that was created. Care must be taken when creating the background task so that backward compatibility with iOS 3.0 deployments is maintained.
RestKit seeks to ease this burden on the developer by providing simple, transparent support for background tasks during the request cycle. Let’s take a look at some code:
– (void)backgroundUpload {
RKRequest* request = [[RKClient sharedClient] post:@”somewhere” delegate:self];
request.backgroundPolicy = RKRequestBackgroundPolicyNone; // Take no action with regard to backgrounding
request.backgroundPolicy = RKRequestBackgroundPolicyCancel; // If the app switches to the background, cancel the request
request.backgroundPolicy = RKRequestBackgroundPolicyContinue; // Continue the request in the background
request.backgroundPolicy = RKRequestBackgroundPolicyRequeue; // Cancel the request and place it back on the queue for next activation
}
The default policy is RKRequestBackgroundPolicyNone. Once you have set your policy and sent your request, RestKit handles the rest — switching in and out of the app will cause the appropriate action to happen.
**Example Code** – See [RKBackgroundRequestExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKBackgroundRequestExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
## Advanced Object Mapping
In part one of our series, we introduced the concept of Object Mapping — the RestKit process for converting JSON payloads into local domain objects. In its most simple form, Object Mapping reduces the tedium associated with parsing simple fields out of a dictionary and assigning them to a target object. But that’s not the end of the story for the object mapper.
RestKit also provides support for mapping hierarchies of objects expressed through relationships. This is a powerful feature for importing a large amount of data via a single HTTP request. In this section we’ll explore relationship mapping in detail and look at how RestKit supports non-idiomatic JSON structures via key-value coding.
### Dealing with Alternate JSON Structures
Most of the object mapping examples we have examined so far have performed simple mappings from one field to another (i.e. created_at becomes createdAt). If you have complete control over the JSON output of the backend system or are exactly modeling the server side output, this may be all that you ever need to do. But sometimes the realities of the backend system we need to integrate with do not fit so neatly with RestKit’s view of the world. If your target JSON contains nested data that you wish to access without decomposing the structures into multiple object types, you will need to leverage the power of key-value coding in your mappings.
Key-value coding is a mechanism for accessing data indirectly in Cocoa by use of a string containing property names, rather than invoking accessor methods or directly accessing instance variables. Key-value coding is one of the most important patterns in Cocoa and is the foundation of RestKit’s object mapping system. When RestKit encounters a data payload it knows how to handle, the payload is handed off to the parser for evaluation. The parser then evaluates the data and returns a key-value coding compliant representation of the data in the form of arrays, dictionaries, and basic types. From here, the object mapper begins analyzing the representation and using key-value accessors to retrieve data and assign it to the target object instance. Every time you register an element to class mapping or define an element to property mapping, you are providing a Key-value coding compliant key path to the mapper. This is an important point — you have the full power of the key-value pattern at your disposal. For example, you can traverse the object graph via dot notation syntax and utilize collection operators to perform actions on collections within your payload.
Let’s take a look at some code to get a better understanding of how key-value coding works within RestKit. Consider the following JSON structure for a simplified bank account application:
{
“id”: 1234,
“name”: “Personal Checking”,
“balance”: 5013.26,
“transactions”: [
{“id”: 1, “payee”: “Joe Blow”, “amount”: 50.16},
{“id”: 2, “payee”: “Grocery Store”, “amount”: 200.15},
{“id”: 3, “payee”: “John Doe”, “amount”: 325.00},
{“id”: 4, “payee”: “Grocery Store”, “amount”: 25.15}]
}
We are going to use key-value coding to access some information within the payload: the number of transactions, the average amount of the transactions, and the distinct group of payees in the transactions list. Here is our model:
@interface SimpleAccount : RKObject {
NSNumber* _accountID;
NSString* _name;
NSNumber* _balance;
NSNumber* _transactionsCount;
NSNumber* _averageTransactionAmount;
NSArray* _distinctPayees;
}
@property (nonatomic, retain) NSNumber* accountID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* balance;
@property (nonatomic, retain) NSNumber* transactionsCount;
@property (nonatomic, retain) NSNumber* averageTransactionAmount;
@property (nonatomic, retain) NSArray* distinctPayees;
@end
@implementation SimpleAccount
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”id”, @”accountID”,
@”name”, @”name”,
@”balance”, @”balance”,
@”transactions.@count”, @”transactionsCount”,
@””, @”averageTransactionAmount”,
@””, @”distinctPayees”,
nil];
}
@end
// — snip —
– (void)workWithKVC {
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/accounts.json” objectClass:[SimpleAccount class] delegate:self];
}
– (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
SimpleAccount* account = [objects objectAtIndex:0];
// Will output “The count is 4″
NSLog(@”The count is %@”, [account transactionsCount]);
// Will output “The average transaction amount is 150.115″
NSLog(@”The average transaction amount is %@”, [account averageTransactionAmount]);
// Will output “The distinct list of payees is: Joe Blow, Grocery Store, John Doe”
NSLog(@”The distinct list of payees is: %@”, [[account distinctPayees] componentsJoinedByString:@”, “]);
}
Now things are getting interesting. Note the new syntax utilized after the balance mapping is defined. We have used key-value coding to traverse down to the transactions array and perform operations on the data. From here, we see the use of several Key-value collection operators. These operators are provided to us by Cocoa and detailed in the “Key-Value Coding Programming Guide” available in the Xcode documentation. The key lesson here is to remember that the object mapper is built with key-value coding in mind and there is additional firepower available beyond simple one-to-one mappings.
Taking advantage of key-value coding in your mappings becomes very useful when working with large, complex JSON payloads where you only care about a subset of the data. But sometimes we actually do care about all that extra information — we just wish it was available in a more accessible format. In these circumstances we can instead turn to the use of relationship modeling to help RestKit transform a big data payload into an object graph.
**Example Code** – See [RKKeyValueMappingExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKKeyValueMappingExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
### Modeling Relationships
Relationship modeling is expressed via the ___elementToRelationshipMappings___ method on the RKObjectMappable protocol. This method instructs the mapper to take a nested JSON dictionary, perform mapping operations, and assign the result object (or objects) to the property with the given name. This is process is repeated for each mapping operation, allowing object graphs of arbitrary depth to be constructed.
To understand how this works, let’s take a look at an example. We are going to walk through the implementation of a Task List data model to illustrate the principles of relationship modeling. The task list example code is contained within the RKRelationshipMappingExample code in the RKCatalog application. Within RKRelationshipMappingExample, there are three data models that are related to one another: Users, Projects, and Tasks. Users are people working within the system. Projects contain a discrete set of steps that work toward a concrete goal that can be completed. Tasks represent each of these concrete steps within a Project. The relationships between them are:
* User has many Projects
* Each Project belongs to a single User
* Each Task belongs to a single Project
* Each Task can be assigned to a single User
The data models can be found in the Code/Models directory of the sample application.
Our application is very simple from a user interface standpoint. We have a single table view that shows all the Projects in the system and the name of the User who created the Project. Clicking on the Project pushes a secondary table view into view that shows all the Tasks contained in the Project. Rather than making multiple requests to individual resource collections to build the view, we are going to request the entire object graph from a single resource path ‘/task_list’. The JSON returned by the resource path looks like:
[{“project”: {
“id”: 123,
“name”: “Produce RestKit Sample Code”,
“description”: “We need more sample code!”,
“user”: {
“id”: 1,
“name”: “Blake Watters”,
“email”: “”
},
“tasks”: [
{“id”: 1, “name”: “Identify samples to write”, “assigned_user_id”: 1},
{“id”: 2, “name”: “Write the code”, “assigned_user_id”: 1},
{“id”: 3, “name”: “Push to Github”, “assigned_user_id”: 1},
{“id”: 4, “name”: “Update the mailing list”, “assigned_user_id”: 1}
]
}},
{“project”: {
“id”: 456,
“name”: “Document Object Mapper”,
“description”: “The object mapper could really use some docs!”,
“user”: {
“id”: 2,
“name”: “Jeremy Ellison”,
“email”: “”
},
“tasks”: [
{“id”: 5, “name”: “Mark up methods with Doxygen markup”, “assigned_user_id”: 2},
{“id”: 6, “name”: “Generate docs and review formatting”, “assigned_user_id”: 2},
{“id”: 7, “name”: “Review docs for accuracy and completeness”, “assigned_user_id”: 1},
{“id”: 8, “name”: “Publish to Github”, “assigned_user_id”: 2}
]
}},
{“project”: {
“id”: 789,
“name”: “Wash the Cat”,
“description”: “Mr. Fluffy is looking like Mr. Scruffy! Time for a bath!”,
“user”: {
“id”: 3,
“name”: “Rachit Shukla”,
“email”: “”
},
“tasks”: [
{“id”: 9, “name”: “Place cat in bathtub”, “assigned_user_id”: 3},
{“id”: 10, “name”: “Run water”, “assigned_user_id”: 3},
{“id”: 11, “name”: “Try not to get scratched”, “assigned_user_id”: 3}
]
}}]
This JSON collection is oriented around an array of Project models, with nested relationship structures. Let’s look at the implementation of our Project class:
@interface Project : RKObject {
NSNumber* _projectID;
NSString* _name;
NSString* _description;
User* _user;
NSArray* _tasks;
}
@property (nonatomic, retain) NSNumber* projectID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* description;
@property (nonatomic, retain) User* user;
@property (nonatomic, retain) NSArray* tasks;
@end
@implementation Project
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”id”, @”projectID”,
@”name”, @”name”,
@”description”, @”description”,
nil];
}
+ (NSDictionary*)elementToRelationshipMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”user”, @”user”,
@”tasks”, @”tasks”,
nil];
}
@end
Here we see the new invocation to elementToRelationshipMappings. If you glance back at the JSON structure, you can see that the declaration is instructing the object mapper to take the data contained in ‘user’ and ‘tasks’ sub-dictionaries, map them into objects, and assign the User and array of Task objects to the Project. When all of this has been completed, the object mapper will return the results and the complete object graph will be sent to your object loader delegate for processing.
**Example Code** – See [RKRelationshipMappingExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKRelationshipMappingExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
## Persistence with Core Data
**NOTE** – It is assumed for the purposes of this tutorial that the reader is familiar with Core Data.
Perhaps the most powerful weapon in RestKit’s arsenal is the seamless integration with Apple’s Core Data technology. Core Data provides a queryable, object persistence framework that is available on OS X and iOS. Building on the foundation of object mapping, RestKit enables the developer to create a persistent mirror of data contained within a remote backend system with very little code. There are a lot of moving pieces involved in providing such a high level of abstraction, so let’s meet the key players before diving into the details:
* **RKManagedObjectStore** – The object store wraps the initialization and configuration of internal Core Data classes including NSManagedObjectModel, NSPersistentStoreCoordinator, and NSManagedObjectContext. The object store is also responsible for managing object contexts for each thread and managing changes between threads. In general, the object store seeks to remove as much boilerplate Core Data code as possible from the main application.
* **RKManagedObject** – The superclass of all RestKit persistent objects. RKManagedObject inherits from NSManagedObject and extends the API with a number of helpful methods. This is an RKObjectMappable class and is configured for mapping in the same way as transient RKObject instances.
* **RKManagedObjectLoader** – When Core Data support has been linked into your application, this descendant of
RKObjectLoader handles the processing of object load requests. It knows how to uniquely identify Core Data backed objects and hides the complexities of passing NSManagedObject’s across threads. Also responsible for deleting objects from the local store when a DELETE is processed successfully.
* **RKManagedObjectCache** – The object cache protocol defines a single method for mapping resource paths to a collection of fetch requests for pulling local copies of objects that ‘live’ at a given resource path. We’ll cover this in detail below.
* **RKManagedObjectSeeder** – The object seeder provides an interface for creating a SQLite database that is loaded with local copies of remote objects. This can be used to bootstrap a large local database so that no lengthy synchronization process is necessary when the app is first downloaded from the App Store. Seeding is covered in detail below as well.
It is worth noting that there is nothing special about RestKit’s utilization of Core Data. The framework uses standard API’s and streamlines common tasks. You can integrate RestKit into an existing Core Data backed application without much trouble. Once integrated, you can use all the familiar Core Data API’s — you don’t have to stick to what RestKit exposes via RKManagedObject.
### Getting Started with Core Data
Enabling persistent object mapping is a relatively straight-forward process. It differs from transient object mapping in only a few ways:
1. libRKCoreData.a must be linked into your target
1. Apple’s CoreData.framework must be linked to your target
1. A Data Model Resource must be added to your target and configured within Xcode
1. The RestKit Core Data headers must be imported via `#import
1. An instance of RKManagedObjectStore must be configured and assigned to the object manager
1. Persistent models inherit from RKManagedObject rather than RKObject
1. A Primary Key property must be defined on each persistent model by implementing the `primaryKeyProperty` method
1. Implementation for properties on managed objects are generated via @dynamic rather than @synthesize
Once these configuration changes have been completed, RestKit will load & map payloads into Core Data backed classes.
There are a couple of common gotchas and things to keep in mind when working with Core Data:
1. You can utilize a mix of persistent and transient models within the application — even within the same JSON payload. RestKit will determine if the target object is backed by Core Data at runtime and will
return managed and unmanaged objects as appropriate.
1. RestKit expects that each instance of an object be uniquely identifiable via a single primary key that is present in the payload. This allows the mapper to differentiate between new, updated and removed objects.
1. When configuring your Data Model resource, care must be taken to ensure that the destination class is set to your desired model class. It defaults to NSManagedObject and must be updated appropriately. Failure to do this will result in exceptions from within the mapper when RestKit methods are invoked on an instance of NSManagedObject.
1. Use of threading in Core Data requires some special care. You cannot safely pass managed object instances across thread boundaries. They must be serialized to NSManagedObjectID and handed off between threads and then refetched from the managed object context. RKObjectLoader performs JSON parsing and object mapping on background threads and handles the thread jumping & object fetching for you. But you must take care if you introduce threading (including the use of performSelector:withDelay:) in your application code.
1. Apple recommends utilizing one managed object context instance per thread. When you retrieve a managed object context from RKManagedObjectStore, a new instance is created and stored onto thread local storage if the calling thread is not the main thread. You don’t need to worry about managing the life-cycle of the managed object contexts or merging changes — the object store observes these thread-local contexts and handles merging changes back into the main object context.
1. RestKit makes some blanket assumptions about how you are using Core Data that may not be appropriate for your application. This includes the merge policy used on object contexts, the options provided during initialization of the persistent store coordinator, etc. If you need more flexibility than is provided out of the box, reach out to the team and we’ll help loosen up these assumptions.
1. RestKit assumes that you use an entity with the same name as your model class in the data model.
1. There is not currently any framework level help for working with store migrations.
For help getting started with Core Data, please refer to the RKTwitter and RKTwitterCoreData projects in the Examples/ directory of the RestKit distribution. These projects provide identical implementations of a simple modeling of the Twitter timeline except that one is persistently backed by Core Data.
### Working with Core Data
Now that we have a grounding in the basic requirements for adding Core Data to a RestKit project, let’s take a look at some code to help us make things happen. All the code in this section is contained in the Examples/RKCoreDataExamples project for reference. Please pop the project open and follow along as we work through the examples.
First, we need to actually get RestKit and Core Data initialized. Open RKCDAppDelegate.m and note the following snippets of code:
// Import RestKit’s Core Data support
#import
RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@”http://restkit.org”];
manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@”RKCoreDataExamples.sqlite”];
What we have done here is instantiated an instance of the object manager and an instance of the managed object store. Within the internals of RKManagedObject, an NSManagedObjectModel and NSPersistentStoreCoordinator has been created for you. A persistent store file is created or reopened for you within the application’s documents directory and is configured to use SQLite as the backing technology. From here you have a working Core Data environment ready to go.
Now let’s take a look at the rather anemic model in Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.m:
@implementation Article
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”id”, @”articleID”,
@”title”, @”title”,
@”body”, @”body”,
nil];
}
+ (NSString*)primaryKeyProperty {
return @”articleID”;
}
@end
Here we see the familiar elementToPropertyMappings method from RKObjectMappable. The only thing new here is the implementation of a method indicating the primary key. This allows the object mapper to know that when working with instances of Article, it should consult the `articleID` property to obtain the primary key value for the instance. This allows RestKit to update the properties for this object no matter what resource path it is loaded from.
Now let’s explore some of the API’s exposed via RKManagedObject. Loading all objects of a given type is trivial:
– (void)loadAllObjects {
NSArray* objects = [Article allObjects];
NSLog(@”We loaded %d objects”, [objects count]);
}
Here we are retrieving all the objects for a given class from Core Data. This wraps the initialization, configuration and execution of a fetch request targeting the entity for our class. We can also configure our own fetch requests or utilize a number of helper methods to quickly perform common tasks:
– (void)funWithFetchRequests {
// Grab a fetch request configured to target the Article entity
NSFetchRequest* fetchRequest = [Article fetchRequest];
NSLog(@”My fetch request is: %@”, fetchRequest);
// Configure a fetch request to sort the results by title
NSFetchRequest* sortedRequest = [Article fetchRequest];
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@”title” ascending:YES];
[sortedRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSArray* sortedObjects = [Article objectsWithFetchRequest:fetchRequest];
NSLog(@”Here are the objects sorted: %@”, sortedObjects);
// Fetch an object by primary key
Article* firstArticle = [Article objectWithPrimaryKeyValue:[NSNumber numberWithInt:1]];
NSLog(@”This is the Article with ID 1: %@”, firstArticle);
// Find Articles where the body contains the word ‘something’ case insensitively
NSPredicate* predicate = [NSPredicate predicateWithFormat:@”body CONTAINS[c] %@”, @”something”];
NSArray* matches = [Article objectsWithPredicate:predicate];
NSLog(@”Found the following Articles that match: %@”, matches);
}
All of these methods are defined on RKManagedObject and provide short-cuts for features provided directly by Core Data. You can certainly configure your own fetch request entirely:
– (NSFetchRequest*)constructMyOwnFetchRequest {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [Article entity]; // The entity is available via RKManagedObject helper method…
[fetchRequest setEntity:entity];
return fetchRequest;
}
These Core Data helpers methods are used to drive a simple table view in the RKCoreDataExample in RKCatalog.
**Example Code** – See [RKCoreDataExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKCoreDataExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
### Automagic Relationship Management
One of nicest benefits of using Core Data with RestKit is that you wind up with a nicely hydrated object graph that let’s you traverse object relationships naturally. Relationship population is handled through the use of the `elementToRelationshipMappings` method we introduced in the previous section on modeling relationships. Recall that `elementToRelationshipMappings` instructs
the mapper to look for associated objects nested as a sub-dictionary within the JSON payload. But this can present a problem for a Core Data backed app — if you do not return all the relationships you have modeled within your payload, the graph can become stale and out of sync with the server. And not to mention that returning all relationships is often incorrect from an API design or performance perspective. So what are we to do?
RestKit solves this problem by introducing a new mapper configuration directive specific to Core Data objects: `relationshipToPrimaryKeyPropertyMappings`. The relationship to primary key mappings definition instructs the mapper to connect a Core Data relationship by using the value stored in another property to lookup the target object. This is easily understood by returning to the Task List data model we explored earlier. Recall that the JSON for an individual task looked like this:
{“id”: 5, “name”: “Place cat in bathtub”, “assigned_user_id”: 3}
Note the `assigned_user_id` element in the payload — this is the primary key value for the User object that the Task has been assigned to. Let’s look at the code:
@interface Task : RKManagedObject {
}
@property (nonatomic, retain) NSNumber* taskID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* assignedUserID;
@property (nonatomic, retain) User* assignedUser;
@end
@implementation Task
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”id”, @”taskID”,
@”name”, @”name”,
@”assigned_user_id”, @”assignedUserID”,
nil];
}
+ (NSDictionary*)relationshipToPrimaryKeyPropertyMappings {
return [NSDictionary dictionaryWithObject:@”assignedUserID” forKey:@”assignedUser”];
}
@end
Note the definition of `relationshipToPrimaryKeyPropertyMappings` — we have informed the mapper that the `assignedUserID` property contains the value of the primary key for the `assignedUser` relationship. When the mapper sees this, it will reflect on the relationship to determine it’s type (in this case, a User) and assign `object.user = User.findByPrimaryKeyValue(object.assignedUserID)`. The target object must exist within the local data store or the relationship will be set to nil.
**Example Code** – See [RKRelationshipMappingExample](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog/Examples/RKRelationshipMappingExample) in [RKCatalog](https://github.com/twotoasters/RestKit/blob/master/Examples/RKCatalog)
### Going Offline: Using the Object Cache
A primary use case for RestKit’s Core Data integration is to provide offline access to remote content. In fact it was from this need that RestKit was born — when development began on GateGuru (an excellent, essential app for the iPhone wielding airline traveler) a primary requirement was the ability to access information at 30,000 feet. What we really wanted was a common programming interface that would work regardless of online or offline status — if we have network connectivity, ping the remote server and give me the results, otherwise hit the cache and give me the most recent local results available. Because we designed our web services RESTfully, we could easily construct URL’s that would access the data for a particular airport, terminal, etc. We realized that we could reach our API nirvana by utilizing the resource path we load remote objects for as a key into our persistent store. This is precisely what the `RKManagedObjectCache` protocol allows you to do:
/**
* Must return an array containing NSFetchRequests for use in retrieving locally
* cached objects associated with a given request resourcePath.
*/
– (NSArray*)fetchRequestsForResourcePath:(NSString*)resourcePath;
To utilize the object cache, you need to provide an implementation of `RKManagedObjectCache` and assign it to the managed object store. The implementation of the method needs to parse the resource path and construct one or more fetch requests that can be used to retrieve objects that ‘live’ at that resource path. For example, in an app like GateGuru that has a collection of airport objects, your implementation might look something like this:
@interface MyObjectCache : NSObject
}
@end
@implementation MyObjectCache
– (NSArray*)fetchRequestsForResourcePath:(NSString*)resourcePath {
if ([resourcePath isEqualToString:@”/airports”]) {
NSFetchRequest* fetchRequest = [Airport fetchRequest]; // A fetch request with an entity set, but nothing else fetches all objects
return [NSArray arrayWithObject:fetchRequest];
}
return nil;
}
@end
MyObjectCache* cache = [[MyObjectCache alloc] init];
[RKObjectManager sharedManager].objectStore.managedObjectCache = cache;
[cache release];
An array of fetch requests is returned to support the case where your remote endpoint returns objects of more than one type — Core Data fetch requests can only target a single entity. Once you have provided an implementation and covered all your resource paths, you can retrieve the locally cached objects for a resource path from the object store:
NSArray* objects = [[RKObjectManager sharedManager].objectStore objectsForResourcePath:@”/airports”];
The object cache is used extensively within the Three20 integration layer we will discuss in more detail below. In summary, if you are using Three20 in your application RestKit ships with an object cache aware implementation of TTModel that can be used to populate a table with data from an object loader or the cache.
### Handling Remote Object Deletion
In addition to providing the basis for offline support, the object cache provides another important feature: intelligent handling of server-side object deletion. If you have provided an implementation of the object cache in your application, RestKit will prune objects that currently exist in the local store but have disappeared from the remote payload for a cached resource path. If your application has many resource paths that can load the same objects, it is important that you handle each path and return fetch requests covering all the objects.
If you are not using the object cache, you must manually handle object server-side object deletion by some other means.
### Database Seeding
In a Core Data backed application, it can be highly desirable to ship your application to the App Store with content already available in the local store. RestKit includes a simple object seeding implementation for this purpose via the `RKObjectSeeder` class. `RKObjectSeeder` provides an interface for opening one or more JSON files stored in the local bundle, processing them with the mapper, and then outputting instructions for how to obtain the seed database for use in your application. The seeding process typically looks like this:
1. Generate a dump file for each of your persistent object types from your backend system in JSON format.
1. Duplicate your existing application target and name the new target “Generate Seed Database”.
1. View the Build Settings for your target and find the GCC – Preprocessing section.
1. In the section named “Preprocessor Macros”, add new preprocessor macro: `RESTKIT_GENERATE_SEED_DB`. This value will be defined when we build and run the seeder target.
1. Add your JSON dump files to the “Generate Seed Database” target and ensure they are copied into the application bundle.
1. Update your application delegate to check for `RESTKIT_GENERATE_SEED_DB` and instantiate an instance of `RKObjectSeeder`.
1. Initialize an instance of `RKObjectSeeder` with your fully configured instance of `RKObjectManager`
1. Invoke the appropriate methods on the `RKObjectSeeder` instance for each of your JSON dump files.
1. When finished, invoke the `finalizeSeedingAndExit` method on the `RKObjectSeeder` instance.
The seeder is designed to be run in the Simulator on your Mac. When you invoke `finalizeSeedingAndExit`, the library will log details out to the console about where you can obtain the SQLite seed database. Once you have obtained a copy of the seed database, you add it to your project as a resource to copy into the app bundle. Once you have added the seed database to your application, you simply modify your initialization of RKManagedObjectStore to indicate that you have a seed database to start with rather than a blank slate.
Let’s take a look at some example code, taken from the RKTwitterCoreData example, that highlights how to work with the seeder:
// Database seeding is configured as a copied target of the main application. There are only two differences
// between the main application target and the ‘Generate Seed Database’ target:
// 1) RESTKIT_GENERATE_SEED_DB is defined in the ‘Preprocessor Macros’ section of the build setting for the target
// This is what triggers the conditional compilation to cause the seed database to be built
// 2) Source JSON files are added to the ‘Generate Seed Database’ target to be copied into the bundle. This is required
// so that the object seeder can find the files when run in the simulator.
#ifdef RESTKIT_GENERATE_SEED_DB
RKManagedObjectSeeder* seeder = [RKManagedObjectSeeder objectSeederWithObjectManager:objectManager];
// Seed the database with instances of RKTStatus from a snapshot of the RestKit Twitter timeline
[seeder seedObjectsFromFile:@”restkit.json” toClass:[RKTStatus class] keyPath:nil];
// Seed the database with RKTUser objects. The class will be inferred via element registration
[seeder seedObjectsFromFiles:@”users.json”, nil];
// Finalize the seeding operation and output a helpful informational message
[seeder finalizeSeedingAndExit];
// NOTE: If all of your mapped objects use element -> class registration, you can perform seeding in one line of code:
// [RKManagedObjectSeeder generateSeedDatabaseWithObjectManager:objectManager fromFiles:@”users.json”, nil];
#endif
// Initialize object store
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@”RKTwitterData.sqlite” usingSeedDatabaseName:RKDefaultSeedDatabaseFileName managedObjectModel:nil];
## Integration Layers
It is briefly worth noting that RestKit ships with some integration layers to help developers work with some complementary technology. As of this writing, there are two such integration points available:
1. RKRailsRouter – A Router implementation aware of Ruby on Rails idioms
2. RKRequestTTModel – An implementation of the TTModel protocol for Three20 that allows RestKit object loaders to drive Three20 tables
### Ruby on Rails Support
The RKRailsRouter inherits from the RKDynamicRouter introduced in the first tutorial. The Rails router alters the default routing behavior in a couple of ways:
1. Allows for registration of server side model names for the purpose of nesting attributes before sending requests
2. Prevents any parameter data from being encoded into the request body for DELETE requests
The attribute nesting is understood simply with an example. Imagine that we have a server-side model called ‘Article’, with two attributes ‘title’ and ‘body’. We would configure the Rails router like so:
RKRailsRouter* router = [[RKRailsRouter alloc] init];
[router setModelName:@”article” forClass:[Article class]];
[router routeClass:[Article class] toResourcePath:@”/articles/(articleID)”];
[router routeClass:[Article class] toResourcePath:@”/articles” forMethod:RKRequestMethodPOST];
Article* article = [Article object];
article.title = @”This is the title”;
article.body = @”This is the body”;
[[RKObjectManager sharedManager] postObject:article delegate:self];
When the object is serialized for the POST request, RestKit will nest the attributes into a hash like so:
article[title]=This is the title&
article[body]=This is the body
This matches the format Rail’s controllers expect attributes to be delivered in. The changes to the DELETE payload are self-explanatory — Rails simply expects the params to be empty during DELETE requests and the Rails router abides.
### Three20 Support
At Two Toasters, the vast majority of our iOS applications are built on top of two frameworks: RestKit and Three20. We have found that Three20 greatly simplifies and streamlines a number of common patterns in our iOS applications (such as the support for URL based dispatch) and provides a rich library of UI components and helpers that make us happier, more productive programmers. And RestKit obviously makes working with data so much more pleasant. So it should come as little surprise that there integration points available between the two frameworks.
Integration between RestKit and Three20 takes the form of an implementation of the TTModel protocol. TTModel defines an interface for abstract data models to inform the Three20 user interface components of their status and provide them with data. TTModel is the basis for all Three20 table view controllers as well as a number of other components. RestKit ships with an optional `libRestKitThree20` target that provides an interface for driving Three20 table views off of a RestKit object loader via the `RKRequestTTModel` class. `RKRequestTTModel` allows us to handle all the modeling, parsing, and object mapping with RestKit and then plug our data model directly into Three20 for presentation. `RKRequestTTModel` also provides transparent offline support and periodic data refresh in our user interfaces. When you have used Core Data to back your data model and utilize `RKRequestTTModel` in your controllers, RestKit will automatically pull any objects from the cache that live at the resource path you are loading in the event you are offline. `RKRequestTTModel` can also be configured to hit the network only after a certain amount of time by configuring the `refreshRate` property.
In addition to `RKRequestTTModel`, a child class `RKRequestFilterableTTModel` is provided as well. `RKRequestFilterableTTModel` provides support for sorting and searching a collection of loaded objects and can be useful for providing client side filtering operations.
## Connecting the Dots
The Three20 support lies at the top of a large pyramid of technology and relies on nearly every part of the framework we have discussed so far. The amount of code necessary to see the full benefits of the framework at this level is daunting to include in the body of this text. A full-featured RestKit application leveraging Core Data, Ruby on Rails, and Three20 is available in the Examples/RKDiscussionBoardExample directory. Please take a close look at the Discussion Board example and join the RestKit mailing list. The community is quite active and more than happy to help new users.
## Conclusion
We hope that you have found learning about RestKit fun and rewarding. At this point we have reviewed the vast majority of framework and you should be prepared to utilize RestKit in your next RESTful iOS application. The framework is maturing quickly and iterating rapidly, so please be sure to join the mailing list or follow @RestKit on Twitter to keep up with the latest developments. Happy coding!
## Learning More
* RestKit: [http://restkit.org]()
* Github: [https://github.com/twotoasters/RestKit]()
* API Docs: [http://restkit.org/api/]()
* Google Group: [http://groups.google.com/group/restkit]()
* Brought to you by Two Toasters: [http://twotoasters.com/]()
blake@restkit.orgtransactions.@avg.amounttransactions.@distinctUnionOfObjects.payeeblake@twotoasters.comjeremy@twotoasters.comrachit@twotoasters.com
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Advanced RestKit/._Advanced_RestKit_Tutorial.md
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._MobileTuts Advanced RestKit
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/add_to_project
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._add_to_project
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/all_configurations
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._all_configurations
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/build_settings
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._build_settings
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/depedency
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._depedency
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/frameworks
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._frameworks
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/get_info
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._get_info
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/linking
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/images/._linking
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/._images
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/index.htmlRestKit is a powerful library that simplifies interacting with web services for iOS applications. In this article, written by RestKit creator and Two Toasters CTO Blake Watters, we will take a quick tour of RestKit’s feature set, get familiar with the core concepts presented by the library, and then explore some code samples to get a feel for what working with RestKit is really like.What is RestKit?RestKit is an Objective-C framework for iOS that aims to make interacting with RESTful web services simple, fast, and fun. It combines a clean, simple HTTP request/response API with a powerful object mapping system that reduces the amount of code you need to write to ‘get stuff done’. RestKit’s primary goal is to allow the developer to think more in terms of their application’s data model and worry less about the details of sending requests, parsing responses, and building representations of remote resources.What does RestKit provide?
A simple, high-level HTTP request/response system. RestKit ships with an HTTP client built on top of NSURLConnection and provides a library of helpful methods for inspecting MIME types and status codes. Submitting form data is as simple as providing a dictionary of parameters and a native params object is included for easily creating multi-part submissions. Simple support for the streaming upload of large files (i.e. videos) is also provided.Framework level support for switching servers & environments (e.g. development, production, staging). RestKit uses a base URL and resource paths rather than full URL’s to allow you to switch target servers quickly. Interpolating URL strings and constructing NSURL objects is a thing of the past.An object mapping system. RestKit provides a modeling layer for mapping processed data payloads into native Cocoa objects declaratively. This lets the application programmer stop worrying about parsing and simply ask the framework to asynchronously fetch a remote resource and call the delegate with the results. Object mapping is implemented using key-value coding, allowing for quick traversal of the parsed object graph. Reflection is used on the property types to allow for mapping from values that don’t have direct representations in the encoding format, such as mapping JSON timestamps encoded as a string to NSDate objects.Core Data support. Building on top of the object mapping layer, RestKit provides integration with Apple’s Core Data framework. This support allows RestKit to persist remotely loaded objects directly back into a local store, either as a fast local cache or a primary data store that is periodically synced with the cloud. RestKit can populate Core Data associations for you, allowing natural property based traversal of your data model. It also provides a nice API on top of the Core Data primitives that simplifies configuration and querying use cases.Database seeding. When the Core Data object store is used, you can seed a database from a collection of data files. This lets you submit your apps to the App Store with a database in the app bundle that is ready for immediate use.Pluggable parsing layer. RestKit currently supports JSON via the SBJSON and YAJL parsers. Parsing is implemented behind a simple interface to allow additional data formats to be handled transparently. Rails integration. RestKit was originally designed as an Objective-C answer to Active Resource. Rails has been used as the backend for a number of RestKit powered iOS apps and turn-key support is provided for interacting with a backend Rails application.Experimental Three20 integration. RestKit is often used alongside the Three20 framework. An optional module is included in the distribution that allows RestKit to interface with Three20 via the TTModel protocol.Getting Up and RunningRestKit is available as a downloadable binary package, as a versioned snapshot, or as a Git submodule if you wish to track mainline development. For users of the library uninterested in doing development, we recommend using the versioned binary packages for the simplicity of installation. If you wish to install as a submodule or build the library yourself, please refer to the documentation available on Github.You can install RestKit in a few easy steps:
Head to and download the latest version (v0.9.0 as of this writing).restkit.orgUnpack the archive wherever you like to keep libraries (the author recommends a Library subdirectory).Drag the RestKit.xcodeproj file to your Xcode project file. It will be added to the Groups & Files section in the left pane of the project. Select the appropriate targets and click ‘Add’ when the sheet appears.
Click on the entry for RestKit.xcodeproj in your project’s Groups & Files section. In the right hand pane, find the entries for libRestKitSupport.a, libRestKitObjectMapping.a, libRestKitNetwork.a, and libRestKitJSONParserYAJL.a and click the checkboxes on the far right underneath the silver target icon. This will link your project against RestKit. If you wish to use the Core Data support, click the checkbox next to libRestKitCoreData.a also. Your project should appear something like the following screenshot:
Find the target for your application in the Targets section of your project. Right click on your app’s target and select ‘Get Info’ from the menu to open the target Info inspector window.
You should be looking at the General tab of your target’s inspector. In the top Direct Dependencies section, click the plus button and add a direct dependency on the RestKit target.
Now look to the bottom of the General pane labeled Linked Libraries. Click the plus button to open the Frameworks selection sheet. Find and select the following frameworks and click ‘Add’:
CFNetwork.framework – Required for networking support.SystemConfiguration.framework – Required for detection of network availability.MobileCoreServices.framework – Required. Provides support for MIME type auto-detection for uploaded files.CoreData.framework – Required. Required for use of the Core Data backed persistent object store.
Switch to the ‘Build’ tab in your project inspector. Make sure that your Configuration pop-up menu reads All Configurations so that your changes will work for all build configurations. Find the Header Search Paths setting. Double click and add a new entry. When RestKit is compiled, it will copy all relevant headers to the appropriate location under the /Build directory within the RestKit checkout. You need to add a path to the /Build directory of RestKit, relative to your project file. For example, if you checked the submodule out to the ‘Libraries’ subdirectory of your project, your header path would be ‘Libraries/RestKit/Build’.
Now find the Other Linker Flags setting. Double click it and add entries for -all_load and -ObjC. Your setting should match the screenshot below.
Close out the inspector window.Congratulations, you are now done adding RestKit into your project!You now only need to add includes for the RestKit libraries at the appropriate places in your application. The relevant includes are:
#import
#import
Build the project to ensure everything is working correctly.
Once you have verified that you have RestKit linked into your project correctly, you are ready to begin using the library.Using RestKitRestKit is designed to make common tasks as straightforward and simple as possible. In this section we will run through many common tasks in the library and focus on code samples to help you get started with the library.Sending requests & processing responsesAll of RestKit’s higher level functionality is built on top of the network layer. The network layer’s primary responsibility is the construction and dispatch of requests and the processing of responses. Generally you will dispatch all requests through the RKClient class.RKClient is a web client object configured to talk to a particular web server. It is initialized with a base URL and allows you to set configuration that is common to the requests in your application, such as HTTP headers and authentication information. While you are free to initialize as many instances of RKClient as is appropriate for your application, there is a shared singleton instance that is globally available. This singleton instance is often configured in your app delegate’s applicationDidFinishLaunching:withOptions: method:- (void)applicationDidFinishLaunching:(UIApplication*)application withOptions:(NSDictionary*)options {
RKClient* client = [RKClient clientWithBaseURL:@”http://restkit.org”];
}
The first RKClient that is initialized is automatically configured as the singleton instance and becomes available via the sharedClient singleton method:NSLog(@”I am your RKClient singleton : %@”, [RKClient sharedClient]);
Now that you have a client configured, you can send and process HTTP requests through the client. RestKit makes this very easy for you and abstracts the low level details of NSURLConnection away from you. When making a request through the client, you supply the resource path on the remote web server that you wish to interact with. Since the most common action in an iOS application is making an asynchronous request to a remote web service, RestKit provides very straight-forward convenience methods for the HTTP verbs: GET, POST, PUT and DELETE. You only need to declare that your class implements the RKRequestDelegate protocol and then provide an implementation of the request:didLoadResponse: method. Let’s take a look at an example class that shows the basics:#import
// Here we declare that we implement the RKRequestDelegate protocol
// Check out RestKit/Network/RKRequest.h for additional delegate methods
// that are available.
@interface RKRequestExamples : NSObject
}
@end
@implementation RKRequestExamples
– (void)sendRequests {
// Perform a simple HTTP GET and call me back with the results
[[RKClient sharedClient] get:@”/foo.xml” delegate:self];
// Send a POST to a remote resource. The dictionary will be transparently
// converted into a URL encoded representation and sent along as the request body
NSDictionary* params = [NSDictionary dictionaryWithObject:@”RestKit” forKey:@”Sender”];
[[RKClient sharedClient] post:@”/other.json” params:params delegate:self];
// DELETE a remote resource from the server
[[RKClient client] delete:@”/missing_resource.txt” delegate:self];
}
– (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
if ([request isGET]) {
// Handling GET /foo.xml
if ([response isOK]) {
// Success! Let’s take a look at the data
NSLog(@”Retrieved XML: %@”, [response bodyAsString]);
}
} else if ([request isPOST]) {
// Handling POST /other.json
if ([response isJSON]) {
NSLog(@”Got a JSON response back from our POST!”);
}
} else if ([request isDELETE]) {
// Handling DELETE /missing_resource.txt
if ([response isNotFound]) {
NSLog(@”The resource path ‘%@’ was not found.”, [request resourcePath]);
}
}
}
@end
As you can see, the code is extremely succinct and readable. There are a number of helper methods available on RKRequest and RKResponse that make inspecting your request state very easy. Be sure to read the headers and get familiar with what’s available.An Introduction to Object MappingSending and receiving HTTP requests with such ease is great and all, but that’s just the tip of the iceberg. RestKit’s real power comes not from the network layer, but from the object mapping layer that sits on top of it. Object mapping is RestKit’s solution to simplifying and DRYing up the overly verbose work-flow of:
Sending a request to a remote web service.Getting back an XML or JSON response and parsing it.Taking the parsed response and assigning the values inside the payload to objects.Much as RKClient is your gateway to a simpler life with HTTP, RKObjectManager is your gateway to the world of object mapping. In fact, on projects where object mapping is used extensively you will initialize RKObjectManager instead of RKClient. Much as RKClient seeks to abstract away the gritty details of handling requests, RKObjectManager works hard to shield you from the complexities of transforming data payloads into objects.Modeling & Loading Remote ObjectsObject mapping requires that you provide a data model class to represent your remote objects. By implementing the RKObjectMappable protocol, you are configuring RestKit to map attributes within a retrieved payload to properties on your model class. The key to this process is the elementToPropertyMappings method, which defines a dictionary of key paths and property names. The key paths are key-value coding compliant strings for accessing data within a parsed document. The property name is simply the string name of a property on the class to assign the accessed data to. To illustrate these points, let’s imagine that our application has a lightweight contact concept containing a name, an e-mail address, and an identifier number. Let’s imagine that this record lives on our remote server at /contacts/1234. The JSON looks like this:{‘id’: 1234,
‘name’: ‘Blake Watters’,
‘company’: ‘Two Toasters’}
Let’s pull together an RKObject class to contain this data:@interface Contact : RKObject {
NSNumber* _identifier;
NSString* _name;
NSString* _company;
}
@property (nonatomic, retain) NSNumber* identifier;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* company;
@end
Now we just need to tell RestKit how to map data from the payload to our properties:@implementation Contact
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”id”, @”identifier”,
@”name”, @”name”,
@”company”, @”company”,
nil];
}
@end
We are now all set to load the data. To do this, we set up RKObjectManager and execute a GET on the record. RKObjectManager will construct and configure an asynchronous RKObjectLoader request for you and send it to the remote server for processing. Instead of implementing the low level RKRequestDelegate methods that deal with requests and responses, we will instead implement the RKObjectLoaderDelegate protocol and get called back with a collection of mapped objects or an error. Let’s take a look at this code:- (void)loadContact {
RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@”http://restkit.org”];
[manager loadObjectsAtResourcePath:@”/contacts/1″ objectClass:[Contact class] delegate:self]
}
// RKObjectLoaderDelegate methods
– (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
Contact* contact = [objects objectAtIndex:0];
NSLog(@”Loaded Contact ID #%@ -> Name: %@, Company: %@”, contact.id, contact.name, contact.company);
}
– (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSLog(@”Encountered an error: %@”, error)
}
As you can see, the entire process is very low ceremony and completely DRY.Setting Up RoutesLoading objects is only half the story. To really interact with a remote web service, you also need to be able to create, update, and delete remote object instances. A confounding factor in these interactions is often that the resource path that an object resides at is specific to each instance. Returning to the contacts example above, imagine that the entire world of Contacts is represented by the following pairs of HTTP verbs and resource paths:
GET /contacts returns all Contacts as a collectionPOST /contacts creates a new ContactGET /contacts/
// Define a default resource path for all unspecified HTTP verbs
[router routeClass:[Contact class] toResourcePath:@”/contacts/(identifier)”];
[router routeClass:[Contact class] toResourcePath:@”/contacts” forMethod:RKRequestMethodPOST];
[RKObjectManager sharedManager].router = router;
The notable piece in the configuration is the use of parentheses in the resource path for the default route. Within the parentheses you can specify any instance method on the class being configured and when RestKit generates a resource path for that object, the value returned will be interpolated into the string.In our example above, we can see that GET, PUT, and DELETE operations will generate /contacts/1234 while POST will generate /contacts.Manipulating Remote ObjectsNow that we have configured routing, we can manipulate remote object representations at a very high level. Let’s take a look at some more code and then we’ll walk through the process:- (void)createObject {
Contact* joeBlow = [Contact object];
joeBlow.name = @”Joe Blow”;
joeBlow.company = @”Two Toasters”;
// POST to /contacts
[[RKObjectManager sharedManager] postObject:joeBlow delegate:self];
}
– (void)updateObject {
Contact* blake = [Contact object];
blake.identifier = [NSNumber numberWithInt:1];
blake.name = @”Blake Watters”;
blake.company = @”RestKit”;
// PUT to /contacts/1
[[RKObjectManager sharedManager] putObject:blake delegate:self];
}
– (void)deleteObject {
Contact* blake = [Contact object];
blake.identififer = [NSNumber numberWithInt:1];
// DELETE to /contacts/1
[[RKObjectManager sharedManager] deleteObject:blake delegate:self];
}
What we have done here is used the combined power of object mapping and routing to perform very high level manipulations on local and remote objects. Behind the scenes, RestKit has identified the appropriate resource path for your operation, created and dispatched an asynchronous request, and processed the response for you.Review of Key Concepts
Client and Object Manager. There are two primary entry points for working with RestKit in your application: RKClient and RKObjectManager. RKClient is the primary entry point when you are working with the Network layer of RestKit and concerns itself with the low level details of building and sending requests. RKObjectManager operates at a higher level of abstraction in the Object Mapping layer and concerns itself with the loading and manipulation of objects that represent remote resources. Depending on what you are trying to accomplish with RestKit, you will be working extensively with one (or both!) of these classes.
Base URL’s and Resource Paths. RestKit uses the concepts of the ‘Base URL’ and ‘Resource Path’ to coordinate access to remote object representations. The Base URL is simply the common part of all URL’s to your remote application and is used to initialize instances of the RKClient and RKObjectManager classes. A resource path is simply the path (or subpath) portion of the full URL to an HTTP resource. Given an RKClient object initialized with ‘http://restkit.org’ and a request to GET the content at resource path ‘/foo/bar.json’, RestKit will create and send a request to ‘http://restkit.org/foo/bar.json’. This allows you to easily support development, staging, and production environments in your applications by conditionally compiling different base URL’s. Most of the time you will think entirely in terms of resource paths once you have moved beyond initializing the library.Example:RKClient* client = [RKClient clientWithBaseURL:@”http:///restkit.org”];
[client get:@”/foo/bar.json” delegate:self];
Object Mapping. When you use RestKit to model remote resources into local objects, you will be interacting with the object mapping layer. Object mapping is the process of taking a remote JSON (or other wire format) payload, parsing it into a graph of key value coding compliant NSObject’s, and applying a set of mapping rules to transform values inside the parsed object graph into attributes on a model object. RestKit supports advanced mapping beyond what you get from simply decoding a payload, such as parsing a string containing a date into an NSDate property and accessing data via key-value coding operators. Object mapping rules are configured by implementing the elementToPropertyMappings method of the RKObjectMappable protocol:Example:@implementation MyObject
// Map full_name and street_adddress in JSON payload to
// local properties fullName and streetAddress
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@”full_name”, @”fullName”,
@”street_address”, @”streetAddress”,
nil];
}
@end
Routing. The routing system is responsible for generating resource paths from local object instances. This allows you to manipulate and synchronize your local objects with their remote representations without ever seeing a URL. The routing system is extensible by providing your own implementation of the RKRouter protocol, but RestKit ships with a powerful implementation in the RKDynamicRouter class. The dynamic router allows you to encoded property names inside of simple strings to generate complex resource paths at run time. This is most easily understood through some examples:Example:RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@”http://restkit.org”];
RKDynamicRouter* router = [[RKDynamicRouter new] autorelease];
manager.router = router;
// Send POST requests for instances of Article to ‘/articles’
[router routeClass:[Article class] toResourcePath:@”/articles” forMethod:RKRequestMethodPOST];
// Configure a default resource path for Articles. Will send GET, PUT, and DELETE requests to ‘/articles/XXXX’
// articleID is a property on the Article class
[router routeClass:[Article class] toResourcePath:@”/articles/(articleID)”];
// Configure Comments on the Article. Send POST of Comment objects to ‘/articles/1234/comments’
// where the Comment has a relationship to an Article.
[router routeClass:[Comment class] toResourcePath:@”/articles/(article.articleID)/comments” forMethod:RKRequestMethodPOST];
// Let’s create an Article
Article* article = [Article object];
article.title = @”Foo”;
article.body = @”This is the body”;
// Send a POST to /articles to create the remote instance
[[RKObjectManager sharedManager] postObject:article delegate:self];
// Now let’s create a Comment on the Article
Comment* comment = [Comment object];
comment.article = article;
comment.body = @”This is the comment!”;
// Given Article has an ID of 1234, will send a POST to /articles/1234/comments to create the Comment
[[RKObjectManager sharedManager] postObject:comment delegate:self];
// Delete the Article. DELETE to /articles/1234
[[RKObjectManager sharedManager] deleteObject:comment delegate:self];
Conclusion
This article has explored the basics of working with RestKit. You should now have a firm understanding of the core concepts and feel well prepared to start building your next RESTful iOS app. As we mentioned in the introductory section, RestKit also includes some advanced features which were not explored in this article. We will fully explore the advanced portions of the library including Core Data in our upcoming advanced tutorial. Until then, you can learn more through the example code included with the library and by exploring the resources below.Learning More
RestKit.org
Github Project Page
Official Google Group
Two Toasters
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/MobileTuts Introduction to RestKit/._index.html
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._MobileTuts Introduction to RestKit
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Object Mapping.md# Object Mapping
This document details the design of object mapping in RestKit as of version 0.9.3
## Object Mapping Overview
RestKit’s key differentiating feature from other HTTP toolkits in the iOS space is the
tightly integrated support for object mapping. Object mapping is the process of taking a representation
of data in one format and transforming it into another form. This mechanism is used extensively within
RestKit to streamline the serialization and deserialization of resources exchanged with a remote
backend application server via HTTP. Object mapping operations are performed when you load a remote
resource via an instance of `RKObjectManager` and when a local object is sent to the backend for processing.
### Key-Value Coding
Object mapping is built on top of the key-value coding pattern that permeates the Cocoa frameworks. KVC is a mechanism
for expressing read and write operations on an object graph in terms of simple strings. RestKit relies on KVC to identify
mappable content within a parsed response body and dynamically update the attributes and relationships of your local domain
objects with the appropriate content. An understanding of key-value coding is essential to fully understand and leverage the
capabilities of the RestKit framework. Before diving into the details of RestKit’s object mapping system, be sure to get a firm
grasp on KVC.
## Object Mapping by Example
To understand the object mapping subsystem of RestKit, let’s consider an example. Imagine that we are building an app
that loads a collection of news articles from a remote system. Each article has a title, a body,
an author, and a publication date. We expect our JSON to come back something like this:
“`json
{ “articles”: [
{ “title”: “RestKit Object Mapping Intro”,
“body”: “This article details how to use RestKit object mapping…”,
“author”: “Blake Watters”,
“publication_date”: “7/4/2011”
},
{ “title”: “RestKit 1.0 Released”,
“body”: “RestKit 1.0 has been released to much fanfare across the galaxy…”,
“author”: “Blake Watters”,
“publication_date”: “9/4/2011″
}]
}
“`
Within our iOS application, we are going to have a table view showing the same information. We have an Objective-C
class to hold this data that looks like the following:
“`objc
@interface Article : NSObject
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* body;
@property (nonatomic, retain) NSString* author;
@property (nonatomic, retain) NSDate* publicationDate;
@end
“`
Our goal is to leverage RestKit’s object mapping capabilities to turn the above JSON into an array of Article instances. To make
this happen, we must first become familiar with a few RestKit classes:
1. **RKObjectMapping**: An object mapping defines the rules for transforming a parsed data payload into a local domain object.
Each object mapping is composed of a collection of attribute and relationship mappings that define how to transform key paths in the
source data into properties on the local object.
1. **RKObjectMappingProvider**: The object mapping provider defines the rules for what key paths in a loaded set of data correspond to
an object mapping.
Let’s take a look at how we would configure RestKit to perform this operation:
“`objc
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@”title” toAttribute:@”title”];
[articleMapping mapKeyPath:@”body” toAttribute:@”body”];
[articleMapping mapKeyPath:@”author” toAttribute:@”author”];
[articleMapping mapKeyPath:@”publication_date” toAttribute:@”publicationDate”];
[[RKObjectManager sharedManager].mappingProvider setMapping:articleMapping forKeyPath:@”articles”];
“`
Let’s consider what we’ve done here. In the first line, we created an instance of `RKObjectMapping` defining a mapping
for the `Article` class. We then configured the mapping to define rules for transforming data within the parsed payload to attributes
on an instance of `Article`. Finally, we instructed the mapping provider to use `articleMapping` whenever it encounters data at the `@”articles”`
key path.
Now that we have configured our object mapping, we can load this collection:
“`objc
– (void)loadArticles {
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/articles” delegate:self];
}
– (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
RKLogInfo(@”Load collection of Articles: %@”, objects);
}
“`
Recall the importance of key-value coding to the process. When we loaded the example JSON above via RestKit with the articleMapping configuration in
place, the following things happened:
1. RestKit created an instance of `RKObjectMapper` with the parsed JSON payload and the mapping provider. The mapper is responsible for figuring
out how to map an opaque collection of potentially mappable data.
1. The `RKObjectMapper` instance asked the mapping provider for a list of mappable key paths. Each key path was evaluated against the parsed
payload using valueForKeyPath:. Since we configured a mapping for the `@”articles”` key path, RestKit invoked `valueForKeyPath:@”articles”` on the
parsed data and found the mappable data.
1. RestKit now knows that there is interesting data in the payload that needs to be mapped. `RKObjectMapper` notes that the mappable data is an array
and iterates over the collection, mapping each dictionary within the array in turn. An instance of RKObjectMappingOperation is created for each element
in the array. Each mapping operation targets one of dictionaries contained in the array returned from the `@”articles”` key path. For the example above, this
means that we would generate two object mapping operations:
“`json
// This dictionary will processed in one mapping operation
{ “title”: “RestKit Object Mapping Intro”,
“body”: “This article details how to use RestKit object mapping…”,
“author”: “Blake Watters”,
“publication_date”: “7/4/2011”
}
// This dictionary will be processed in another mapping operation
{ “title”: “RestKit 1.0 Released”,
“body”: “RestKit 1.0 has been released to much fanfare across the galaxy…”,
“author”: “Blake Watters”,
“publication_date”: “9/4/2011”
}
“`
1. Once the object mapping operation takes over, a new set of KVC key paths is examined. The attribute mappings we defined via the calls to
`mapKeyPath:toAttribute:` are now evaluated against the dictionary. RestKit will invoke `valueForKeyPath:@”title”`, `valueForKeyPath:@”body”`,
`valueForKeyPath:@”author”`, and `valueForKeyPath:@”publication_date”` against the dictionary to determine if there is any data available for
mapping. If any data is found, it will set the data on the target object by invoking `setValue:forKeyPath:`. In the above example, RestKit will
find the data for the title via `valueForKeyPath:@”title”` and then set the title attribute of our Article object to
“RestKit Object Mapping Intro” and “RestKit 1.0 Released”, respectively. This process is repeated for all the attributes and relationships
defined in the object mapping. It is worth noting that although the key paths are often symmetrical between the source and destination objects
(i.e. mapping a title to a title), they do not have to be and you can store your data in more logical or idiomatic names as appropriate (i.e.
we mapped `publication_date` to `publicationDate` so that it fits better with Cocoa naming conventions).
From this example, it should now be clear that object mapping can be thought of as a declarative, key-value coding chainsaw for your JSON/XML
data. We have declared that any time data is found underneath the `@”articles”` keyPath, it should be processed using the `articleMapping` and thus
transformed into one or more instances of the `Article` class. Once mappable data is found, we have declared that values existing at a given source
key path should be assigned to the target object at the destination key path. This is the fundamental trick of object mapping and all other features
are built upon this foundation.
### Parameters
GET query parameters should be added with the new NSString method appendQueryParameters. For example,
“`objc
– (void)loadArticlesContainingText:(NSString *)searchText {
NSDictionary *queryParams = [NSDictionary dictionaryWithObject:searchText forKey:@”q”];
NSString *resourcePath = [@”/articles” appendQueryParameters:queryParams];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath delegate:self];
}
“`
POST parameters can be provided by setting the RKObjectLoader’s params property:
“`objc
– (void)saveArticleWithAdditionalParams:(NSDictionary *)extraPOSTParams {
RKObjectLoader* loader = [objectManager sendObject:human delegate:responseLoader block:^(RKObjectLoader* loader) {
loader.method = RKRequestMethodPOST;
loader.resourcePath = @”/articles/create”;
loader.params = extraPOSTParams;
}];
}
“`
## Object Mapping Fundamentals
Now that we have established a foundation for the basics of object mapping, we can explore the remaining portions of the system. We’ll examine
various use-cases of object mapping in turn with brief discussion and code samples.
### Type Transformation
One of the notable features of object mapping is that it infers a great deal of information about your intentions by leveraging the dynamic
features of the Objective-C runtime. RestKit will examine the source and destination types of your attribute at mapping time and perform a
variety of type transformations for you. This feature eliminates a great deal of glue code that you would otherwise have to write if you
were assigning a parsed data structure to your object model manually. The following table enumerates a number of available transformations
from a source type to a destination type that are automatically applied when you define an attribute mapping:
| Source Type | Destination Type | Discussion |
|---|---|---|
| NSString | NSDate | NSString values are mapped to NSDate properties by applying the date format strings from the RKObjectMapping instance. |
| NSString | NSURL | NSString values are mapped to NSURL properties via
|
| NSString | NSDecimalNumber | NSString values are mapped to NSDecimalNumber properties via
|
| NSString | NSNumber | NSString values are mapped to NSNumber properties via
|
| NSString containing YES, NO, true, false, t, f | NSNumber | NSString values containing a known boolean string are mapped to NSNumber properties via
|
| NSSet | NSArray | NSSet values are mapped to NSArray properties via
|
| NSArray | NSSet | NSArray values are mapped to NSSet properties via
|
| NSNumber | NSDate | NSNumber values are mapped to NSDate properties via
|
| NSCFBoolean | NSString | Boolean literals true and false parsed from JSON are mapped to NSString properties as @"true" and @"false" |
| NSNull | Anything | NSNull entries (null in JSON) are mapped to nil for any destination property. |
| respondsToSelector:@selector(stringValue) | NSString | Any mappable value can be mapped to an NSString property if the object responds to the stringValue selector. This works for NSNumbers, etc. |
### Relationships
In addition to mapping simple attributes, RestKit is also capable of mapping arbitrarily complex object graphs. Relationship mappings are configured
very similarly to attribute mapping, but with one notable addition: they are initialized with an object mapping for the relationship. To understand this, let's
extend our previous articles JSON to contain some nested relationship data:
```json
{ "articles": [
{ "title": "RestKit Object Mapping Intro",
"body": "This article details how to use RestKit object mapping...",
"author": {
"name": "Blake Watters",
"email": ""
},
"publication_date": "7/4/2011"
}]
}
```
Notice that we have changed the structure of the "author" field. Rather than being a simple string, it now contains a nested dictionary. We want
to represent this nested dictionary as a new type in our object model -- the Author class. Let's pull together a data model for our author data:
```objc
@interface Author : NSObject
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* email;
@end
```
We also need to change `author` property type in `Article` from `NSString*` to `Author*`:
```objc
@interface Article : NSObject
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* body;
@property (nonatomic, retain) Author* author;
@property (nonatomic, retain) NSDate* publicationDate;
@end
```
Now we just need to configure RestKit to map the data appropriately. Let's extend our previous articleMapping to include the new author relationship:
```objc
// Create our new Author mapping
RKObjectMapping* authorMapping = [RKObjectMapping mappingForClass:[Author class]];
// NOTE: When your source and destination key paths are symmetrical, you can use mapAttributes: as a shortcut
[authorMapping mapAttributes:@"name", @"email", nil];
// Now configure the Article mapping
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
// Define the relationship mapping
[articleMapping mapKeyPath:@"author" toRelationship:@"author" withMapping:authorMapping];
[[RKObjectManager sharedManager].mappingProvider setMapping:articleMapping forKeyPath:@"articles"];
```
That's all there is to it. RestKit is now configured to map the above JSON into an array of Article objects, each of which has a related Author object. The
configuration is the same for a nested array of data -- if RestKit encounters an array at mapping time it will map each element in the array using the supplied
mapping and assign the mapped collection back to the destination property.
### Object Serialization
Until now we have been concerned with loading remote object representations into our applications and mapping them into local objects. RestKit also supports
an object mapping powered mechanism for serializing local objects into a textual format for submission back to your backend system for processing. This facility
is provided by the `RKObjectSerializer` class. It is important to note that serialization is just another object mapping operation -- it leverages the same core
engine that is used to map parsed objects into local domain objects. The fundamental difference is that the target output of a serialization operation is an
NSMutableDictionary. The attributes and relationships of your local domain objects are mapped into an intermediate dictionary implementation so that they can
then be run through an encoder to produce URL Form Encoded or JSON data to be sent in the body of the request.
Enough theory, let's take a look at how we configure object serialization. In addition to its duties in providing the object mapper with mappings for key paths,
`RKObjectMappingProvider` has a secondary responsibility of providing the appropriate mapping for serializing an object of a given type. There are a couple of
options for configuring serialization that are best understood through code:
```objc
// Configure a serialization mapping for our Article class. We want to send back title, body, and publicationDate
RKObjectMapping* articleSerializationMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[articleSerializationMapping mapAttributes:@"name", @"body", @"publicationDate", nil];
// Now register the mapping with the provider
[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:articleSerializationMapping forClass:[Article class]];
```
We have now built an object mapping that can take our local `Article` objects and turn them back into `NSMutableDictionary` instances and
we have told the mapping provider how the mapping and classes are related. Life is good -- let's see how it comes into play in the app:
```objc
// Create a new Article and POST it to the server
Article* article = [Article new];
article.title = @"This is my new article!";
article.body = @"RestKit is pretty cool. This is kinda slick.";
[[RKObjectManager sharedManager] postObject:article delegate:self];
```
So how do these pieces connect, you may be asking? When we use postObject:, we are essentially asking RestKit to create and perform an
object serialization on our behalf. Behind the scenes, the following things have just happened:
1. `RKObjectManager` initializes an `RKObjectLoader` instance with a sourceObject property targeting our article object.
1. The `serializationMIMEType` property of the `RKObjectLoader` is set to value of the `serializationMIMEType` property on `RKObjectManager`. This
establishes the destination format to serialize the object into (either URL Form Encoded or JSON, as of this writing). More on this in a moment.
1. `RKObjectManager` asks the `mappingProvider` for the `serializationMappingForClass:[Article class]` to obtain the serialization mapping
for the source object. The serialization mapping is assigned to the `RKObjectLoader` instance on the `serializationMapping` property.
1. The `RKObjectLoader` notices that it has a sourceObject and is performing a POST or PUT request. This triggers serialization to kick in.
1. The `RKObjectLoader` instance initializes an `RKObjectSerializer` with the `sourceObject` and `serializationMapping` configured on the loader.
1. The `RKObjectSerializer` is invoked to build and return a serialized representation of the object in the `serializationMIMEType` format and that
value is assigned to the body of the loader.
1. The asynchronous request is sent off for processing with the serialized data in tow.
We have packed quite a bit of power into just a few lines of code. Let's fill in some of the missing details. As mentioned above, the format the data
takes when being assigned to the request is determined by the value of the `serializationMIMEType` property. We can change this easily:
```objc
// Globally use JSON as the wire format for POST/PUT operations
[RKObjectManager sharedManager].serializationMIMEType = RKMIMETypeJSON;
// Or switch on a per request basis
RKObjectLoader* objectLoader = [[RKObjectManager sharedManager] objectLoaderForObject:article method:RKRequestMethodPOST delegate:self];
objectLoader.serializationMIMEType = RKMIMETypeFormURLEncoded;
[objectLoader send];
```
Because serialization uses `NSMutableDictionary` as the intermediate format, new MIME Types such as XML, Protocol Buffers, BSON, etc. can be added
down the line without major changes to the serializer. We'll examine how this all works in greater depth in the `RKParser` discussion.
Something else you may have noticed when configuring the serialization mapping is that most of the time our serialization mappings are extremely similar
to our object mappings -- except the source and destination key paths are reversed and the destination class is always `NSMutableDictionary`. RestKit
understands and recognizes this relationship between our mappings and provides some extremely convenient shortcuts for configuring serialization:
```objc
// Our familiar articlesMapping from earlier
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"author" toAttribute:@"author"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
// Build a serialization mapping by inverting our object mapping. Includes attributes and relationships
RKObjectMapping* articleSerializationMapping = [articleMapping inverseMapping];
// You can customize the mapping here as necessary -- adding/removing mappings
[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:articleSerializationMapping forClass:[Article class]];
```
### Mapping without KVC
As should be obvious by now, RestKit is a big believer in KVC and offers a very seamless workflow if your JSON conforms
to the patterns. But sadly this is not always the case -- many web API's return their JSON without any nesting attributes that
can be used for mapping selection. In these cases you can still work with RestKit, you just have to be explicit about how your
content is to be handled. Let's consider another example: Imagine that our weblog services returning articles works just as before,
but the JSON output looks like this:
```json
[
{ "title": "RestKit Object Mapping Intro",
"body": "This article details how to use RestKit object mapping...",
"author": {
"name": "Blake Watters",
"email": ""
},
"publication_date": "7/4/2011"
}
]
```
We no longer have the outer @"articles" key path to identify our content and instead have a plain old fashioned array. We'll configure
our mappings much the same, but a slight difference in the registration with the mapping provider:
```objc
// Our familiar articlesMapping from earlier
RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"author" toAttribute:@"author"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
[[RKObjectManager sharedManager].mappingProvider addObjectMapping:articleMapping];
```
Rather than leveraging `setMapping:forKeyPath:`, we have invoked `addObjectMapping:`. This method essentially adds a retained reference
to the mapping provider so that we can easily get the mapping back later when we need it via `objectMappingForClass:`. Let's take a look at how
we'd load this array of `Article` objects:
```objc
- (void)loadArticlesWithoutKVC {
RKObjectMapping* articleMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Article class]];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/articles" objectMapping:articleMapping delegate:self];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
RKLogInfo(@"Load collection of Articles: %@", objects);
}
```
We've had to take the extra step of providing the object mapping directly to the object loader so that RestKit knows what to do with
the object. This can sometimes be necessary when using serialization as well. Consider another example: We have a system where we post an
ArticleQuery object and get back a collection of Articles. Our ArticleQuery object looks like this:
```objc
@interface ArticleQuery
@property (nonatomic, retain) NSString* searchTerm;
@property (nonatomic, retain) NSNumber* pageNumber;
@property (nonatomic, retain) NSNumber* yearPublished;
@end
```
We have configured a serialization mapping for the object and want to fetch our results:
```objc
- (void)loadArticlesUsingQuery {
ArticleQuery* query = [ArticleQuery new];
query.searchTerm = @"Monkey";
query.pageNumber = [NSNumber numberWithInt:5];
query.yearPublished = [NSNumber numberWithInt:2011];
RKObjectMapping* articleMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Article class]];
[[RKObjectManager sharedManager] postObject:query mapResponseWith:articleMapping delegate:self];
}
```
One inconvenience of working with non-KVC data is that RestKit is completely unable to automatically infer the appropriate mappings for you. If you
happen to be working with data where you post/put an object and receive the same object back, you can instruct RestKit to automatically select the
appropriate object mapping for you:
```objc
[RKObjectManager sharedManager].inferMappingsFromObjectTypes = YES;
[[RKObjectManager sharedManager] postObject:article delegate:self];
```
This will cause RestKit to search the mapping provider for the first registered mapping targeting the `Article` class and configure the
object loader to map the results with that mapping. This is provided as a convenience for users who cannot use KVC mappings and is disabled by
default.
### Core Data
Until now we have focused on transient objects within RestKit. For many applications transient objects are completely the right choice --
if your data set is constantly changing and your use-cases can rely on the availability of network access, using transient objects is a
simpler, easier way forward. But for some applications, you really need the full power of a queryable, persistent object model for performance,
flexibility, offline access, etc. Apple has provided a great solution in Core Data. RestKit integrates with Core Data to bridge the gap between
your remote server backend and your local object model. Since Core Data managed objects are KVC compliant, we get much of the integration "for free".
But there are some Core Data specific steps and features that you must understand to leverage the persistence.
First off, when you begin using Core Data you must import the Core Data headers, then configure an object store and connect it your object manager.
The object store is a RestKit component that handles the details of setting of a Core Data environment that is backed with a SQLite database. Let's
take a look at how this works:
```objc
#import
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:@"http://restkit.org"];
RKManagedObjectStore* objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"MyApp.sqlite"];
objectManager.objectStore = objectStore;
```
Now that we have set up the object store, we can configure persistent mappings. Let's say that we want to take our familiar Article object
and make it persistent. You'll have to create a Core Data Managed Object Model and add it to your project. The configuration is outside the
scope of this document, but there are great resources about how this works all over the net. Having done that, we'll update the Article
interface & implementation, then configure a managed object mapping:
```objc
@interface Article : NSManagedObject
@property (nonatomic, retain) NSNumber* articleID;
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* body;
@property (nonatomic, retain) NSDate* publicationDate;
@end
@implementation Article
// We use @dynamic for the properties in Core Data
@dynamic title;
@dynamic body;
@dynamic author;
@dynamic publicationDate;
@end
// Now for the object mappings
RKManagedObjectMapping* articleMapping = [RKManagedObjectMapping objectMappingForClass:[Article class]];
[articleMapping mapKeyPath:@"id" toAttribute:@"articleID"];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
articleMapping.primaryKeyAttribute = @"articleID";
```
The astute reader will notice a couple of things:
1. We changed our inheritance to NSManagedObject from NSObject
1. Our properties are now implemented via @dynamic instead of @synthesize
1. We have added a new property -- articleID. Typically when you load a remote object it is going to include a unique
primary key attribute that uniquely identifies that particular entity. This attribute is typically either an integer or
a string (i.e. a UUID or permalink).
1. We instantiated `RKManagedObjectMapping` instead of `RKObjectMapping`.
1. We have added a new key-path to attribute mapping specifying that we expect an "id" attribute in the payload. In our JSON,
we'd see a fragment like `"id": 12345` added to the dictionary for each Article.
1. We have a new property set on the articleMapping: `primaryKeyAttribute`. This property is significant because it helps RestKit
understand how to uniquely identify your objects and perform intelligently update existing instances. The primaryKeyAttribute is used
to look up an existing object instance by server-side primary key and map updates onto that object instance. If you do not specify a
primaryKeyAttribute, then you will get new objects created every time you trigger object mapping.
### Handling Dynamic Nesting Attributes
A common, though somewhat annoying pattern in some JSON API's is the use of dynamic attributes as the keys for mappable object data.
This commonly shows up with JSON like the following:
```json
{ "blake": {
"email": "",
"favorite_animal": "Monkey"
}
}
```
We might have a User class like the following:
```objc
@interface User : NSObject
@property (nonatomic, retain) NSString* email
@property (nonatomic, retain) NSString* username;
@property (nonatomic, retain) NSString* favoriteAnimal;
@end
```
You will note that this JSON is problematic compared to our earlier examples because the `username` attribute's data
exists as the key in a dictionary, rather than a value. We handle this by creating an object mapping and using a new
type of mapping definition:
```json
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[User class]];
[mapping mapKeyOfNestedDictionaryToAttribute:@"username"];
[mapping mapFromKeyPath:@"(username).email" toAttribute:"email"];
[mapping mapFromKeyPath:@"(username).favorite_animal" toAttribute:"favoriteAnimal"];
```
What happens with this type of object mapping is that when applied against a dictionary of data,
the keys are interpreted to contain the value for the nesting attribute (so "blake" becomes `username`). When
the remaining attribute and relationship key paths are evaluated against the parsed data, the value of the nesting attribute
is substituted into the key path before it is applied. So your @"(username).email" key path becomes @"blake.email" and the
mapping continues.
Note that there annoying limitations with this. It is common for many API's to use e-mail addresses as dynamic keys in this
fashion. This doesn't fly with KVC because the @ character is used to denote array operations.
There is also a subtlety with nesting mappings and collections like this:
```json
{
"blake": {
"email": "",
"favorite_animal": "Monkey"
},
"sarah": {
"email": "",
"favorite_animal": "Cat"
}
}
```
In these cases it is impossible for RestKit to automatically determine if the dictionary represents a single object or
a collection with dynamic attributes. In these cases, you must give RestKit a hint if you have a collection:
```json
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[User class]];
mapping.forceCollectionMapping = YES;
[mapping mapKeyOfNestedDictionaryToAttribute:@"username"];
[mapping mapFromKeyPath:@"(username).email" toAttribute:"email"];
[mapping mapFromKeyPath:@"(username).favorite_animal" toAttribute:"favoriteAnimal"];
```
### Dynamic Object Mapping
Thus far we have examined clear-cut cases where the appropriate object mapping can be determined either by consulting the
key path or by the developer directly providing the mapping. Sometimes it is desirable to dynamically determine the appropriate
object mapping to use at mapping time. Perhaps we have a collection of objects with identical attribute names, but we wish
to represent them differently. Or maybe we are loading a collection of objects that are not KVC compliant, but contain a mixture
of types that we would like to model. RestKit supports such use cases via the RKObjectDynamicMapping class.
RKObjectDynamicMapping is a sibling class to RKObjectMapping and can be added to instances of RKObjectMappingProvider and
used to configure RKObjectMappingOperation instances. RKObjectDynamicMapping allows you to hook into the mapping process
and determine an appropriate RKObjectMapping to use on a per-object basis.
When RestKit is performing a mapping operation and the current mapping being applied is an RKObjectDynamicMapping instance,
the dynamic mapping will be sent the `objectMappingForDictionary:` message with the NSDictionary that is currently being
mapped. The dynamic mapping is responsible for introspecting the contents of the dictionary and returning an RKObjectMapping
instance that can be used to map the data into a concrete object.
There are three ways in which the determination of the appropriate object mapping can be made:
1. Via a declarative matcher on an attribute within the mappable data. If your dynamic data contains an attribute that can
be used to infer the appropriate object type, then you are in luck -- RestKit can handle the dynamic mapping via simple
configuration.
2. Via a delegate callback. If your data requires some special analysis or you want to dynamically construct an object mapping
to handle the data, you can assign a delegate to the RKObjectDynamicMapping and you will be called back to perform whatever
logic you need to implement the object mapping lookup/construction.
3. Via a delegate block invocation. Similar to the delegate configuration, you can assign a delegateBlock to the RKObjectDynamicMapping that will be invoked to determine the appropriate RKObjectMapping to use for the mappable data.
To illustrate these concepts, let's consider the following JSON fragment:
```json
{
"people": [
{
"name": "Blake Watters",
"type": "Boy",
"friends": [
{
"name": "John Doe",
"type": "Boy"
},
{
"name": "Jane Doe",
"type": "Girl"
}
]
},
{
"name": "Sarah",
"type": "Girl"
}
]
}
```
In this JSON we have a dictionary containing an array of people at the "people" key path. We want to map each of the
people within that collection into different classes: `Boy` and `Girl`. Our meaningful attributes are the name and
the friends, which is itself a dynamic collection of people. The `type` attribute will be used to determine what
the appropriate destination mapping and class will be. Let's set it up:
```objc
// Basic setup
RKObjectMapping* boyMapping = [RKObjectMapping mappingForClass:[Boy class]];
[boyMapping mapAttributes:@"name", nil];
RKObjectMapping* girlMapping = [RKObjectMapping mappingForClass:[Girl class]];
[girlMapping mapAttributes:@"name", nil];
RKObjectDynamicMapping* dynamicMapping = [RKObjectDynamicMapping dynamicMapping];
[boyMapping mapKeyPath:@"friends" toRelationship:@"friends" withMapping:dynamicMapping];
[girlMapping mapKeyPath:@"friends" toRelationship:@"friends" withMapping:dynamicMapping];
// Connect our mapping to RestKit's mapping provider
[[RKObjectManager sharedManager].mappingProvider setMapping:dynamicMapping forKeyPath:@"people"];
// Configure the dynamic mapping via matchers
[dynamicMapping setObjectMapping:boyMapping whenValueOfKeyPath:@"type" isEqualTo:@"Boy"];
[dynamicMapping setObjectMapping:girlMapping whenValueOfKeyPath:@"type" isEqualTo:@"Girl"];
// Configure the dynamic mapping via a delegate
dynamicMapping.delegate = self;
- (RKObjectMapping*)objectMappingForData:(id)data {
// Dynamically construct an object mapping for the data
if ([[data valueForKey:@"type"] isEqualToString:@"Girl"]) {
return [RKObjectMapping mappingForClass:[Girl class] block:^(RKObjectMapping* mapping) {
[mapping mapAttributes:@"name", nil];
}];
} else if ([[data valueForKey:@"type"] isEqualToString:@"Boy"]) {
return [RKObjectMapping mappingForClass:[Boy class] block:^(RKObjectMapping* mapping) {
[mapping mapAttributes:@"name", nil];
}];
}
return nil;
}
// Configure the dynamic mapping via a block
dynamicMapping.objectMappingForDataBlock = ^ RKObjectMapping* (id mappableData) {
if ([[mappableData valueForKey:@"type"] isEqualToString:@"Boy"]) {
return boyMapping;
} else if ([[mappableData valueForKey:@"type"] isEqualToString:@"Girl"]) {
return girlMapping;
}
return nil;
};
```
Notable within this code are the calls to `setObjectMapping:whenValueOfKeyPath:isEqualTo:`. This is the declarative
matcher form of dynamic configuration. When you use these matchers, RestKit will invoke `valueForKeyPath:` on your
mappable data and then attempt to compare the resulting value with the value provided in the invocation. If you have
a simple string or numeric value that can be used to differentiate your mappings, then you don't need to use the
delegate or block callbacks at all to perform dynamic mapping.
That's all there is to it. RestKit will invoke the dynamic mapping with the data and apply whatever object
mapping is returned to that data. You can even decline the mapping of individual elements by returning a nil mapping.
This can be useful to filter out unwanted information deep within an object graph.
### Key-value Validation
RestKit supports the use of key-value validation at mapping time. This permits a number of helpful additions to your
workflow. Using KVC validation, you can:
1. Reject inappropriate values coming back from the server.
1. Perform custom transformations of values returned from the server.
1. Fail out the mapping operation using custom logic.
Unlike the vast majority of the work we have done thus far, key-value validation is performed by adding methods onto your model class. KVC validation is
a standard part of the Cocoa stack, but must be manually invoked on NSObject's. It is always performed for you on Core Data
managed object when the managed object context is saved. RestKit provides KVC validation for you when object mapping is taking place.
Let's take a look at how you can leverage key-value validation to perform the above three tasks on our familiar Article object:
```objc
@implementation Article
- (BOOL)validateTitle:(id *)ioValue error:(NSError **)outError {
// Force the title to uppercase
*ioValue = [(NSString*)ioValue uppercaseString];
return YES;
}
- (BOOL)validateArticleID:(id *)ioValue error:(NSError **)outError {
// Reject an article ID of zero. By returning NO, we refused the assignment and the value will not be set
if ([(NSNumber*)ioValue intValue] == 0) {
return NO;
}
return YES;
}
- (BOOL)validateBody:(id *)ioValue error:(NSError **)outError {
// If the body is blank, return NO and fail out the operation.
if ([(NSString*)ioValue length] == 0) {
*outError = [NSError errorWithDomain:RKRestKitErrorDomain code:RKObjectMapperErrorUnmappableContent userInfo:nil];
return NO;
}
return YES;
}
@end
```
These three methods will get invoked when the appropriate attribute is going to be set on the Article objects being mapped. The ioValue
is a pointer to a pointer of the object reference that will be assigned to attribute. This means that we can completely change the value
being assigned to anything that we want. If we return NO from the function, the assignment will not take place. We can also return NO
and construct an error object and set the `outError`. This will cause mapping to fail and the error will bubble back up the RestKit stack.
Look at the NSKeyValueCoding.h and search the web for more info about key-value validation in general.
## Class Hierarchy
- **RKObjectManager** - The external client interface for performing object mapping operations on resources
loaded from the network. The object manager is responsible for creating object loaders and brokering interactions
between the application and object mapping subsystem.
- **RKObjectLoader** - A subclass of RKRequest that sends an HTTP request and performs an object mapping operation
on the resulting payload. Responsible for parsing the payload appropriately and initializing an `RKObjectMapper` to handle the mapping.
- **RKObjectMappingProvider** - Responsible for providing keyPaths and RKObjectMapping objects to instances of `RKObjectMapper`.
An instance of the mapping provider is available via the `mappingProvider` property of `RKObjectManager`. This mapping provider
is automatically assigned to all `RKObjectLoader` instances instantiated through the object manager.
- **RKObjectMapping** - A definition of an object mapping for a particular class. Contains a collection of attribute mappings
defining how attributes in a particular mappable object should be mapped onto the target class. Also contains relationship mappings
specifying how to map nested object structures into one-to-one or one-to-many relationships. Object mappings are registered with the
mapping provider to define rules for mapping and serializing objects.
- **RKObjectAttributeMapping** - Defines a mapping from a source keyPath to a destination keyPath within an object mapping
definition. For example, defines a rule that the NSString attribute at the `created_at` keyPath maps to the NSString property at
the `createdAt` keyPath on the destination object.
- **RKObjectRelationshipMapping** - A subclass of `RKObjectAttributeMapping` that defines a mapping to a related mappable object.
Includes an objectMapping property defining the rules for mapping the related object. Used for transforming nested arrays and dictionaries into
related objects.
- **RKObjectMapper** - The interface for performing object mapping on mappable data. The mapper evaluates the type of the object
and obtains the appropriate object mapping from an `RKObjectMappingProvider` and applies it by creating instances of `RKObjectMappingOperation`.
- **RKObjectMappingOperation** - Responsible for applying an object mapping to a particular mappable dictionary. Evaluates the attribute mappings
contained in the `RKObjectMapping` against the mappable dictionary and assigns the results to the target object. Recursively creates child mapping
operations for all relationships and continues on until a full object graph has been constructed according to the mapping rules.
- **RKObjectMappingResult** - When `RKObjectMapper` has finished its work, it will either return nil to indicate an unrecoverable error occurred or
will return an instance of `RKObjectMappingResult`. The mapping result enables you to coerce the mapped results into the format you wish to work with.
The currently available result coercions are:
1. `asObject` - Return the result as a single object. Useful when you know you have mapped a single object back (i.e. used `postObject`).
1. `asCollection` - Return the result as a collection of mapped objects. This will take all the mapped keyPaths and combine all mapped objects
under those keyPaths and return it as a single array of objects.
1. `asDictionary` - Return the result as a dictionary of keyPaths and mapped object pairs. Useful when you want to identify your results by keyPath.
1. `asError` - Return the result as an NSError. The error is constructed by coercing the result into a collection, then calling `description` on all
mapped objects to turn them into a string. The collection of error message strings are then joined together with the ", " delimiter to construct
the localizedDescription for the error. The raw error objects the error was mapped from is available on the userInfo of the NSError instance. This
is useful when you encountered a server side error and want to coerce the mapping results into an NSError. This is how `objectLoader:didFailWithError`
returns server side error messages to you.
- **RKObjectRouter** - Responsible for generating resource paths for accessing remote representations of objects. Capable of generating a resource
path by interpolating property values into a string. For example, a path of "/articles/:articleID" when applied to an Article object with a `articleID` property
with the value 12345, would generate "/articles/12345". The object router is used to generate resource paths when getObject, postObject, putObject and deleteObject
are invoked.
- **RKErrorMessage** - A simple class providing for the mapping of server-side error messages back to NSError objects. Contains a single `errorMessage` property. When an
RKObjectManager is initialized, object mappings from the "error" and "errors" keyPaths to instances of RKErrorMessage are registered with the mapping provider. This
provides out of the box mapping support for simple error messages. The mappings can be removed or replaced by the developer to handle more advanced error return values,
such as containing a server side error code or other metadata.
- **RKObjectPropertyInspector** - An internally used singleton object responsible for cacheing the properties and types of a target class. This is used during object mapping
to transform values at mapping time based on the source and destination types.
- **RKObjectSerializer** - Responsible for taking Cocoa objects are serializing them for transport via HTTP to a remote server. The serializer takes an instance of an object
and maps it back into an NSDictionary representation by creating an `RKObjectMappingOperation`. During the mapping process, certain types are transformed into serializable
representation (i.e. NSDate & NSDecimalNumber objects are coerced into NSString instances). Once mapping is complete, the NSDictionary instance is encoded into a wire format
and returned as an `RKRequestSerializable` object. The serializer is invoked for you automatically when `postObject` and `putObject` are invoked on the object manager. The
appropriate mapping is selected by consulting the `objectMappingForClass:` method of the `RKObjectMappingProvider` instance configured on the object manager. Currently serialization to form encoded and JSON is supported.
- **RKParserRegistry** - Responsible for maintaining the association between MIME Types and the `RKParser` object responsible for handling it. There is a singleton
sharedRegistry instance that is automatically configured at library initialization time to handle the application/json and application/xml MIME types. Runtime detection
of the parser classes is utilized to configure the registry appropriately. For JSON, autoconfiguration searches for JSONKit, then YAJL, and then SBJSON.
## Tasks
### Configuring an Object Mapping
```objc
// In this use-case Article is a vanilla NSObject with properties
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[Article class]];
// Add an attribute mapping to the object mapping directly
RKObjectAttributeMapping* titleMapping = [RKObjectAttributeMapping mappingFromKeyPath:@"title" toKeyPath:@"title"];
[mapping addAttributeMapping:titleMapping];
// Configure attribute mappings using helper methods
[mapping mapAttributes:@"title", @"body", nil]; // Define mappings where the keyPath and target attribute have the same name
[mapping mapKeyPath:@"created_at" toAttribute:@"createdAt"]; // Map a differing keyPath and attribute
[mapping mapKeyPathsToAttributes:@"some.keyPath", @"targetAttribute1", @"another.keyPath", @"targetAttribute2", nil];
// Configure relationship mappings
RKObjectMapping* commentMapping = [[RKObjectManager sharedManager] objectMappingForClass:[Comment class]];
// Direct configuration of instances
RKObjectRelationshipMapping* articleCommentsMapping = [RKObjectRelationshipMapping mappingFromKeyPath:@"comments" toKeyPath:@"comments" withMapping:commentMapping];
[mapping addRelationshipMapping:articleCommentsMapping];
// Configuration using helper methods
[mapping mapRelationship:@"comments" withMapping:commentMapping];
[mapping hasMany:@"comments" withMapping:commentMapping];
[mapping belongsTo:@"user" withMapping:userMapping];
// Register the mapping with the object manager
[objectManager.mappingProvider setMapping:mapping forKeyPath:@"article"];
```
### Configuring a Core Data Object Mapping
```objc
#import
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:@"http://restkit.org"];
RKManagedObjectStore* objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"MyApp.sqlite"];
objectManager.objectStore = objectStore;
RKManagedObjectMapping* articleMapping = [RKManagedObjectMapping objectMappingForClass:[Article class]];
[articleMapping mapKeyPath:@"id" toAttribute:@"articleID"];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];
articleMapping.primaryKeyAttribute = @"articleID";
```
### Loading Using KeyPath Mapping Lookup
```objc
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:@"http://restkit.org"];
RKManagedObjectMapping* articleMapping = [RKObjectMapping objectMappingForClass:[Article class]];
[articleMapping mapKeyPath:@"id" toAttribute:@"articleID"];
[objectManager.mappingProvider setMapping:articleMapping forKeyPath:@"articles"];
RKObjectLoader* loader = [RKObjectManager loadObjectsAtResourcePath:@"/articles" delegate:self];
/**
The object mapper will try to determine the mappings by examining keyPaths in the loaded payload. If
the payload contains a dictionary with data at the 'articles' key, it will be mapped
*/
```
### Load using an explicit mapping
```objc
RKObjectMapping* articleMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Article class]];
[RKObjectManager loadObjectsAtResourcePath:@"/objects" objectMapping:articleMapping delegate:self];
```
### Using Object Mapping Block Helpers
```objc
[[RKObjectManager sharedManager] postObject:user delegate:self block:^(RKObjectLoader* loader) {
loader.objectMapping = [RKObjectMapping mappingForClass:[User class] block:^(RKObjectMapping* mapping) {
mapping.rootKeyPath = @"user";
[mapping mapAttributes:@"password", nil];
[mapping mapKeyPath:@"passwordConfirmation" toAttribute:@"password_confirmation"];
}];
}];
```
### Configuring the Serialization Format
```objc
// Serialize to Form Encoded
[RKObjectManager sharedManager].serializationMIMEType = RKMIMETypeFormURLEncoded;
// Serialize to JSON
[RKObjectManager sharedManager].serializationMIMEType = RKMIMETypeJSON;
```
### Object Serialization Tasks
This is handled for you when using postObject and putObject, presented here for reference
```objc
RKUser* user = [User new];
user.firstName = @"Blake";
user.lastName = @"Watters";
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[NSDictionary class]];
[mapping mapAttributes:@"firstName", @"lastName", nil];
RKObjectSerializer* serializer = [RKObjectSerializer serializerWithObject:object mapping:serializationMapping];
NSError* error = nil;
// Turn an object into a dictionary
NSMutableDictionary* dictionary = [serializer serializedObject:&error];
// Serialize the object to JSON
NSString* JSON = [serializer serializedObjectForMIMEType:RKMIMETypeJSON error:&error];
// Turn it into a RKRequestSerializable
id
```
### Performing a Mapping
This is handled for you when using loadObjectAtResourcePath:, presented here for reference:
```objc
NSString* JSONString = @"{ \"name\": \"The name\", \"number\": 12345}";
NSString* MIMEType = @"application/json";
NSError* error = nil;
id
id parsedData = [parser objectFromString:JSONString error:error];
if (parsedData == nil && error) {
// Parser error...
}
RKObjectMappingProvider* mappingProvider = [RKObjectManager sharedManager].mappingProvider;
RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider];
RKObjectMappingResult* result = [mapper performMapping];
if (result) {
// Yay! Mapping finished successfully
}
```
### Registering a Parser
```objc
[[RKParserRegistry sharedRegistry] setParserClass:[RKJSONParserJSONKit class] forMIMEType:RKMIMETypeJSON];
```
blake@restkit.orgblake@restkit.orgblake@restkit.orgblake@restkit.orgsarah@restkit.org
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._Object Mapping.md
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Presentations/Introduction to RestKit/Introduction to RestKit.key
Click to edit Master text styles
Click to edit Master text styles
Body Level TwoText
Introduction to RestKit
Blake Watters
- Here to introduce you to RestKit, an iOS framework for modeling RESTful resources- Walk through a bunch of code slides to give flavor for the library- Be interactive- Brief overview of the technology we are going to look at...We’ll walk through each of these pieces with code samples
Technology Overview
Integrated HTTP stackNSURLConnection basedSimplifies common tasksObject MappingBuild domain objects for REST resourcesCore Data IntegrationActive Record Pattern ImplementationExtends Object MappingTable UI ToolkitMap objects to table cells
Project Overview
Apache LicensedBuilt on Core Apple TechnologiesProduction ReadyWell supportedFast MovingLarge, active communityOver 1100 Github Watchers~200 Forks500+ Mailing List Members
Network Layer
- Request/Response model for HTTP- Client models user agent- Base URL and Resource paths- Streaming File Uploads- HTTP AUTH, OAuth- Reachability- Queueing Requests- Cacheingetags, time based
Initializing RKClient- (void)initRKClient {// Initialize with a Base URLRKClient* client = [RKClient clientWithBaseURL:@"http://restkit.org"];
// Setup HTTP AUTHclient.username = @"restkit";client.password = @"rocks";
// Set an app-wide API key HTTP header[client setValue:@"123456" forHTTPHeaderField:@"X-RESTKIT-API-KEY"];
// The first initialized RKClient becomes// the sharedClient instance[[RKClient sharedClient] isNetworkAvailable];}
Think of the client as your user agentCentralizes your configuration for new requests to DRY up the code
Sending Requests- (void)sendRequest {// Send an HTTP GET request to 'http://restkit.org/contacts'[[RKClient sharedClient] get:@"/contacts" delegate:self];}
// RKRequestDelegate methods
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {RKLogInfo(@"Yay! We Got a response");}
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError *)error {RKLogInfo(@"Oh no! We encountered an error: %@", [error localizedDescription]);}
Processing Responses- (void)sendRequest {// Send an HTTP GET request to 'http://restkit.org/contacts'[[RKClient sharedClient] get:@"/contacts" delegate:self];}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {RKLogInfo(@"Request Headers: %@", [response allHeaderFields]);RKLogInfo(@"Cookies: %@", [response cookies])
if ([response isSuccessful]) {// Response status was 200..299if ([response isCreated] && [response isJSON]) {// Looks like we have a 201 response of type 'application/json'RKLogInfo(@"The JSON is %@", [response bodyAsJSON]);}} else if ([response isError]) {// Response status was either 400..499 or 500..599RKLogInfo(@"Ouch! We have an HTTP error. Status Code description: %@", [response localizedStatusCodeString]);}}
Requests with Parameters- (void)sendRequestWithParams {// Simple paramsNSDictionary* paramsDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"Joe Blow", @"name", @"Acme, Inc", @"company", nil];[[RKClient sharedClient] post:@"/contacts" params:paramsDictionary delegate:self];
// Multi-part params via RKParamsRKParams* params = [RKParams paramsWithDictionary:paramsDictionary];NSData* imageData = UIImagePNGRepresentation([UIImage imageNamed:@"picture "]);[params setData:imageData MIMEType:@"image/png" forParam:@"photo"];[params setFile:@"bio.txt" forParam:@"attachment"];[[RKClient sharedClient] post:@"/contacts" params:params delegate:self];}
Reachability- (void)demoReachability {// Check if the network is available[[RKClient sharedClient] isNetworkAvailable];
// Register for changes in network availabilityNSNotificationCenter* center = [NSNotificationCenter defaultCenter];[center addObserver:self selector:@selector(reachabilityDidChange:) name:RKReachabilityStateChangedNotification object:nil];}
- (void)reachabilityDidChange:(NSNotification *)notification {RKReachabilityObserver* observer = (RKReachabilityObserver *) [notification object];RKReachabilityNetworkStatus status = [observer networkStatus];if (RKReachabilityNotReachable == status) {RKLogInfo(@"No network access!");} else if (RKReachabilityReachableViaWiFi == status) {RKLogInfo(@"Online via WiFi!");} else if (RKReachabilityReachableViaWWAN == status) {RKLogInfo(@"Online via Edge or 3G!");}}
Request Queue- (IBAction)queueRequests { RKRequestQueue* queue = [RKRequestQueue new]; queue.delegate = self; queue.concurrentRequestsLimit = 1; queue.showsNetworkActivityIndicatorWhenBusy = YES; // Queue up 4 requests [queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org"] delegate:nil]]; [queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org"] delegate:nil]]; [queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org"] delegate:nil]]; [queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org"] delegate:nil]]; // Start processing! [queue start]; [queue cancelAllRequests];}
Object Mapping
Key-value coding is fundamental to RestKit object mappingProcess of taking a JSON/XML document and parsing into a key-value coding
Initializing the Object Manager- (void)initObjectManager {RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"]; // Ask for & generate JSON manager.acceptMIMEType = RKMIMETypeJSON; manager.serializationMIMEType = RKMIMETypeJSON;
// Object manager has a client [manager.client setValue:@"123456" forHTTPHeaderField:@"X-RESTKIT-API-KEY"];}
When we work with the object mapping layer we step up to RKObjectManager from RKClientIt mints RKObjectLoader instead of RKRequest objectsRKObjectLoader is a subclass that does a network load followed by an object mapping operation
Modeling a RESTful Service
/contacts
@interface Contact[{ 'contact': { 'id': 1234, 'name': 'Blake Watters', 'email': '',blake@restkit.org 'company': 'GateGuru', 'birth_date': '11/27/1982' }},{ 'contact': { 'id': 3456, 'name': 'John Doe', 'email': '',john@doe.com 'company': 'Acme, Inc' }}]@interface Contact : NSObject
@property (retain) NSNumber* contactID; @property (retain) NSString* name; @property (retain) NSString* email; @property (retain) NSString* company; @property (retain) NSDate* birthDate;@end
This is a simple case. It gets muchThere are a number of type conversions available. Strings -> Dates, Strings -> NSDecimalNumber, etc.Talk about relationships and nesting. Ability to map similar JSON dynamically to different types
Configuring an Object Mapping- (void)setupContactMapping { RKObjectMapping *contactMapping = [RKObjectMapping mappingForClass:[Contact class]]; [contactMapping mapKeyPath:@"id" toAttribute:@"contactID"]; [contactMapping mapKeyPath:@"birth_date" toAttribute:@"birthDate"]; [contactMapping mapAttributes:@"name", @"email", @"company", nil];
NSDateFormatter *dateFormatter = [NSDateFormatter new]; [dateFormatter setDateFormat:@"MM/dd/yyyy"]; // 11/27/1982 dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; contactMapping.dateFormatters = [NSArray arrayWithObject:dateFormatter]; [[RKObjectManager sharedManager].mappingProvider setMapping:contactMapping forKeyPath:@"contact"];}
Loading Remote Objects- (void)loadRemoteObjects {[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/contacts" delegate:self];}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {if ([objectLoader wasSentToResourcePath:@"/contacts"]) {// Introspect the resource pathNSLog(@"Nice! We loaded the following contacts: %@", objects);}}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {// Note that failures here can be at the _application_ level in addition to transportNSLog(@"Rats! Failed to load objects: %@", [error localizedDescription]);}
What just happened?
RKObjectManager configured to map ‘contact’ dictionaries to Contact classAsynchronous GET sent to ‘/contacts’ via RKObjectLoader200 response returned, with JSON bodyRKObjectMapper parsed payload and mapped JSON data to Contact objectsCallback invoked with array of Contacts
Focus on being asynchronousNetwork Queue -> Grand Central Dispatch Queue
Configuring the Router- (void)configureRouter {RKObjectRouter* router = [RKObjectManager sharedManager].router;
// Configure a default route[router routeClass:[Contact class] toResourcePath:@"/contacts/:contactID"];[router routeClass:[Contact class] toResourcePath:@"/contacts" forMethod:RKRequestMethodPOST];}
Responsible for building resource paths for an objectThis allows us to hand object references to the manager and let it build the requests for us
RESTful Object Manipulation// Create a new Contact- (void)createObject {Contact* contact = [Contact new];contact.name = @"RestKit User";contact.email = @"";user@restkit.org
// POST to /contacts[[RKObjectManager sharedManager] postObject:contact delegate:self];}
// Edit Contact with ID 12345- (void)editObject {Contact* contact = [Contact new];contact.contactID = [NSNumber numberWithInt:12345];contact.name = @"New Name";
// POST to /contacts/12345[[RKObjectManager sharedManager] putObject:contact delegate:self];}
// Delete Contact with ID 321- (void)deleteObject {Contact* contact = [Contact new];contact.contactID = [NSNumber numberWithInt:321];
// DELETE to /contacts/321[[RKObjectManager sharedManager] deleteObject:contact delegate:self];}
Serialization can target form encoded or JSON outputObject is serialized into a dictionary and then run through a parser
Core Data
Core Data support extends object mapping with specifics for Core Data classesAlso introduces an extension library for managed objects implementing the Active Record patternAbstracts away details of Core Data and threading for youConnect via primary keyUpdates existing objects via primary key to prevent duplicatesCan handle server-side object deletionsWhen in use you can skip the network and parsing by using object cache
Configuring RKManagedObjectStore- (void)configureObjectStore { // Initialize the RestKit Object Manager RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"];
// Initialize object store // We are using the Core Data support, so we have initialized a managed object store backed // with a SQLite database. objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"Contacts.sqlite"];}
Making Contact Persistent#import
@interface Contact : NSManagedObject
@end
@implementation Contact
@dynamic name;@dynamic email;@dynamic company;@dynamic contactID;
@end
- (void)coreDataMapping { RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:[Contact class] inManagedObjectStore:store]; mapping.primaryKeyAttribute = @"contactID";}
Mapping definition changes slightly. NSManagedObject instead of NSObjectAlso possible to map against a Core Data entity
Working with Core Data- (void)workWithCoreData {// Get all the ContactsNSArray* contacts = [Contact findAll];
// Count the ContactsNSError* error = nil;NSUInteger count = [Contact count:&error];
// Find Contact by primary keyNSNumber* contactID = [NSNumber numberWithInt:12345];Article* somebody = [Contact findFirstByAttribute:@"contactID" withValue:contactID];
// Find Contacts with criteriaNSPredicate* predicate = [NSPredicate predicateWithFormat:@"name contains[cd] 'restkit'"];NSArray* matches = [Contact findAllWithPredicate:predicate];
// Find first 10 Contacts, sorted by nameNSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];NSFetchRequest* fetchRequest = [Contact fetchRequest];[fetchRequest setFetchLimit:10];[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];NSArray* sortedContacts = [Contact executeFetchRequest:fetchRequest];
}
Database Seeding// This is typically configured as a secondary target on your project// Dump your seed data out of your backend system in JSON format// Add to the project as resources// Run the secondary target in the Simulator- (void)seedTheDatabase {// Setup the object managerRKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"];objectManager.objectStore = [RKManagedObjectStore objectManagerWithStoreFilename:@"ContactsSeed.sqlite"];
// Load all the data from the file contacts.json into a seed database// The seeder will print instructions for how to copy the data to your appRKObjectSeeder* seeder = [RKObjectSeeder objectSeederWithObjectManager:objectManager];[seeder seedObjectsFromFiles:@"contacts.json", nil];[seeder finalizeSeedingAndExit];}
RestKit UI
Static, Network and Core Data backed tablesTable states for loading, empty, error and offlineSupports form based UI’s via RKFormAPI is in flux, will be released in 0.9.5
Static Table
Static Table- (void)loadStaticTable { RKTableController *tableController = [RKTableController tableControllerWithTableView:self.tableView]; NSArray* tableItems = [NSArray arrayWithObjects: [RKTableItem tableItemWithText:@"User" URL:@"gg://user"], [RKTableItem tableItemWithText:@"Connect" URL:@"gg://user/connect"], [RKTableItem tableItemWithText:@"Bookmarks" URL:@"gg://user/bookmarks"], [RKTableItem tableItemWithText:@"Reviews & Tips" URL:@"gg://user/reviews"], [RKTableItem tableItemWithText:@"Scores" URL:@"gg://user/scores"], nil]; // Load the table view [self.tableController loadTableItems:tableItems withMappingBlock:^(RKTableViewCellMapping* cellMapping) { cellMapping.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cellMapping.onSelectCellForObjectAtIndexPath = ^(UITableViewCell* cell, id object, NSIndexPath* indexPath) { TTOpenURL([object valueForKey:@"URL"]); }; }];}
Table controller takes over as delegate and data sourceTable items are data model for ad-hoc table entriesThey are key-value coding compliant -- you can connect them to cells declarativelyRKTableCellMapping is a subclass of RKObjectMapping. Defines mappings from any object to a table cellExtensive use of a blocks API
Network Table- (void)loadTableView { // Setup the Table View Model self.tableController = [RKTableController tableControllerWithTableView:self.tableView]; self.tableController.delegate = self; self.tableController.imageForEmpty = [UIImage imageNamed:@"no_high_flyers "]; self.tableController.imageForOffline = [UIImage imageNamed:@"offline "]; [self.tableController mapObjectsWithClass:[GGHighFlyer class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingWithBlock:^(RKTableViewCellMapping* cellMapping) { cellMapping.cellClass = [GGHighFlyerTableViewCell class]; cellMapping.selectionStyle = UITableViewCellSelectionStyleNone; cellMapping.rowHeight = 44; [cellMapping mapAttributes:@"points", @"login", nil]; cellMapping.onCellWillAppearForObjectAtIndexPath = ^(UITableViewCell* cell, id object, NSIndexPath* indexPath) { GGHighFlyerTableViewCell* highFlyerCell = (GGHighFlyerTableViewCell*) cell; highFlyerCell.captain = (indexPath.row == 0); highFlyerCell.rank = indexPath.row + 1; }; }]]; NSString* resourcePath = [NSString stringWithFormat:@"/airports/%@/high_flyers.json", [_airport airportId]]; NSString* resourcePathWithQueryString = [self addQueryStringToResourcePath:resourcePath]; [self.tableController loadTableFromResourcePath:resourcePathWithQueryString];}
Perform a network load of High Flyers objects from the serverObject map them into GGHighFlyer objectsThen object map them into GGHighFlyerTableCell
Building a Form
Building a Form- (void)changePasswordForm { GGUser *user = [GGUser user]; RKForm *form = [RKForm formForObject:user withBlock:^(RKForm *form) { [form addRowForAttribute:@"password" withControlType:RKFormControlTypeTextFieldSecure block:^(RKControlTableItem *tableItem) { tableItem.textField.placeholder = @"New Password"; tableItem.textField.returnKeyType = UIReturnKeyDone; tableItem.textField.keyboardAppearance = UIKeyboardAppearanceAlert; }]; form.onSubmit = ^{ NSError* error = nil; GGUser *user = (GGUser *) form.object; if (! [[GGUser user] changePassword:user.password error:&error]) { GGAlertWithTitleAndMessage(@"Invalid Password", [error localizedDescription]); } }; }]; [self.tableController loadForm:form];}
Object maps a particular instance of an object into a tableAttributes of the object are bound to controls
Mention integration with key-value validation
Thank You!
http://restkit.org/http://twitter.com/restkithttp://github.com/RestKit/RestKit
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Presentations/Introduction to RestKit/._Introduction to RestKit.key
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Presentations/Introduction to RestKit/Introduction to RestKit
Introduction to RestKit
Blake Watters
Wednesday, September 14, 11
Technology Overview
2
• Integrated HTTP stack
– NSURLConnection based
– Simpli!es common tasks
• Object Mapping
– Build domain objects for REST resources
• Core Data Integration
– Active Record Pattern Implementation
– Extends Object Mapping
• Table UI Toolkit
– Map objects to table cells
Wednesday, September 14, 11
• Large, active
community
• Over 1100 Github
Watchers
• ~200 Forks
• 500+ Mailing List
Members
Project Overview
3
• Apache Licensed
• Built on Core
Apple
Technologies
• Production Ready
• Well supported
• Fast Moving
Wednesday, September 14, 11
Network Layer
4
Wednesday, September 14, 11
Initializing RKClient
- (void)initRKClient {
! // Initialize with a Base URL
! RKClient* client = [RKClient clientWithBaseURL:@"http://restkit.org"];
!
! // Setup HTTP AUTH
! client.username = @"restkit";
! client.password = @"rocks";
!
! // Set an app-wide API key HTTP header
! [client setValue:@"123456" forHTTPHeaderField:@"X-RESTKIT-API-KEY"];
!
! // The first initialized RKClient becomes
! // the sharedClient instance
! [[RKClient sharedClient] isNetworkAvailable];
}
5
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
Sending Requests
- (void)sendRequest {
! // Send an HTTP GET request to 'http://restkit.org/contacts'
! [[RKClient sharedClient] get:@"/contacts" delegate:self];
}
// RKRequestDelegate methods
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
! RKLogInfo(@"Yay! We Got a response");
}
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError *)error {
! RKLogInfo(@"Oh no! We encountered an error: %@", [error
localizedDescription]);
}
6
Wednesday, September 14, 11
http://restkit.org/contacts'
http://restkit.org/contacts'
Processing Responses
- (void)sendRequest {
! // Send an HTTP GET request to 'http://restkit.org/contacts'
! [[RKClient sharedClient] get:@"/contacts" delegate:self];
}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
! RKLogInfo(@"Request Headers: %@", [response allHeaderFields]);
! RKLogInfo(@"Cookies: %@", [response cookies])
!
! if ([response isSuccessful]) {
! ! // Response status was 200..299
! ! if ([response isCreated] && [response isJSON]) {
! ! ! // Looks like we have a 201 response of type 'application/json'
! ! ! RKLogInfo(@"The JSON is %@", [response bodyAsJSON]);
! ! }
! } else if ([response isError]) {
! ! // Response status was either 400..499 or 500..599
! ! RKLogInfo(@"Ouch! We have an HTTP error. Status Code description: %@",
[response localizedStatusCodeString]);
! }
}
7
Wednesday, September 14, 11
http://restkit.org/contacts'
http://restkit.org/contacts'
Requests with Parameters
- (void)sendRequestWithParams {
! // Simple params
! NSDictionary* paramsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
! ! ! ! ! ! ! ! ! @"Joe Blow", @"name",
! ! ! ! ! ! ! ! ! @"Acme, Inc", @"company", nil];
! [[RKClient sharedClient] post:@"/contacts" params:paramsDictionary
delegate:self];
!
! // Multi-part params via RKParams!
! RKParams* params = [RKParams paramsWithDictionary:paramsDictionary];
! NSData* imageData = UIImagePNGRepresentation([UIImage
imageNamed:@"picture "]);
! [params setData:imageData MIMEType:@"image/png" forParam:@"photo"];
! [params setFile:@"bio.txt" forParam:@"attachment"];
! [[RKClient sharedClient] post:@"/contacts" params:params delegate:self];
}
8
Wednesday, September 14, 11
Reachability
- (void)demoReachability {
! // Check if the network is available
! [[RKClient sharedClient] isNetworkAvailable];
!
! // Register for changes in network availability
! NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
! [center addObserver:self selector:@selector(reachabilityDidChange:)
name:RKReachabilityStateChangedNotification object:nil];
}
- (void)reachabilityDidChange:(NSNotification *)notification {
! RKReachabilityObserver* observer = (RKReachabilityObserver *) [notification
object];
! RKReachabilityNetworkStatus status = [observer networkStatus];
! if (RKReachabilityNotReachable == status) {
! ! RKLogInfo(@"No network access!");
! } else if (RKReachabilityReachableViaWiFi == status) {
! ! RKLogInfo(@"Online via WiFi!");
! } else if (RKReachabilityReachableViaWWAN == status) {
! ! RKLogInfo(@"Online via Edge or 3G!");
! }
} 9
Wednesday, September 14, 11
Request Queue
- (IBAction)queueRequests {
RKRequestQueue* queue = [RKRequestQueue new];
queue.delegate = self;
queue.concurrentRequestsLimit = 1;
queue.showsNetworkActivityIndicatorWhenBusy = YES;
// Queue up 4 requests
[queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://
restkit.org"] delegate:nil]];
[queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://
restkit.org"] delegate:nil]];
[queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://
restkit.org"] delegate:nil]];
[queue addRequest:[RKRequest requestWithURL:[NSURL URLWithString:@"http://
restkit.org"] delegate:nil]];
// Start processing!
[queue start];
[queue cancelAllRequests];
}
10
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
Object Mapping
11
Wednesday, September 14, 11
Initializing the Object Manager
- (void)initObjectManager {
! RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:@"http://
restkit.org"];
// Ask for & generate JSON
manager.acceptMIMEType = RKMIMETypeJSON;
manager.serializationMIMEType = RKMIMETypeJSON;
!
// Object manager has a client
[manager.client setValue:@"123456" forHTTPHeaderField:@"X-RESTKIT-API-KEY"];
}
12
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
@interface Contact
Modeling a RESTful Service
13
/contacts
[{
'contact':
{
'id':
1234,
'name':
'Blake
Wa8ers',
'email':
'',
'company':
'GateGuru',
blake@restkit.org
'birth_date':
'11/27/1982'
}
},
{
'contact':
{
'id':
3456,
'name':
'John
Doe',
'email':
'',
'company':
'Acme,
Inc'
}
}]
john@doe.com@interface
Contact
:
NSObject
@property
(retain)
NSNumber*
contactID;
@property
(retain)
NSString*
name;
@property
(retain)
NSString*
email;
@property
(retain)
NSString*
company;
@property
(retain)
NSDate*
birthDate;
@end
Wednesday, September 14, 11
mailto:blake@twotoasters.com
mailto:blake@twotoasters.com
mailto:rachit@twotoasters.com
mailto:rachit@twotoasters.com
Con!guring an Object Mapping
- (void)setupContactMapping {
RKObjectMapping *contactMapping = [RKObjectMapping mappingForClass:[Contact class]];
[contactMapping mapKeyPath:@"id" toAttribute:@"contactID"];
[contactMapping mapKeyPath:@"birth_date" toAttribute:@"birthDate"];
[contactMapping mapAttributes:@"name", @"email", @"company", nil];
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:@"MM/dd/yyyy"]; // 11/27/1982
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
contactMapping.dateFormatters = [NSArray arrayWithObject:dateFormatter];
[[RKObjectManager sharedManager].mappingProvider setMapping:contactMapping
forKeyPath:@"contact"];
}
14
Wednesday, September 14, 11
Loading Remote Objects
- (void)loadRemoteObjects {
! [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/contacts" delegate:self];
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
! if ([objectLoader wasSentToResourcePath:@"/contacts"]) {
! ! // Introspect the resource path
! ! NSLog(@"Nice! We loaded the following contacts: %@", objects);
! }
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
! // Note that failures here can be at the _application_ level in addition to transport
! NSLog(@"Rats! Failed to load objects: %@", [error localizedDescription]);
}
15
Wednesday, September 14, 11
16
What just happened?
• RKObjectManager con!gured to map
‘contact’ dictionaries to Contact class
• Asynchronous GET sent to ‘/contacts’ via
RKObjectLoader
• 200 response returned, with JSON body
• RKObjectMapper parsed payload and
mapped JSON data to Contact objects
• Callback invoked with array of Contacts
Wednesday, September 14, 11
Con!guring the Router
- (void)configureRouter {
! RKObjectRouter* router = [RKObjectManager sharedManager].router;
!
! // Configure a default route
! [router routeClass:[Contact class] toResourcePath:@"/contacts/:contactID"];
! [router routeClass:[Contact class] toResourcePath:@"/contacts" forMethod:RKRequestMethodPOST];
}
17
Wednesday, September 14, 11
RESTful Object Manipulation
// Create a new Contact
- (void)createObject {
! Contact* contact = [Contact new];
! contact.name = @"RestKit User";
! contact.email = @"";
!
! // POST to /contacts
! [[RKObjectManager sharedManager] postObject:contact delegate:self];
}
user@restkit.org// Edit Contact with ID 12345
- (void)editObject {
! Contact* contact = [Contact new];
! contact.contactID = [NSNumber numberWithInt:12345];
! contact.name = @"New Name";
!
! // POST to /contacts/12345
! [[RKObjectManager sharedManager] putObject:contact delegate:self];
}
// Delete Contact with ID 321
- (void)deleteObject {
! Contact* contact = [Contact new];
! contact.contactID = [NSNumber numberWithInt:321];
!
! // DELETE to /contacts/321
! [[RKObjectManager sharedManager] deleteObject:contact delegate:self];!
} 18
Wednesday, September 14, 11
mailto:user@restkit.org
mailto:user@restkit.org
Core Data
19
Wednesday, September 14, 11
Con!guring RKManagedObjectStore
- (void)configureObjectStore {
// Initialize the RestKit Object Manager
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"];
!
// Initialize object store
// We are using the Core Data support, so we have initialized a managed object store backed
// with a SQLite database.
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"Contacts.sqlite"];
}
20
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
Making Contact Persistent
#import
@interface Contact : NSManagedObject
@end
@implementation Contact
@dynamic name;
@dynamic email;
@dynamic company;
@dynamic contactID;
@end
- (void)coreDataMapping {
RKManagedObjectMapping *mapping = [RKManagedObjectMapping mappingForClass:
[Contact class] inManagedObjectStore:store];
mapping.primaryKeyAttribute = @"contactID";
}
21
Wednesday, September 14, 11
Working with Core Data
- (void)workWithCoreData {
! // Get all the Contacts
! NSArray* contacts = [Contact findAll];
!
! // Count the Contacts
! NSError* error = nil;
! NSUInteger count = [Contact count:&error];
!
! // Find Contact by primary key
! NSNumber* contactID = [NSNumber numberWithInt:12345];
! Article* somebody = [Contact findFirstByAttribute:@"contactID"
withValue:contactID];
!
! // Find Contacts with criteria
! NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name contains[cd]
'restkit'"];
! NSArray* matches = [Contact findAllWithPredicate:predicate];
!
! // Find first 10 Contacts, sorted by name
! NSSortDescriptor* sortDescriptor = [NSSortDescriptor
sortDescriptorWithKey:@"name" ascending:YES];
! NSFetchRequest* fetchRequest = [Contact fetchRequest];
! [fetchRequest setFetchLimit:10];
! [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
! NSArray* sortedContacts = [Contact executeFetchRequest:fetchRequest];
} 22
Wednesday, September 14, 11
Database Seeding
// This is typically configured as a secondary target on your project
// Dump your seed data out of your backend system in JSON format
// Add to the project as resources
// Run the secondary target in the Simulator
- (void)seedTheDatabase {
! // Setup the object manager
! RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"http://
restkit.org"];
! objectManager.objectStore = [RKManagedObjectStore
objectManagerWithStoreFilename:@"ContactsSeed.sqlite"];
!
! // Load all the data from the file contacts.json into a seed database
! // The seeder will print instructions for how to copy the data to your app
! RKObjectSeeder* seeder = [RKObjectSeeder objectSeederWithObjectManager:objectManager];
! [seeder seedObjectsFromFiles:@"contacts.json", nil];
! [seeder finalizeSeedingAndExit];
}
23
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
http://restkit.org
http://restkit.org
RestKit UI
24
Wednesday, September 14, 11
Static Table
- (void)loadStaticTable {
RKTableController *tableController = [RKTableController
tableControllerWithTableView:self.tableView];
NSArray* tableItems = [NSArray arrayWithObjects:
[RKTableItem tableItemWithText:@"User" URL:@"gg://user"],
[RKTableItem tableItemWithText:@"Connect" URL:@"gg://user/connect"],
[RKTableItem tableItemWithText:@"Bookmarks" URL:@"gg://user/bookmarks"],
[RKTableItem tableItemWithText:@"Reviews & Tips" URL:@"gg://user/reviews"],
[RKTableItem tableItemWithText:@"Scores" URL:@"gg://user/scores"],
nil];
// Load the table view
[self.tableController loadTableItems:tableItems
withMappingBlock:^(RKTableViewCellMapping* cellMapping) {
cellMapping.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cellMapping.onSelectCellForObjectAtIndexPath = ^(UITableViewCell* cell, id
object, NSIndexPath* indexPath) {
TTOpenURL([object valueForKey:@"URL"]);
};
}];
}
25
Wednesday, September 14, 11
26
Wednesday, September 14, 11
Network Table
- (void)loadTableView {
// Setup the Table View Model
self.tableController = [RKTableController tableControllerWithTableView:self.tableView];
self.tableController.delegate = self;
self.tableController.imageForEmpty = [UIImage imageNamed:@"no_high_flyers "];
self.tableController.imageForOffline = [UIImage imageNamed:@"offline "];
[self.tableController mapObjectsWithClass:[GGHighFlyer class] toTableCellsWithMapping:
[RKTableViewCellMapping cellMappingWithBlock:^(RKTableViewCellMapping* cellMapping) {
cellMapping.cellClass = [GGHighFlyerTableViewCell class];
cellMapping.selectionStyle = UITableViewCellSelectionStyleNone;
cellMapping.rowHeight = 44;
[cellMapping mapAttributes:@"points", @"login", nil];
cellMapping.onCellWillAppearForObjectAtIndexPath = ^(UITableViewCell* cell, id object,
NSIndexPath* indexPath) {
GGHighFlyerTableViewCell* highFlyerCell = (GGHighFlyerTableViewCell*) cell;
highFlyerCell.captain = (indexPath.row == 0);
highFlyerCell.rank = indexPath.row + 1;
};
}]];
NSString* resourcePath = [NSString stringWithFormat:@"/airports/%@/high_flyers.json", [_airport
airportId]];
NSString* resourcePathWithQueryString = [self addQueryStringToResourcePath:resourcePath];
[self.tableController loadTableFromResourcePath:resourcePathWithQueryString];
}
27
Wednesday, September 14, 11
28
Wednesday, September 14, 11
Building a Form
- (void)changePasswordForm {
GGUser *user = [GGUser user];
RKForm *form = [RKForm formForObject:user withBlock:^(RKForm *form) {
[form addRowForAttribute:@"password"
withControlType:RKFormControlTypeTextFieldSecure block:^(RKControlTableItem
*tableItem) {
tableItem.textField.placeholder = @"New Password";
tableItem.textField.returnKeyType = UIReturnKeyDone;
tableItem.textField.keyboardAppearance = UIKeyboardAppearanceAlert;
}];
form.onSubmit = ^{
NSError* error = nil;
GGUser *user = (GGUser *) form.object;
if (! [[GGUser user] changePassword:user.password error:&error]) {
GGAlertWithTitleAndMessage(@"Invalid Password", [error
localizedDescription]);
}
};
}];
[self.tableController loadForm:form];
}
29
Wednesday, September 14, 11
30
Wednesday, September 14, 11
Thank You!
http://restkit.org/
Tweets by RestKit
http://github.com/RestKit/RestKit
Wednesday, September 14, 11
http://restkit.org
http://restkit.org
Tweets by RestKit
Tweets by RestKit
http://github.com/RestKit/RestKit/
http://github.com/RestKit/RestKit/
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Presentations/Introduction to RestKit/._Introduction to RestKit
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/Presentations/._Introduction to RestKit
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._Presentations
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/TESTING.mdRestKit Test Environment
========================
RestKit ships with a testing infrastructure built around OCUnit and
a Ruby testing server environment built on Sinatra. To be able to run the
tests, you need to do a little bit of setup. These instructions are value for **Xcode version 4.3 and higher**.
1. Install the Xcode **Command Line Tools** by selecting the **Xcode** > **Preferences…** menu and then navigating to the **Downloads** tab, then clicking the **Install** button next to the appropriate entry in the table.
2. After installation completes, ensure your command line Xcode installation is configured by executing `xcode-select -print-path`. If no path is returned, configure xcode-select by executing `xcode-select -switch /Applications/Xcode.app/Contents/Developer`.
1. Ensure that you have **Ruby 1.9.2** available. We recommend installation via [RVM](http://beginrescueend.com/rvm/install/) or [Homebrew](http://mxcl.github.com/homebrew/).
1. Install the Ruby Bundler Gem (if necessary): `gem install bundler`
1. Install the other required Gems via Bundler: `bundle`
1. Start the Test server: `rake server`
1. Build and execute the tests within Xcode via the **Product** > **Test** menu or on the command line via `rake`.
If the project builds the RestKitTests target correctly and executes the suite, then
you are all set. If there are any issues, you may need to reach out to us via a Github issue for help debugging.
Running Tests
-------------
### Within Xcode
By default, all tests will be executed when your run the **Test** build action. You can selectively
enable/disable which tests are run by holding down the Option Key when selecting **Product** > **Test**
(or type Apple+Option+U).
### On the Command Line
RestKit includes full support for executing the test suite via the commandline via the excellent [Xcoder](https://github.com/rayh/xcoder) gem. The suite can be run in its entirety or as individual pieces targetting subsets of the suite. Test execution is performed via the `rake` tool. A list of the available test tasks as of this writing (obtained via `rake -T test`) follows:
rake test # Run all the GateGuru tests
rake test:all # Run all tests for iOS and OS X
rake test:application # Run the application tests for iOS
rake test:application:ios # Run the application tests for iOS
rake test:logic # Run the unit tests for iOS and OS X
rake test:logic:ios # Run the logic tests for iOS
rake test:logic:osx # Run the logic tests for OS X
Rake is also used for a number of other automation tasks in the project. Consult the full list of tasks via `rake -T` for more info.
Test Server
-------------
RestKit includes a [Sinatra](http://www.sinatrarb.com/) powered test server that is required to exercise the majority of the HTTP specific functionality within the library. Execution of the test server is handled via a rich library of Rake tasks provided by the [RestKit Gem](https://github.com/RestKit/RestKit-Gem).
The server can be run interactively or daemonized into a background process. Tasks are provided for stopping, starting, restarting, tailing the logs of a backgrounded process, and for automatically starting and stopping the server via Rake task dependencies. A list of the available server tasks as of this writing (as obtained via `rake -T server`) follows:
rake server # Run the Test server in the foreground
rake server:abort_unless_running # Abort the task chain unless the Test server is running
rake server:autostart # Starts the server if there is not already an instance running
rake server:autostop # Stops the server if executed via autostart
rake server:logs # Dumps the last 25 lines from the Test server logs
rake server:logs:tail # Tails the Test server logs
rake server:restart # Restart the Test server daemon
rake server:start # Start the Test server daemon
rake server:status # Check the status of the Test server daemon
rake server:stop # Stop the Test server daemon
The tasks are reusable via the RestKit gem and can be used to provide a test server for applications using RestKit as well. Details about configuring the RestKit gem to quickly build an application specific test server are available on the [RestKit Gem Github Page](https://github.com/RestKit/RestKit-Gem). An example application leveraging the test server is provided in the [RKGithub](https://github.com/RestKit/RKGithub) application.
Writing Tests
-------------
RestKit tests are divided into two portions. There are pure unit tests, which only require the test harness to be
configured and there are integration tests that test the full request/response life-cycle. In general, testing RestKit is very straight-forward. There are only a few items to keep in mind:
1. Tests are implemented in Objective-C and run inside the Simulator or on the Device.
1. Test files live in sub-directories under Tests/ appropriate to the layer the code under test belongs to
1. Tests begin with "test" and should be camel-cased descriptive. i.e. testShouldConsiderA200ResponseSuccessful
1. Expectations are provided using OCHamcrest. Details of the matchers are available on the [OCHamcrest Github Page](http://jonreid.github.com/OCHamcrest/). Generally the matchers are of the form:
assertThat([someObject someMethod], is(equalTo(@"some value")));
There is a corresponding `isNot` method available as well.
1. The RKTestEnvironment.h header includes a number of helpers for initializing and configuring a clean testing environment.
1. OCMock is available for mock objects support. See [http://www.mulle-kybernetik.com/software/OCMock/](http://www.mulle-kybernetik.com/software/OCMock/) for details
1. RestKit is available for 32bit (iOS) and 64bit (OS X) platforms. This introduces some complexity when working with integer data types as NSInteger
and NSUInteger are int's on 32bit and long's on 64bit. Cocoa and OC Hamcrest provide helper methods for dealing with these differences. Rather than using the **Int**
flavor of methods (i.e. `[NSNumber numberWithInt:3]`) use the **Integer** flavor (i.e. `[NSNumber numberWithInteger:]`). This will account for the type differences without
generating warnings or requiring casting.
### RestKit Testing Classes
RestKit includes a number of testing specific classes as part of the library that are used within the test suite and are also available for testing applications leveraging RestKit. This functionality is covered in detail in the [Unit Testing with RestKit](https://github.com/RestKit/RestKit/wiki/Unit-Testing-with-RestKit) article on the Github site.
### Writing Integration Tests
RestKit ships with a Sinatra powered specs server for testing portions of the codebase that require interaction
with a web service. Sinatra is a simple Ruby DSL for defining web server. See the [Sinatra homepage](http://www.sinatrarb.com/) for more details.
The Test server is built as a modular Sinatra application in the Tests/Server subdirectory of the RestKit distribution. When you are adding new integration test coverage to the library, you may need to add new routes to Sinatra to serve your needs. By convention, these are namespaced by functional unit for simplicity. For example, if we are adding a new
cacheing component to the application and want to test the functionality, we might add a new route to the Test server at Tests/Server/server.rb like so:
get '/cacheing/index' do
"OK"
end
You now have a functional server-side component to work with. Consult the Sinatra documentation for example on setting
response headers, MIME types, etc. It's all very simple and low ceremony.
You can now switch to the RestKit sources and look in the Tests directory. Keeping with the cacheing example, we would create a new RKCacheingTest.m file and pull in RKSTestEnvironment.h. From there we can utilize `RKTestResponseLoader` to asynchronously test
the entire request/response cycle. The response loader essentially spins the run-loop to allow background processing to execute and
simulate a blocking API. The response, objects, or errors generated by processing the response are made available via properties
on the RKTestResponseLoader object.
Let's take a look at an example of how to use the response loader to test some functionality:
- (void)testShouldFailAuthenticationWithInvalidCredentialsForHTTPAuthBasic {
RKSpecResponseLoader *loader = [RKTestResponseLoader responseLoader];
RKClient *client = [RKTestFactory client];
client.username = RKAuthenticationTestUsername;
client.password = @"INVALID";
[client get:@"/authentication/basic" delegate:loader];
[loader waitForResponse];
assertThatBool([loader.response isOK], is(equalToBool(NO)));
assertThatInt([loader.response statusCode], is(equalToInt(0)));
assertThatInt([loader.failureError code], is(equalToInt(NSURLErrorUserCancelledAuthentication)));
}
That's really all there is to it. Consult the existing test code in Tests/ for reference.
Continuous Integration
-------------
The RestKit team keeps the master, development, and active branches of RestKit under the watchful eye of the [Jenkins Continuous Integration Server](http://jenkins-ci.org/). There is a fair amount of complexity involved in getting iOS projects running under Jenkins, so to make things as easy as possible all Jenkins configuration has been collected into a single script within the source code. Currently use of the Jenkins build **requires** the use of RVM for managing the Ruby environment.
To configure Jenkins to build RestKit, do the following:
1. Ensure the RestKit test suite executes cleanly on the CI host using the above reference.
1. Install Jenkins (again, we recommend [Homebrew](http://mxcl.github.com/)): `brew install jenkins`
2. Install Jenkins as a system service. Instructions are printed post installation via Homebrew
3. Configure your CI user's OS X account to automatically manage the RVM environment. Create an `~/.rvmrc` file and populate it with the following:
```bash
export rvm_install_on_use_flag=1
export rvm_gemset_create_on_use_flag=1
export rvm_trust_rvmrcs_flag=1
export rvm_always_trust_rvmrc_flag=1
```
4. Install the Git plugin for Jenkins and configure it for the fork you are tracking.
5. Create a Jenkins project for building RestKit within the Jenkins UI.
6. Add an **Execute shell** build step to the Jenkins project with a Command value of: `bash -x ./Tests/cibuild`
7. Save the project and tap the **Build Now** button to force Jenkins to build the project.
When the RestKit build is invoked, the cibuild script will leverage Bundler to bundle all the required Ruby gems and then start up an instance of the test server on port 4567, execute all the tests, then shut down the server.
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._TESTING.md
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/WRITING_DOCS.mdWriting Documentation
=====================
RestKit utilizes the excellent [Appledoc](http://www.gentlebytes.com/home/appledocapp/) utility from [Gentle Bytes](http://www.gentlebytes.com/).
Appledoc provides a commandline utility for parsing and generating documentation from Objective-C code in HTML and DocSet format. This HTML can be
published to the Web and installed directly within Xcode.
To generate meaningful and informative documentation, Appledoc needs support in the form of markup within the header files. This document
seeks to outline the process for marking up RestKit headers to generate great end-user documentation directly from the source code.
## Generating Documentation
RestKit ships with a set of Rake tasks that simplify the task of generating documentation. A compiled x86_64 executable of the Appledoc
utility is provided with the RestKit distribution at the Vendor/appledoc path. Most authors will not need to interact directly with
Appledoc since the process has been automated.
The tasks available for working with Appledoc are:
1. `rake docs:generate` - Generates a set of HTML documentation in Docs/API/html
1. `rake docs:check` - Runs the RestKit sources through the parser to detect any issues preventing documentation generation
1. `rake docs:install` - Generates and installs an Xcode DocSet viewable through the Xcode organizer and integrated help viewer
## Writing Documentation
Writing documentation in Appledoc markup is simple. There is extensive documentation available on the [Appledoc project page](http://tomaz.github.com/appledoc/comments.html), but
the guidelines below should be sufficient for basic authoring tasks. For clarity, let's consider the following example class:
/**
* Demonstrates how to document a RestKit class using Appledoc
*
* This class provides a simple boilerplate example for how to properly document
* RestKit classes using the Appledoc system. This paragraph forms the details
* description of the class and will be presented in detail
@interface RKDocumentationExample : NSObject {
NSString* _name;
NSString* _rank;
NSString* _serialNumber;
}
/// @name Demonstrates Documentation Task Groups
/**
* Returns the name of the person in this documentation example
*
* This property is *important* and that's why the preceeding text will be bolded
*/
@property (nonatomic, retain) NSString* name;
/**
* The rank of this example in the theoretical documentation hierarchy
*
* This one is _somewhat important_, so we emphasized that text
*
* Can be one of the following unordered lists:
* - Captain
* - General
* - Private
*/
@property (nonatomic, retain) NSString* rank;
/**
* Serial number for this example, as issued by the Colonial Fleet of the 12 Colonies of Kobol
*
* @warning Somebody might be a Cylon
@ @see RKDocumentationSerialNumberGenerator
*/
@property (nonatomic, retain) NSString* serialNumber;
/**
* Promotes the example to the rank specified
*
* For example: `[exampleObject promoteToRank:@"General"];`
*
* @bug This might be broken
* @param rank The rank to promote the example to
*/
- (void)promoteToRank:(NSString*)rank;
/**
* Returns the next rank for this example.
*
* @return The next rank this example could be promoted to
* @exception RKInvalidRankException Raised when there is no current rank
*/
- (NSString*)nextRank;
@end
1. Documentation blocks must precede the item being documented and begin with a slash and a double star. They must be terminated with a single star and a slash.
1. The first paragraph forms the short description of the entity being documented.
1. The second paragraph forms the long description of the entity and can contain an arbitrary number of paragraphs.
1. Methods & properties can be grouped together by using the @name directive. The directive must follow 3 delimiting characters. RestKit standard is '///'
1. Text can be bolded and italicized using Markdown standard (i.e. *bolded* and _italicized_)
1. Markdown text such as unordered and ordered lists and links can be embedded into the descriptions as appropriate.
1. @warning and @bug can be used to call out specific warnings and known issues in the codebase
1. Code spans can be embedded by using backticks
1. Method arguments should be documented clearly using "@param Brief description here"
1. Method return values should be documented using "@return A description of the return value"
1. Exceptions should be documented using "@exception
1. Cross references to other parts of the codebase can be generated via "@see SomeOtherClass" or "@see [SomeClass someMethod:withArguments:]"
## Submitting Documentation
If you want to contribute documentation, the process is simple:
1. Fork the codebase from the current development branch
1. Generate a set of docs to work with via `rake docs` and open `Docs/API/html/index.html` in your browser
1. Edit the headers in Code/ and regenerate the docs via `rake docs`
1. Repeat the editing and reload cycle until your are happy.
1. Commit the code and push to Github
1. Submit a Pull Request to the RestKit repository on Github at: https://github.com/RestKit/RestKit/pull/new/master
You may want to coordinate your efforts via the mailing list to ensure nobody else is working on documentation in the same place.
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Docs/._WRITING_DOCS.md
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Docs
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/main.m//
// main.m
// RestKit CLI
//
// Created by Blake Watters on 10/15/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
int main (int argc, const char * argv[])
{
@autoreleasepool {
RKLogConfigureByName("App", RKLogLevelTrace);
// Validate arguments
if (argc < 2) {
printf("usage: %s path/to/file [keyPath]\n", argv[0]);
printf("Parses the specified file and outputs the payload.\n"
"If keyPath is provided it will be evaluated against the payload and the result printed.\n");
return 0;
}
NSString *filePathOrURL = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
NSURL *URL = nil;
NSString *keyPath = nil;
if ([filePathOrURL rangeOfString:@"://"].length == 0) {
// Local file
URL = [NSURL fileURLWithPath:filePathOrURL];
} else {
// Web URL
URL = [NSURL URLWithString:filePathOrURL];
}
if (argc == 3) keyPath = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding];
NSError *error = nil;
NSString *payload = [NSString stringWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];
if (!payload) {
RKLogError(@"Failed to read file at path %@: %@", URL, error);
return 0;
}
NSString *MIMEType = [[URL absoluteString] MIMETypeForPathExtension];
RKLogInfo(@"Parsing %@ using MIME Type: %@", URL, MIMEType);
id
id parsedData = [parser objectFromString:payload error:&error];
if (!parsedData) {
RKLogError(@"Failed to parse file: %@", error);
RKLogError(@"Payload => %@", payload);
return 0;
}
RKLogInfo(@"Parsed data => %@", parsedData);
if (keyPath) RKLogInfo(@"valueForKeyPath:@\"%@\" => %@", keyPath, [parsedData valueForKeyPath:keyPath]);
}
return 0;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/._main.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/RestKit CLI-Prefix.pch//
// Prefix header for all source files of the 'RestKit CLI' target in the 'RestKit CLI' project
//
#ifdef __OBJC__
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/._RestKit CLI-Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/RestKit_CLI.1.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
.\"See Also:
.\"man mdoc.samples for a complete listing of options
.\"man mdoc for the short list of editing options
.\"/usr/share/misc/mdoc.template
.Dd 10/15/11 \" DATE
.Dt RestKit CLI 1 \" Program name and manual section number
.Os Darwin
.Sh NAME \" Section Header - required - don't modify
.Nm RestKit CLI,
.\" The following lines are read in generating the apropos(man -k) database. Use only key
.\" words here as the database is built based on the words here and in the .ND line.
.Nm Other_name_for_same_program(),
.Nm Yet another name for the same program.
.\" Use .Nm macro to designate other names for the documented program.
.Nd This line parsed for whatis database.
.Sh SYNOPSIS \" Section Header - required - don't modify
.Nm
.Op Fl abcd \" [-abcd]
.Op Fl a Ar path \" [-a path]
.Op Ar file \" [file]
.Op Ar \" [file ...]
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
arg2 ... \" Arguments
.Sh DESCRIPTION \" Section Header - required - don't modify
Use the .Nm macro to refer to your program throughout the man page like such:
.Nm
Underlining is accomplished with the .Ar macro like this:
.Ar underlined text .
.Pp \" Inserts a space
A list of items with descriptions:
.Bl -tag -width -indent \" Begins a tagged list
.It item a \" Each item preceded by .It macro
Description of item a
.It item b
Description of item b
.El \" Ends the list
.Pp
A list of flags and their descriptions:
.Bl -tag -width -indent \" Differs from above in tag removed
.It Fl a \"-a flag as a list item
Description of -a flag
.It Fl b
Description of -b flag
.El \" Ends the list
.Pp
.\" .Sh ENVIRONMENT \" May not be needed
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
.\" .It Ev ENV_VAR_1
.\" Description of ENV_VAR_1
.\" .It Ev ENV_VAR_2
.\" Description of ENV_VAR_2
.\" .El
.Sh FILES \" File used or created by the topic of the man page
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
.It Pa /usr/share/file_name
FILE_1 description
.It Pa /Users/joeuser/Library/really_long_file_name
FILE_2 description
.El \" Ends the list
.\" .Sh DIAGNOSTICS \" May not be needed
.\" .Bl -diag
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .El
.Sh SEE ALSO
.\" List links in ascending order by section, alphabetically within a section.
.\" Please do not reference files that do not exist without filing a bug report
.Xr a 1 ,
.Xr b 1 ,
.Xr c 1 ,
.Xr a 2 ,
.Xr b 2 ,
.Xr a 3 ,
.Xr b 3
.\" .Sh BUGS \" Document known, unremedied bugs
.\" .Sh HISTORY \" Document history if command behaves in a unique manner
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI/._RestKit_CLI.1
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/._RestKit CLI
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
250DF27B14C684510001DEFA /* RestKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A3422B147D885B0009758D /* RestKit.framework */; };
2516F0FC144A8577004631A1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516F0FB144A8577004631A1 /* Foundation.framework */; };
2516F0FF144A8577004631A1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516F0FE144A8577004631A1 /* main.m */; };
2516F103144A8577004631A1 /* RestKit_CLI.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2516F102144A8577004631A1 /* RestKit_CLI.1 */; };
2516F15E144A8923004631A1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516F15D144A8923004631A1 /* SystemConfiguration.framework */; };
2516F160144A895E004631A1 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516F15F144A895E004631A1 /* libxml2.dylib */; };
2516F162144A8AED004631A1 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516F161144A8AED004631A1 /* CoreServices.framework */; };
25A34230147D88630009758D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A3422F147D88620009758D /* Security.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
25678093152D124D000725F5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 259C301615128079003066A2;
remoteInfo = RestKitResources;
};
25A34226147D885B0009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D1614564E810060A5C5;
remoteInfo = RestKit;
};
25A34228147D885B0009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D2614564E820060A5C5;
remoteInfo = RestKitTests;
};
25A3422A147D885B0009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E62145651060060A5C5;
remoteInfo = RestKitFramework;
};
25A3422C147D885B0009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E78145651060060A5C5;
remoteInfo = RestKitFrameworkTests;
};
25A3423E147D89DC0009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160E61145651060060A5C5;
remoteInfo = RestKitFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
2516F0F5144A8577004631A1 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
2516F103144A8577004631A1 /* RestKit_CLI.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2516F0F7144A8577004631A1 /* rkkeypath */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = rkkeypath; sourceTree = BUILT_PRODUCTS_DIR; };
2516F0FB144A8577004631A1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
2516F0FE144A8577004631A1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "
2516F101144A8577004631A1 /* RestKit CLI-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RestKit CLI-Prefix.pch"; sourceTree = "
2516F102144A8577004631A1 /* RestKit_CLI.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = RestKit_CLI.1; sourceTree = "
2516F10D144A8841004631A1 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../../RestKit.xcodeproj; sourceTree = "
2516F15D144A8923004631A1 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
2516F15F144A895E004631A1 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
2516F161144A8AED004631A1 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
25A3422F147D88620009758D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2516F0F4144A8577004631A1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
250DF27B14C684510001DEFA /* RestKit.framework in Frameworks */,
25A34230147D88630009758D /* Security.framework in Frameworks */,
2516F162144A8AED004631A1 /* CoreServices.framework in Frameworks */,
2516F160144A895E004631A1 /* libxml2.dylib in Frameworks */,
2516F15E144A8923004631A1 /* SystemConfiguration.framework in Frameworks */,
2516F0FC144A8577004631A1 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2516F0EC144A8577004631A1 = {
isa = PBXGroup;
children = (
2516F0FD144A8577004631A1 /* RestKit CLI */,
2516F0FA144A8577004631A1 /* Frameworks */,
2516F0F8144A8577004631A1 /* Products */,
2516F10D144A8841004631A1 /* RestKit.xcodeproj */,
);
sourceTree = "
};
2516F0F8144A8577004631A1 /* Products */ = {
isa = PBXGroup;
children = (
2516F0F7144A8577004631A1 /* rkkeypath */,
);
name = Products;
sourceTree = "
};
2516F0FA144A8577004631A1 /* Frameworks */ = {
isa = PBXGroup;
children = (
25A3422F147D88620009758D /* Security.framework */,
2516F15F144A895E004631A1 /* libxml2.dylib */,
2516F161144A8AED004631A1 /* CoreServices.framework */,
2516F15D144A8923004631A1 /* SystemConfiguration.framework */,
2516F0FB144A8577004631A1 /* Foundation.framework */,
);
name = Frameworks;
sourceTree = "
};
2516F0FD144A8577004631A1 /* RestKit CLI */ = {
isa = PBXGroup;
children = (
2516F0FE144A8577004631A1 /* main.m */,
2516F102144A8577004631A1 /* RestKit_CLI.1 */,
2516F100144A8577004631A1 /* Supporting Files */,
);
path = "RestKit CLI";
sourceTree = "
};
2516F100144A8577004631A1 /* Supporting Files */ = {
isa = PBXGroup;
children = (
2516F101144A8577004631A1 /* RestKit CLI-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "
};
2516F10E144A8841004631A1 /* Products */ = {
isa = PBXGroup;
children = (
25A34227147D885B0009758D /* libRestKit.a */,
25A34229147D885B0009758D /* RestKitTests.octest */,
25A3422B147D885B0009758D /* RestKit.framework */,
25A3422D147D885B0009758D /* RestKitFrameworkTests.octest */,
25678094152D124D000725F5 /* RestKitResources.bundle */,
);
name = Products;
sourceTree = "
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
2516F0F6144A8577004631A1 /* RestKit CLI */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2516F106144A8577004631A1 /* Build configuration list for PBXNativeTarget "RestKit CLI" */;
buildPhases = (
2516F0F3144A8577004631A1 /* Sources */,
2516F0F4144A8577004631A1 /* Frameworks */,
2516F0F5144A8577004631A1 /* CopyFiles */,
2516F28E144AB1F1004631A1 /* Copy to Tools */,
);
buildRules = (
);
dependencies = (
25A3423F147D89DC0009758D /* PBXTargetDependency */,
);
name = "RestKit CLI";
productName = "RestKit CLI";
productReference = 2516F0F7144A8577004631A1 /* rkkeypath */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2516F0EE144A8577004631A1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
};
buildConfigurationList = 2516F0F1144A8577004631A1 /* Build configuration list for PBXProject "RestKit CLI" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 2516F0EC144A8577004631A1;
productRefGroup = 2516F0F8144A8577004631A1 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 2516F10E144A8841004631A1 /* Products */;
ProjectRef = 2516F10D144A8841004631A1 /* RestKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
2516F0F6144A8577004631A1 /* RestKit CLI */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
25678094152D124D000725F5 /* RestKitResources.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitResources.bundle;
remoteRef = 25678093152D124D000725F5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A34227147D885B0009758D /* libRestKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRestKit.a;
remoteRef = 25A34226147D885B0009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A34229147D885B0009758D /* RestKitTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitTests.octest;
remoteRef = 25A34228147D885B0009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A3422B147D885B0009758D /* RestKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = RestKit.framework;
remoteRef = 25A3422A147D885B0009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A3422D147D885B0009758D /* RestKitFrameworkTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitFrameworkTests.octest;
remoteRef = 25A3422C147D885B0009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXShellScriptBuildPhase section */
2516F28E144AB1F1004631A1 /* Copy to Tools */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy to Tools";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cp \"${BUILT_PRODUCTS_DIR}/rkkeypath\" \"${SOURCE_ROOT}/../../Tools\"";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2516F0F3144A8577004631A1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2516F0FF144A8577004631A1 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
25A3423F147D89DC0009758D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKitFramework;
targetProxy = 25A3423E147D89DC0009758D /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
2516F104144A8577004631A1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
2516F105144A8577004631A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
};
name = Release;
};
2516F107144A8577004631A1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RestKit CLI/RestKit CLI-Prefix.pch";
HEADER_SEARCH_PATHS = ../../Build;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = rkkeypath;
};
name = Debug;
};
2516F108144A8577004631A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RestKit CLI/RestKit CLI-Prefix.pch";
HEADER_SEARCH_PATHS = ../../Build;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = rkkeypath;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2516F0F1144A8577004631A1 /* Build configuration list for PBXProject "RestKit CLI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2516F104144A8577004631A1 /* Debug */,
2516F105144A8577004631A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2516F106144A8577004631A1 /* Build configuration list for PBXNativeTarget "RestKit CLI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2516F107144A8577004631A1 /* Debug */,
2516F108144A8577004631A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2516F0EE144A8577004631A1 /* Project object */;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI.xcodeproj/._project.pbxproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/RestKit CLI.xcodeproj/._project.xcworkspace
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RestKit CLI/._RestKit CLI.xcodeproj
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/._RestKit CLI
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/InfoPlist.strings/* Localized versions of Info.plist keys */
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/._InfoPlist.strings
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/MainWindow.xib
1024
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBProxyObject
IBUINavigationController
IBUIViewController
IBUICustomObject
IBUIWindow
IBUINavigationBar
IBUINavigationItem
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
IBCocoaTouchFramework
1316
{320, 480}
1
MSAxIDEAA
NO
NO
IBCocoaTouchFramework
YES
1
1
IBCocoaTouchFramework
NO
256
{0, 0}
NO
YES
YES
IBCocoaTouchFramework
YES
RestKit
IBCocoaTouchFramework
RootViewController
1
1
IBCocoaTouchFramework
NO
YES
delegate
4
window
5
navigationController
15
YES
0
2
YES
-1
File's Owner
3
-2
9
YES
11
13
YES
14
Navigation Item - RestKit
YES
YES
-1.CustomClassName
-2.CustomClassName
11.IBPluginDependency
13.CustomClassName
13.IBPluginDependency
2.IBAttributePlaceholdersKey
2.IBEditorWindowLastContentRect
2.IBPluginDependency
3.CustomClassName
3.IBPluginDependency
9.IBEditorWindowLastContentRect
9.IBPluginDependency
YES
UIApplication
UIResponder
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
RootViewController
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
{{673, 376}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
RKCatalogAppDelegate
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
{{186, 376}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
16
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/._MainWindow.xib
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/RootViewController.xib
784
10D541
760
1038.29
460.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
81
YES
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
{320, 247}
3
MQA
NO
YES
NO
IBCocoaTouchFramework
NO
1
0
YES
44
22
22
YES
view
3
dataSource
4
delegate
5
YES
0
-1
File's Owner
-2
2
YES
YES
-1.CustomClassName
-2.CustomClassName
2.IBEditorWindowLastContentRect
2.IBPluginDependency
YES
RootViewController
UIResponder
{{144, 609}, {320, 247}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
YES
5
YES
RootViewController
UITableViewController
IBProjectSource
RootViewController.h
YES
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSError.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSFileManager.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyValueCoding.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyValueObserving.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyedArchiver.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSNetServices.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSObject.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSPort.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSRunLoop.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSStream.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSThread.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSURL.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSURLConnection.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSXMLParser.h
NSObject
IBFrameworkSource
UIKit.framework/Headers/UIAccessibility.h
NSObject
IBFrameworkSource
UIKit.framework/Headers/UINibLoading.h
NSObject
IBFrameworkSource
UIKit.framework/Headers/UIResponder.h
UIResponder
NSObject
UIScrollView
UIView
IBFrameworkSource
UIKit.framework/Headers/UIScrollView.h
UISearchBar
UIView
IBFrameworkSource
UIKit.framework/Headers/UISearchBar.h
UISearchDisplayController
NSObject
IBFrameworkSource
UIKit.framework/Headers/UISearchDisplayController.h
UITableView
UIScrollView
IBFrameworkSource
UIKit.framework/Headers/UITableView.h
UITableViewController
UIViewController
IBFrameworkSource
UIKit.framework/Headers/UITableViewController.h
UIView
IBFrameworkSource
UIKit.framework/Headers/UITextField.h
UIView
UIResponder
IBFrameworkSource
UIKit.framework/Headers/UIView.h
UIViewController
IBFrameworkSource
UIKit.framework/Headers/UINavigationController.h
UIViewController
IBFrameworkSource
UIKit.framework/Headers/UITabBarController.h
UIViewController
UIResponder
IBFrameworkSource
UIKit.framework/Headers/UIViewController.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
RKCatalog.xcodeproj
3
81
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/en.lproj/._RootViewController.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._en.lproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/main.m//
// main.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._main.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RKCatalog-Info.plist
CFBundleDevelopmentRegion
en
CFBundleDisplayName
${PRODUCT_NAME}
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
org.restkit.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1.0
LSRequiresIPhoneOS
NSMainNibFile
MainWindow
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RKCatalog-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RKCatalog-Prefix.pch//
// Prefix header for all source files of the 'RKCatalog' target in the 'RKCatalog' project
//
#import
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import
#import
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RKCatalog-Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RKCatalog.h//
// RKCatalog.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
#import
// Import the base URL defined in the app delegate
extern NSURL* gRKCatalogBaseURL;
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RKCatalog.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RKCatalogAppDelegate.h//
// RKCatalogAppDelegate.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@interface RKCatalogAppDelegate : NSObject
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RKCatalogAppDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RKCatalogAppDelegate.m//
// RKCatalogAppDelegate.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalogAppDelegate.h"
#import "RootViewController.h"
NSURL *gRKCatalogBaseURL = nil;
@implementation RKCatalogAppDelegate
@synthesize window;
@synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
gRKCatalogBaseURL = [[NSURL alloc] initWithString:@"http://rkcatalog.heroku.com"];
return YES;
}
- (void)dealloc {
[window release];
[navigationController release];
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RKCatalogAppDelegate.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RootViewController.h//
// RootViewController.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@interface RootViewController : UITableViewController
NSArray* _exampleTableItems;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RootViewController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/RootViewController.m//
// RootViewController.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RootViewController.h"
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
_exampleTableItems = [[NSArray alloc] initWithObjects:
@"RKAuthenticationExample",
@"RKParamsExample",
@"RKRequestQueueExample",
@"RKReachabilityExample",
@"RKBackgroundRequestExample",
@"RKKeyValueMappingExample",
@"RKRelationshipMappingExample",
@"RKCoreDataExample",
nil];
}
- (void)dealloc {
[_exampleTableItems release];
[super dealloc];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_exampleTableItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"RKCatalogCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSString* exampleName = [_exampleTableItems objectAtIndex:indexPath.row];
cell.textLabel.text = exampleName;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Clear the singleton instances to isolate the examples
[RKClient setSharedClient:nil];
[RKObjectManager setSharedManager:nil];
NSString* exampleName = [_exampleTableItems objectAtIndex:indexPath.row];
Class exampleClass = NSClassFromString(exampleName);
UIViewController* exampleController = [[exampleClass alloc] initWithNibName:exampleName bundle:nil];
if (exampleController) {
[self.navigationController pushViewController:exampleController animated:YES];
if (exampleController.title == nil) {
exampleController.title = exampleName;
}
[exampleController release];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/App/._RootViewController.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/._App
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/RKAuthenticationExample.h//
// RKAuthenticationExample.h
// RKCatalog
//
// Created by Blake Watters on 9/27/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKCatalog.h"
@interface RKAuthenticationExample : UIViewController
@property (nonatomic, retain) RKRequest *authenticatedRequest;
@property (nonatomic, retain) IBOutlet UITextField *URLTextField;
@property (nonatomic, retain) IBOutlet UITextField *usernameTextField;
@property (nonatomic, retain) IBOutlet UITextField *passwordTextField;
@property (nonatomic, retain) IBOutlet UIPickerView *authenticationTypePickerView;
- (IBAction)sendRequest;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/._RKAuthenticationExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/RKAuthenticationExample.m//
// RKAuthenticationExample.m
// RKCatalog
//
// Created by Blake Watters on 9/27/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKAuthenticationExample.h"
@implementation RKAuthenticationExample
@synthesize authenticatedRequest;
@synthesize URLTextField;
@synthesize usernameTextField;
@synthesize passwordTextField;
@synthesize authenticationTypePickerView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
RKClient *client = [RKClient clientWithBaseURL:gRKCatalogBaseURL];
[RKClient setSharedClient:client];
}
return self;
}
- (void)dealloc {
[authenticatedRequest cancel];
[authenticatedRequest release];
authenticatedRequest = nil;
[super dealloc];
}
/**
We are constructing our own RKRequest here rather than working with the client.
It is important to remember that RKClient is really just a factory object for instances
of RKRequest. At any time you can directly configure an RKRequest instead.
*/
- (void)sendRequest {
NSURL *URL = [NSURL URLWithString:[URLTextField text]];
RKRequest *newRequest = [RKRequest requestWithURL:URL];
newRequest.delegate = self;
newRequest.authenticationType = RKRequestAuthenticationTypeHTTP;
newRequest.username = [usernameTextField text];
newRequest.password = [passwordTextField text];
self.authenticatedRequest = newRequest;
}
- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
RKLogError(@"Load of RKRequest %@ failed with error: %@", request, error);
[request release];
}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
RKLogCritical(@"Loading of RKRequest %@ completed with status code %d. Response body: %@", request, response.statusCode, [response bodyAsString]);
[request release];
}
#pragma mark - UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 0;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/._RKAuthenticationExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/RKAuthenticationExample.xib
1280
11B26
1934
1138
566.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
931
IBUIPickerView
IBUIButton
IBUIView
IBUITextField
IBProxyObject
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
PluginDependencyRecalculationVersion
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
-2147483358
{{0, 244}, {320, 216}}
_NS:650
IBCocoaTouchFramework
YES
292
{{20, 20}, {280, 31}}
_NS:304
NO
YES
IBCocoaTouchFramework
0
3
URL
3
MAA
2
YES
17
3
IBCocoaTouchFramework
1
14
Helvetica
14
16
292
{{19, 67}, {130, 31}}
_NS:304
NO
YES
IBCocoaTouchFramework
0
3
Username
3
MAA
YES
17
1
7
IBCocoaTouchFramework
292
{{170, 67}, {130, 31}}
_NS:304
NO
YES
IBCocoaTouchFramework
0
3
Password
3
MAA
YES
17
1
IBCocoaTouchFramework
292
{{227, 139}, {72, 37}}
_NS:225
NO
IBCocoaTouchFramework
0
0
1
Go
3
MQA
1
MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
3
MC41AA
2
15
Helvetica-Bold
15
16
{{0, 20}, {320, 460}}
3
MQA
IBCocoaTouchFramework
view
3
authenticationTypePickerView
11
URLTextField
12
usernameTextField
13
passwordTextField
14
dataSource
15
delegate
16
sendRequest
7
17
0
1
-1
File's Owner
-2
4
5
6
7
8
RKAuthenticationExample
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
UIResponder
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
17
RKAuthenticationExample
UIViewController
sendRequest
id
sendRequest
sendRequest
id
UITextField
UIPickerView
UITextField
UITextField
URLTextField
UITextField
authenticationTypePickerView
UIPickerView
passwordTextField
UITextField
usernameTextField
UITextField
IBProjectSource
./Classes/RKAuthenticationExample.h
0
IBCocoaTouchFramework
YES
3
931
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKAuthenticationExample/._RKAuthenticationExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKAuthenticationExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/RKBackgroundRequestExample.h//
// RKBackgroundRequestExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKBackgroundRequestExample : UIViewController
UIButton* _sendButton;
UISegmentedControl* _segmentedControl;
UILabel* _statusLabel;
}
@property (nonatomic, retain) IBOutlet UIButton* sendButton;
@property (nonatomic, retain) IBOutlet UISegmentedControl* segmentedControl;
@property (nonatomic, retain) IBOutlet UILabel* statusLabel;
- (IBAction)sendRequest;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/._RKBackgroundRequestExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/RKBackgroundRequestExample.m//
// RKBackgroundRequestExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKBackgroundRequestExample.h"
@implementation RKBackgroundRequestExample
@synthesize sendButton = _sendButton;
@synthesize segmentedControl = _segmentedControl;
@synthesize statusLabel = _statusLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
RKClient* client = [RKClient clientWithBaseURL:gRKCatalogBaseURL];
[RKClient setSharedClient:client];
}
return self;
}
- (void)dealloc {
[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:self];
[super dealloc];
}
- (IBAction)sendRequest {
RKRequest* request = [[RKClient sharedClient] requestWithResourcePath:@"/RKBackgroundRequestExample"];
request.delegate = self;
request.backgroundPolicy = _segmentedControl.selectedSegmentIndex;
[request send];
_sendButton.enabled = NO;
}
- (void)requestDidStartLoad:(RKRequest *)request {
_statusLabel.text = [NSString stringWithFormat:@"Sent request with background policy %d at %@", request.backgroundPolicy, [NSDate date]];
}
- (void)requestDidTimeout:(RKRequest *)request {
_statusLabel.text = @"Request timed out during background processing";
_sendButton.enabled = YES;
}
- (void)requestDidCancelLoad:(RKRequest *)request {
_statusLabel.text = @"Request canceled";
_sendButton.enabled = YES;
}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
_statusLabel.text = [NSString stringWithFormat:@"Request completed with response: '%@'", [response bodyAsString]];
_sendButton.enabled = YES;
}
- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
_statusLabel.text = [NSString stringWithFormat:@"Request failed with error: %@", [error localizedDescription]];
_sendButton.enabled = YES;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/._RKBackgroundRequestExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/RKBackgroundRequestExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBUIButton
IBUISegmentedControl
IBUIView
IBUILabel
IBProxyObject
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
YES
274
{{12, 15}, {288, 166}}
NO
YES
7
NO
IBCocoaTouchFramework
Select the background policy to test. The server will take 5 seconds to respond. Use the home button to background the app and observe the results.
1
MCAwIDAAA
1
10
10
0
292
{{20, 286}, {280, 110}}
NO
YES
7
NO
IBCocoaTouchFramework
1
MCAwIDEAA
1
10
2
292
{{95, 234}, {112, 37}}
NO
IBCocoaTouchFramework
0
0
Helvetica-Bold
15
16
1
Send Request
3
MQA
1
MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
3
MC41AA
292
{{12, 189}, {288, 30}}
NO
IBCocoaTouchFramework
2
4
0
YES
None
Cancel
Continue
Requeue
YES
YES
YES
{0, 0}
{0, 0}
{0, 0}
{0, 0}
YES
{{0, 20}, {320, 460}}
3
MQA
2
IBCocoaTouchFramework
YES
view
3
statusLabel
9
sendRequest
7
10
segmentedControl
16
sendButton
17
YES
0
1
YES
-1
File's Owner
-2
4
5
7
15
YES
YES
-1.CustomClassName
-2.CustomClassName
1.IBEditorWindowLastContentRect
1.IBPluginDependency
15.IBPluginDependency
15.IUISegmentedControlInspectorSelectedSegmentMetadataKey
4.IBPluginDependency
5.IBPluginDependency
7.IBPluginDependency
YES
RKBackgroundRequestExample
UIResponder
{{556, 412}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
17
YES
RKBackgroundRequestExample
UIViewController
sendRequest
id
sendRequest
sendRequest
id
YES
YES
segmentedControl
sendButton
statusLabel
YES
UISegmentedControl
UIButton
UILabel
YES
YES
segmentedControl
sendButton
statusLabel
YES
segmentedControl
UISegmentedControl
sendButton
UIButton
statusLabel
UILabel
IBProjectSource
./Classes/RKBackgroundRequestExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKBackgroundRequestExample/._RKBackgroundRequestExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKBackgroundRequestExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.h//
// RKCoreDataExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKCoreDataExample : UITableViewController {
NSArray* _articles;
UISegmentedControl* _segmentedControl;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/._RKCoreDataExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.m//
// RKCoreDataExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKCoreDataExample.h"
@interface Article : NSManagedObject {
}
@property (nonatomic, retain) NSNumber* articleID;
@property (nonatomic, retain) NSString* title;
@property (nonatomic, retain) NSString* body;
@end
@implementation Article
@dynamic articleID;
@dynamic title;
@dynamic body;
@end
////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
@implementation RKCoreDataExample
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
RKObjectManager* manager = [RKObjectManager managerWithBaseURLString:@"http://restkit.org"];
manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"RKCoreDataExample.sqlite"];
[RKObjectManager setSharedManager:manager];
// Create some starter objects if the database is empty
if ([Article count:nil] == 0) {
for (int i = 1; i <= 5; i++) {
Article* article = [Article object];
article.articleID = [NSNumber numberWithInt:i];
article.title = [NSString stringWithFormat:@"Article %d", i];
article.body = @"This is the body";
// Persist the object store
[manager.objectStore save:nil];
}
}
NSArray* items = [NSArray arrayWithObjects:@"All", @"Sorted", @"By Predicate", @"By ID", nil];
_segmentedControl = [[UISegmentedControl alloc] initWithItems:items];
_segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
_segmentedControl.momentary = NO;
[_segmentedControl addTarget:self action:@selector(updateTableView) forControlEvents:UIControlEventValueChanged];
_segmentedControl.selectedSegmentIndex = 0;
}
return self;
}
- (void)dealloc {
[_articles release];
[_segmentedControl release];
[super dealloc];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 35;
}
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return _segmentedControl;
}
- (NSFetchRequest*)fetchRequestForSelectedSegment {
NSFetchRequest* fetchRequest = [Article fetchRequest];
NSPredicate* predicate = nil;
switch (_segmentedControl.selectedSegmentIndex) {
// All objects
case 0:
// An empty fetch request will return all objects
// Duplicates the functionality of [Article allObjects]
break;
// Sorted
case 1:;
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
break;
// By Predicate
case 2:
// Duplicates functionality of calling [Article objectsWithPredicate:predicate];
predicate = [NSPredicate predicateWithFormat:@"title CONTAINS[c] %@", @"2"];
[fetchRequest setPredicate:predicate];
break;
// By ID
case 3:
// Duplicates functionality of [Article findByAttribute:@"articleID" withValue:[NSNumber numberWithInt:3]];
predicate = [NSPredicate predicateWithFormat:@"%K = %d", @"articleID", 3];
[fetchRequest setPredicate:predicate];
break;
default:
break;
}
return fetchRequest;
}
- (void)updateTableView {
[_articles release];
NSFetchRequest* fetchRequest = [self fetchRequestForSelectedSegment];
_articles = [[Article objectsWithFetchRequest:fetchRequest] retain];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_articles count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"ArticleCell"];
if (nil == cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ArticleCell"] autorelease];
}
Article* article = [_articles objectAtIndex:indexPath.row];
cell.textLabel.text = article.title;
cell.detailTextLabel.text = article.body;
return cell;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/._RKCoreDataExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/.xccurrentversion
_XCCurrentVersionName
RKCoreDataExample.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/._.xccurrentversion
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/RKCoreDataExample.xcdatamodel/elements
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/RKCoreDataExample.xcdatamodel/._elements
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/RKCoreDataExample.xcdatamodel/layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/RKCoreDataExample.xcdatamodel/._layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xcdatamodeld/._RKCoreDataExample.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/._RKCoreDataExample.xcdatamodeld
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/RKCoreDataExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBProxyObject
IBUITableView
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
{{0, 20}, {320, 460}}
10
549453824
{84, 1}
YES
YES
TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB
AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES
AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS
AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA
3
MCAwAA
groupTableViewBackgroundColor
NO
YES
NO
IBCocoaTouchFramework
5
0.0
5
0.0
NO
1
2
0
YES
44
10
10
YES
view
5
dataSource
6
delegate
7
YES
0
-1
File's Owner
-2
4
Table View
YES
YES
-1.CustomClassName
-2.CustomClassName
4.IBEditorWindowLastContentRect
4.IBPluginDependency
YES
RKCoreDataExample
UIResponder
{{329, 504}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
7
YES
RKCoreDataExample
UITableViewController
IBProjectSource
./Classes/RKCoreDataExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKCoreDataExample/._RKCoreDataExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKCoreDataExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/RKKeyValueMappingExample.h//
// RKKeyValueMappingExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKKeyValueMappingExample : UIViewController
UILabel* _infoLabel;
}
@property (nonatomic, retain) IBOutlet UILabel* infoLabel;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/._RKKeyValueMappingExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/RKKeyValueMappingExample.m//
// RKKeyValueMappingExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKKeyValueMappingExample.h"
/**
This code is excerpted from the Advanced Tutorial. See Docs/ for explanation
*/
@interface SimpleAccount : NSObject {
NSNumber* _accountID;
NSString* _name;
NSNumber* _balance;
NSNumber* _transactionsCount;
NSNumber* _averageTransactionAmount;
NSArray* _distinctPayees;
}
@property (nonatomic, retain) NSNumber* accountID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* balance;
@property (nonatomic, retain) NSNumber* transactionsCount;
@property (nonatomic, retain) NSNumber* averageTransactionAmount;
@property (nonatomic, retain) NSArray* distinctPayees;
@end
@implementation SimpleAccount
@synthesize accountID = _accountID;
@synthesize name = _name;
@synthesize balance = _balance;
@synthesize transactionsCount = _transactionsCount;
@synthesize averageTransactionAmount = _averageTransactionAmount;
@synthesize distinctPayees = _distinctPayees;
@end
////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
@implementation RKKeyValueMappingExample
@synthesize infoLabel = _infoLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[RKObjectManager managerWithBaseURL:gRKCatalogBaseURL];
}
return self;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[SimpleAccount class]];
[mapping mapKeyPathsToAttributes:
@"id", @"accountID",
@"name", @"name",
@"balance", @"balance",
@"transactions.@count", @"transactionsCount",
@"", @"averageTransactionAmount",
@"", @"distinctPayees",
nil];
[[RKObjectManager sharedManager].mappingProvider setObjectMapping:mapping forResourcePathPattern:@"/RKKeyValueMappingExample"];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/RKKeyValueMappingExample" delegate:self];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
SimpleAccount* account = [objects objectAtIndex:0];
NSString* info = [NSString stringWithFormat:
@"The count is %@\n"
@"The average transaction amount is %@\n"
@"The distinct list of payees is: %@",
[account transactionsCount],
[account averageTransactionAmount],
[[account distinctPayees] componentsJoinedByString:@", "]];
_infoLabel.text = info;
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
_infoLabel.text = [NSString stringWithFormat:@"Error: %@", [error localizedDescription]];
_infoLabel.textColor = [UIColor redColor];
}
@end
transactions.@avg.amounttransactions.@distinctUnionOfObjects.payee
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/._RKKeyValueMappingExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/RKKeyValueMappingExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBProxyObject
IBUIView
IBUILabel
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
YES
274
{{20, 214}, {280, 207}}
NO
YES
7
NO
IBCocoaTouchFramework
Loading...
Helvetica
17
16
3
MC4zMzMzMzMzMzMzAA
1
10
6
274
{{20, 20}, {280, 139}}
NO
YES
7
NO
IBCocoaTouchFramework
This example has no user interface concerns. The mapping results are displayed below.
1
MCAwIDAAA
1
10
6
0
292
{{89, 185}, {143, 21}}
NO
YES
7
NO
IBCocoaTouchFramework
Mapping Results
Helvetica-Bold
18
16
1
10
{{0, 20}, {320, 460}}
3
MQA
2
IBCocoaTouchFramework
YES
view
3
infoLabel
7
YES
0
1
YES
-1
File's Owner
-2
4
5
6
YES
YES
-1.CustomClassName
-2.CustomClassName
1.IBEditorWindowLastContentRect
1.IBPluginDependency
4.IBPluginDependency
5.IBPluginDependency
6.IBPluginDependency
YES
RKKeyValueMappingExample
UIResponder
{{556, 412}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
7
YES
RKKeyValueMappingExample
UIViewController
infoLabel
UILabel
infoLabel
infoLabel
UILabel
IBProjectSource
./Classes/RKKeyValueMappingExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKKeyValueMappingExample/._RKKeyValueMappingExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKKeyValueMappingExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/RestKit
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/._RestKit
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/RKParamsExample.h//
// RKParamsExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKParamsExample : UIViewController
RKClient* _client;
UIProgressView* _progressView;
UIActivityIndicatorView* _activityIndicatorView;
UIImageView* _imageView;
UIButton* _uploadButton;
UILabel* _statusLabel;
}
@property (nonatomic, retain) IBOutlet UIProgressView* progressView;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* activityIndicatorView;
@property (nonatomic, retain) IBOutlet UIImageView* imageView;
@property (nonatomic, retain) IBOutlet UIButton* uploadButton;
@property (nonatomic, retain) IBOutlet UILabel* statusLabel;
- (IBAction)uploadButtonWasTouched:(id)sender;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/._RKParamsExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/RKParamsExample.m//
// RKParamsExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKParamsExample.h"
@implementation RKParamsExample
@synthesize progressView = _progressView;
@synthesize activityIndicatorView = _activityIndicatorView;
@synthesize imageView = _imageView;
@synthesize uploadButton = _uploadButton;
@synthesize statusLabel = _statusLabel;
- (void)dealloc {
[RKClient setSharedClient:nil];
[_client release];
[super dealloc];
}
- (void)viewDidLoad {
_client = [[RKClient alloc] initWithBaseURL:gRKCatalogBaseURL];
}
- (IBAction)uploadButtonWasTouched:(id)sender {
RKParams* params = [RKParams params];
// Attach the Image from Image View
NSLog(@"Got image: %@", [_imageView image]);
NSData* imageData = UIImagePNGRepresentation([_imageView image]);
[params setData:imageData MIMEType:@"image/png" forParam:@"image1"];
// Attach an Image from the App Bundle
UIImage* image = [UIImage imageNamed:@"RestKit "];
imageData = UIImagePNGRepresentation(image);
[params setData:imageData MIMEType:@"image/png" forParam:@"image2"];
// Log info about the serialization
NSLog(@"RKParams HTTPHeaderValueForContentType = %@", [params HTTPHeaderValueForContentType]);
NSLog(@"RKParams HTTPHeaderValueForContentLength = %d", [params HTTPHeaderValueForContentLength]);
// Send it for processing!
[_client post:@"/RKParamsExample" params:params delegate:self];
}
- (void)requestDidStartLoad:(RKRequest *)request {
_uploadButton.enabled = NO;
[_activityIndicatorView startAnimating];
}
- (void)request:(RKRequest *)request didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
_progressView.progress = (totalBytesWritten / totalBytesExpectedToWrite) * 100.0;
}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response {
_uploadButton.enabled = YES;
[_activityIndicatorView stopAnimating];
if ([response isOK]) {
_statusLabel.text = @"Upload Successful!";
_statusLabel.textColor = [UIColor greenColor];
} else {
_statusLabel.text = [NSString stringWithFormat:@"Upload failed with status code: %d", [response statusCode]];
_statusLabel.textColor = [UIColor redColor];
}
}
- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
_uploadButton.enabled = YES;
[_activityIndicatorView stopAnimating];
_progressView.progress = 0.0;
_statusLabel.text = [NSString stringWithFormat:@"Upload failed with error: %@", [error localizedDescription]];
_statusLabel.textColor = [UIColor redColor];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/._RKParamsExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/RKParamsExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBUIProgressView
IBUIImageView
IBUIView
IBProxyObject
IBUIActivityIndicatorView
IBUILabel
IBUIButton
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
YES
274
{{6, 76}, {306, 71}}
4
NO
IBCocoaTouchFramework
NSImage
RestKit
292
{{112, 211}, {123, 37}}
NO
IBCocoaTouchFramework
0
0
Helvetica-Bold
15
16
1
Upload Image
3
MQA
1
MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
3
MC41AA
292
{{20, 170}, {280, 9}}
NO
IBCocoaTouchFramework
-2147483356
{{84, 220}, {20, 20}}
NO
IBCocoaTouchFramework
2
292
{{42, 271}, {237, 157}}
NO
YES
7
NO
IBCocoaTouchFramework
Helvetica
17
16
1
MCAwIDAAA
1
12
6
1
{{0, 20}, {320, 460}}
3
MQA
2
IBCocoaTouchFramework
YES
view
3
uploadButtonWasTouched:
7
11
imageView
12
progressView
13
uploadButton
14
activityIndicatorView
15
statusLabel
16
YES
0
1
YES
-1
File's Owner
-2
6
7
8
9
10
YES
YES
-1.CustomClassName
-2.CustomClassName
1.IBEditorWindowLastContentRect
1.IBPluginDependency
10.IBPluginDependency
6.IBPluginDependency
7.IBPluginDependency
8.IBPluginDependency
9.IBPluginDependency
YES
RKParamsExample
UIResponder
{{556, 412}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
16
YES
RKParamsExample
UIViewController
uploadButtonWasTouched:
id
uploadButtonWasTouched:
uploadButtonWasTouched:
id
YES
YES
activityIndicatorView
imageView
progressView
statusLabel
uploadButton
YES
UIActivityIndicatorView
UIImageView
UIProgressView
UILabel
UIButton
YES
YES
activityIndicatorView
imageView
progressView
statusLabel
uploadButton
YES
activityIndicatorView
UIActivityIndicatorView
imageView
UIImageView
progressView
UIProgressView
statusLabel
UILabel
uploadButton
UIButton
IBProjectSource
./Classes/RKParamsExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
RestKit
{250, 54}
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKParamsExample/._RKParamsExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKParamsExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/RKReachabilityExample.h//
// RKReachabilityExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKReachabilityExample : UIViewController {
RKReachabilityObserver *_observer;
UILabel *_statusLabel;
UILabel *_flagsLabel;
}
@property (nonatomic, retain) RKReachabilityObserver *observer;
@property (nonatomic, retain) IBOutlet UILabel *statusLabel;
@property (nonatomic, retain) IBOutlet UILabel *flagsLabel;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/._RKReachabilityExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/RKReachabilityExample.m//
// RKReachabilityExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKReachabilityExample.h"
@implementation RKReachabilityExample
@synthesize observer = _observer;
@synthesize statusLabel = _statusLabel;
@synthesize flagsLabel = _flagsLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.observer = [[RKReachabilityObserver alloc] initWithHost:@"restkit.org"];
// self.observer = [RKReachabilityObserver reachabilityObserverForLocalWifi];
// self.observer = [RKReachabilityObserver reachabilityObserverForInternet];
// Register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:RKReachabilityDidChangeNotification
object:_observer];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_observer release];
[super dealloc];
}
- (void)viewDidLoad {
if (! [_observer isReachabilityDetermined]) {
_statusLabel.text = @"Reachability is indeterminate...";
_statusLabel.textColor = [UIColor blueColor];
}
}
- (void)reachabilityChanged:(NSNotification *)notification {
RKReachabilityObserver* observer = (RKReachabilityObserver *) [notification object];
RKLogCritical(@"Received reachability update: %@", observer);
_flagsLabel.text = [NSString stringWithFormat:@"Host: %@ -> %@", observer.host, [observer reachabilityFlagsDescription]];
if ([observer isNetworkReachable]) {
if ([observer isConnectionRequired]) {
_statusLabel.text = @"Connection is available...";
_statusLabel.textColor = [UIColor yellowColor];
return;
}
_statusLabel.textColor = [UIColor greenColor];
if (RKReachabilityReachableViaWiFi == [observer networkStatus]) {
_statusLabel.text = @"Online via WiFi";
} else if (RKReachabilityReachableViaWWAN == [observer networkStatus]) {
_statusLabel.text = @"Online via 3G or Edge";
}
} else {
_statusLabel.text = @"Network unreachable!";
_statusLabel.textColor = [UIColor redColor];
}
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/._RKReachabilityExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/RKReachabilityExample.xib
1280
11C74
1938
1138.23
567.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
933
YES
IBProxyObject
IBUIView
IBUILabel
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
PluginDependencyRecalculationVersion
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
YES
292
{{45, 90}, {230, 21}}
NO
YES
7
NO
IBCocoaTouchFramework
Reachability Status
1
MCAwIDAAA
1
10
1
Helvetica-Bold
Helvetica
2
17
Helvetica-Bold
17
16
292
{{73, 125}, {174, 21}}
NO
YES
7
NO
IBCocoaTouchFramework
1
10
1
1
17
Helvetica
17
16
256
{{20, 199}, {273, 105}}
NO
YES
7
NO
IBCocoaTouchFramework
A reachability observer has been installed. Try disconnecting and reconnecting your Airport to see status change.
1
10
5
292
{{45, 154}, {230, 37}}
_NS:328
NO
YES
7
NO
IBCocoaTouchFramework
3
MC4zMzMzMzMzMzMzAA
1
10
{{0, 20}, {320, 460}}
3
MQA
2
IBCocoaTouchFramework
YES
view
3
statusLabel
8
flagsLabel
10
YES
0
YES
1
YES
-1
File's Owner
-2
4
5
6
9
YES
YES
-1.CustomClassName
-1.IBPluginDependency
-2.CustomClassName
-2.IBPluginDependency
1.IBPluginDependency
4.IBPluginDependency
5.IBPluginDependency
6.IBPluginDependency
9.IBPluginDependency
YES
RKReachabilityExample
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
UIResponder
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
10
YES
RKReachabilityExample
UIViewController
YES
YES
flagsLabel
statusLabel
YES
UILabel
UILabel
YES
YES
flagsLabel
statusLabel
YES
flagsLabel
UILabel
statusLabel
UILabel
IBProjectSource
./Classes/RKReachabilityExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
933
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKReachabilityExample/._RKReachabilityExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKReachabilityExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/Project.h//
// Project.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
#import "User.h"
@interface Project : NSObject {
NSNumber* _projectID;
NSString* _name;
NSString* _description;
User* _user;
NSArray* _tasks;
}
@property (nonatomic, retain) NSNumber* projectID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* description;
@property (nonatomic, retain) User* user;
@property (nonatomic, retain) NSArray* tasks;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._Project.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/Project.m//
// Project.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "Project.h"
@implementation Project
@synthesize projectID = _projectID;
@synthesize name = _name;
@synthesize description = _description;
@synthesize user = _user;
@synthesize tasks = _tasks;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._Project.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.h//
// RKRelationshipMappingExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
#import "Project.h"
@interface RKRelationshipMappingExample : UITableViewController
Project* _selectedProject;
NSArray* _objects;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._RKRelationshipMappingExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.m//
// RKRelationshipMappingExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
#import "RKRelationshipMappingExample.h"
#import "User.h"
#import "Project.h"
#import "Task.h"
@implementation RKRelationshipMappingExample
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:gRKCatalogBaseURL];
RKManagedObjectStore *objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"RKRelationshipMappingExample.sqlite"];
objectManager.objectStore = objectStore;
RKManagedObjectMapping* taskMapping = [RKManagedObjectMapping mappingForClass:[Task class] inManagedObjectStore:objectStore];
taskMapping.primaryKeyAttribute = @"taskID";
[taskMapping mapKeyPath:@"id" toAttribute:@"taskID"];
[taskMapping mapKeyPath:@"name" toAttribute:@"name"];
[taskMapping mapKeyPath:@"assigned_user_id" toAttribute:@"assignedUserID"];
[objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"task"];
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class] inManagedObjectStore:objectStore];
userMapping.primaryKeyAttribute = @"userID";
[userMapping mapAttributes:@"name", @"email", nil];
[userMapping mapKeyPath:@"id" toAttribute:@"userID"];
[userMapping mapRelationship:@"tasks" withMapping:taskMapping];
[objectManager.mappingProvider setMapping:userMapping forKeyPath:@"user"];
// Hydrate the assignedUser association via primary key
[taskMapping hasOne:@"assignedUser" withMapping:userMapping];
[taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];
// NOTE - Project is not backed by Core Data
RKObjectMapping* projectMapping = [RKObjectMapping mappingForClass:[Project class]];
[projectMapping mapKeyPath:@"id" toAttribute:@"projectID"];
[projectMapping mapAttributes:@"name", @"description", nil];
[projectMapping mapRelationship:@"user" withMapping:userMapping];
[projectMapping mapRelationship:@"tasks" withMapping:taskMapping];
[objectManager.mappingProvider setMapping:projectMapping forKeyPath:@"project"];
}
return self;
}
- (void)dealloc {
[_objects release];
[super dealloc];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.title = @"Task List";
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/RKRelationshipMappingExample" delegate:self];
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
_objects = [objects retain];
[self.tableView reloadData];
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Error!" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Rats!" otherButtonTitles:nil];
[alert show];
[alert release];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
// Return number of projects
return [_objects count];
} else {
// Return number of tasks in the selected project...
NSIndexPath* indexPath = [self.tableView indexPathForSelectedRow];
if (indexPath) {
return [[[_objects objectAtIndex:indexPath.row] tasks] count];
}
}
return 0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 150, 100)];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:18];
if (section == 0) {
label.text = @"Projects";
} else if (section == 1) {
label.text = @"Tasks";
}
return [label autorelease];
}
#pragma mark - Table View Selection
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Don't allow selections in the bottom section
if (indexPath.section == 1) {
return nil;
}
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_selectedProject release];
_selectedProject = [[_objects objectAtIndex:indexPath.row] retain];
[self.tableView reloadData];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if (indexPath.section == 0) {
Project* project = (Project*) [_objects objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = project.name;
} else if (indexPath.section == 1) {
// NOTE: We refetch the object here because Project is not Core Data backed
NSManagedObject* objectReference = [_selectedProject.tasks objectAtIndex:indexPath.row];
Task* task = (Task*) [[RKObjectManager sharedManager].objectStore objectWithID:[objectReference objectID]];
cell.textLabel.text = [NSString stringWithFormat:@"%@", task.name];
cell.detailTextLabel.text = [NSString stringWithFormat:@"Assigned to: %@", task.assignedUser.name];
}
return cell;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._RKRelationshipMappingExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/.xccurrentversion
_XCCurrentVersionName
RKRelationshipMappingExample.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/._.xccurrentversion
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/RKRelationshipMappingExample.xcdatamodel/elements
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/RKRelationshipMappingExample.xcdatamodel/._elements
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/RKRelationshipMappingExample.xcdatamodel/layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/RKRelationshipMappingExample.xcdatamodel/._layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xcdatamodeld/._RKRelationshipMappingExample.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._RKRelationshipMappingExample.xcdatamodeld
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/RKRelationshipMappingExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBProxyObject
IBUITableView
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
{{0, 20}, {320, 460}}
10
549453824
{84, 1}
YES
YES
TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB
AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES
AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS
AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA
3
MCAwAA
groupTableViewBackgroundColor
NO
YES
NO
IBCocoaTouchFramework
NO
1
2
0
YES
44
25
10
YES
view
5
dataSource
6
delegate
7
YES
0
-1
File's Owner
-2
4
YES
YES
-1.CustomClassName
-2.CustomClassName
4.IBEditorWindowLastContentRect
4.IBPluginDependency
YES
RKRelationshipMappingExample
UIResponder
{{329, 504}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
7
YES
RKRelationshipMappingExample
UITableViewController
IBProjectSource
./Classes/RKRelationshipMappingExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._RKRelationshipMappingExample.xib
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/Task.h//
// Task.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
#import "User.h"
@interface Task : NSManagedObject {
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* taskID;
@property (nonatomic, retain) NSNumber* assignedUserID;
@property (nonatomic, retain) User* assignedUser;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._Task.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/Task.m//
// Task.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "Task.h"
@implementation Task
@dynamic name;
@dynamic taskID;
@dynamic assignedUserID;
@dynamic assignedUser;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._Task.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/User.h//
// User.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface User : NSManagedObject {
}
@property (nonatomic, retain) NSNumber* userID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* email;
@property (nonatomic, retain) NSSet* tasks;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._User.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/User.m//
// User.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "User.h"
@implementation User
@dynamic userID;
@dynamic name;
@dynamic email;
@dynamic tasks;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRelationshipMappingExample/._User.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKRelationshipMappingExample
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/RKRequestQueueExample.h//
// RKRequestQueueExample.h
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKCatalog.h"
@interface RKRequestQueueExample : UIViewController
@property (nonatomic, retain) RKRequestQueue *requestQueue;
@property (nonatomic, retain) IBOutlet UILabel *statusLabel;
- (IBAction)sendRequest;
- (IBAction)queueRequests;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/._RKRequestQueueExample.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/RKRequestQueueExample.m//
// RKRequestQueueExample.m
// RKCatalog
//
// Created by Blake Watters on 4/21/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKRequestQueueExample.h"
@implementation RKRequestQueueExample
@synthesize requestQueue;
@synthesize statusLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
RKClient* client = [RKClient clientWithBaseURL:gRKCatalogBaseURL];
[RKClient setSharedClient:client];
// Ask RestKit to spin the network activity indicator for us
client.requestQueue.delegate = self;
client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
}
return self;
}
// We have been dismissed -- clean up any open requests
- (void)dealloc {
[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:self];
[requestQueue cancelAllRequests];
[requestQueue release];
requestQueue = nil;
[super dealloc];
}
// We have been obscured -- cancel any pending requests
- (void)viewWillDisappear:(BOOL)animated {
[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:self];
}
- (IBAction)sendRequest {
/**
* Ask RKClient to load us some data. This causes an RKRequest object to be created
* transparently pushed onto the RKClient's RKRequestQueue instance
*/
[[RKClient sharedClient] get:@"/RKRequestQueueExample" delegate:self];
}
- (IBAction)queueRequests {
RKRequestQueue *queue = [RKRequestQueue requestQueue];
queue.delegate = self;
queue.concurrentRequestsLimit = 1;
queue.showsNetworkActivityIndicatorWhenBusy = YES;
// Queue up 4 requests
RKRequest *request = [[RKClient sharedClient] requestWithResourcePath:@"/RKRequestQueueExample"];
request.delegate = self;
[queue addRequest:request];
request = [[RKClient sharedClient] requestWithResourcePath:@"/RKRequestQueueExample"];
request.delegate = self;
[queue addRequest:request];
request = [[RKClient sharedClient] requestWithResourcePath:@"/RKRequestQueueExample"];
request.delegate = self;
[queue addRequest:request];
request = [[RKClient sharedClient] requestWithResourcePath:@"/RKRequestQueueExample"];
request.delegate = self;
[queue addRequest:request];
// Start processing!
[queue start];
self.requestQueue = queue;
}
- (void)requestQueue:(RKRequestQueue *)queue didSendRequest:(RKRequest *)request {
statusLabel.text = [NSString stringWithFormat:@"RKRequestQueue %@ is current loading %d of %d requests",
queue, [queue loadingCount], [queue count]];
}
- (void)requestQueueDidBeginLoading:(RKRequestQueue *)queue {
statusLabel.text = [NSString stringWithFormat:@"Queue %@ Began Loading...", queue];
}
- (void)requestQueueDidFinishLoading:(RKRequestQueue *)queue {
statusLabel.text = [NSString stringWithFormat:@"Queue %@ Finished Loading...", queue];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/._RKRequestQueueExample.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/RKRequestQueueExample.xib
1056
10J869
1306
1038.35
461.00
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
301
YES
IBUIButton
IBUIView
IBUILabel
IBProxyObject
YES
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
YES
IBFilesOwner
IBCocoaTouchFramework
IBFirstResponder
IBCocoaTouchFramework
274
YES
292
{{20, 165}, {273, 60}}
NO
YES
7
NO
IBCocoaTouchFramework
Helvetica-Bold
12
16
1
MCAwIDAAA
1
10
3
292
{{33, 246}, {125, 37}}
NO
IBCocoaTouchFramework
0
0
Helvetica-Bold
15
16
1
Send Request
3
MQA
1
MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
3
MC41AA
292
{{171, 246}, {122, 37}}
NO
IBCocoaTouchFramework
0
0
1
Create Queue
1
MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
304
{{20, 57}, {280, 100}}
NO
YES
7
NO
IBCocoaTouchFramework
This example highlights RestKit queue handling. Use the buttons to cause queues to be manipulated.
Helvetica
17
16
1
10
3
{{0, 20}, {320, 460}}
3
MQA
2
IBCocoaTouchFramework
YES
view
3
statusLabel
11
sendRequest
7
12
queueRequests
7
13
YES
0
1
YES
-1
File's Owner
-2
4
5
6
7
YES
YES
-1.CustomClassName
-2.CustomClassName
1.IBEditorWindowLastContentRect
1.IBPluginDependency
4.IBPluginDependency
5.IBPluginDependency
6.IBPluginDependency
7.IBPluginDependency
YES
RKRequestQueueExample
UIResponder
{{556, 412}, {320, 480}}
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
com.apple.InterfaceBuilder.IBCocoaTouchPlugin
YES
YES
13
YES
RKRequestQueueExample
UIViewController
YES
YES
queueRequests
sendRequest
YES
id
id
YES
YES
queueRequests
sendRequest
YES
queueRequests
id
sendRequest
id
statusLabel
UILabel
statusLabel
statusLabel
UILabel
IBProjectSource
./Classes/RKRequestQueueExample.h
0
IBCocoaTouchFramework
com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
YES
3
301
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/RKRequestQueueExample/._RKRequestQueueExample.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/Examples/._RKRequestQueueExample
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/._Examples
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/RKCatalog.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
2501DE5D13607B67003DE9E4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2501DE5C13607B67003DE9E4 /* UIKit.framework */; };
2501DE5F13607B67003DE9E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2501DE5E13607B67003DE9E4 /* Foundation.framework */; };
2501DE6113607B67003DE9E4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2501DE6013607B67003DE9E4 /* CoreGraphics.framework */; };
2501DE6313607B67003DE9E4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2501DE6213607B67003DE9E4 /* CoreData.framework */; };
256F388C1361053900CE0C58 /* RKKeyValueMappingExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F388A1361053900CE0C58 /* RKKeyValueMappingExample.m */; };
256F388D1361053900CE0C58 /* RKKeyValueMappingExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 256F388B1361053900CE0C58 /* RKKeyValueMappingExample.xib */; };
256F38971361188700CE0C58 /* RKRelationshipMappingExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F38951361188700CE0C58 /* RKRelationshipMappingExample.m */; };
256F38981361188700CE0C58 /* RKRelationshipMappingExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 256F38961361188700CE0C58 /* RKRelationshipMappingExample.xib */; };
256F389B13611B5E00CE0C58 /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F389A13611B5E00CE0C58 /* User.m */; };
256F389E13611B6700CE0C58 /* Task.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F389D13611B6700CE0C58 /* Task.m */; };
256F38A113611B7200CE0C58 /* Project.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F38A013611B7200CE0C58 /* Project.m */; };
256F38AE13612E9400CE0C58 /* RKCoreDataExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 256F38AC13612E9400CE0C58 /* RKCoreDataExample.m */; };
256F38AF13612E9400CE0C58 /* RKCoreDataExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 256F38AD13612E9400CE0C58 /* RKCoreDataExample.xib */; };
25825DF31361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 25825DF11361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodeld */; };
258BAA4813608BDB00ED0614 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA3513608BDB00ED0614 /* InfoPlist.strings */; };
258BAA4913608BDB00ED0614 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA3713608BDB00ED0614 /* MainWindow.xib */; };
258BAA4A13608BDB00ED0614 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA3913608BDB00ED0614 /* RootViewController.xib */; };
258BAA4B13608BDB00ED0614 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAA3B13608BDB00ED0614 /* main.m */; };
258BAA4D13608BDB00ED0614 /* RKCatalogAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAA3F13608BDB00ED0614 /* RKCatalogAppDelegate.m */; };
258BAA4E13608BDB00ED0614 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAA4113608BDB00ED0614 /* RootViewController.m */; };
258BAA4F13608BDB00ED0614 /* RestKit in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA4413608BDB00ED0614 /* RestKit */; };
258BAA5013608BDB00ED0614 /* RKParamsExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAA4613608BDB00ED0614 /* RKParamsExample.m */; };
258BAA5113608BDB00ED0614 /* RKParamsExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA4713608BDB00ED0614 /* RKParamsExample.xib */; };
258BAA5F13609F5200ED0614 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 258BAA5E13609F5200ED0614 /* libxml2.dylib */; };
258BAA6113609F5D00ED0614 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 258BAA6013609F5D00ED0614 /* SystemConfiguration.framework */; };
258BAA6313609F6400ED0614 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 258BAA6213609F6400ED0614 /* CFNetwork.framework */; };
258BAA6513609F6D00ED0614 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 258BAA6413609F6D00ED0614 /* MobileCoreServices.framework */; };
258BAA6A1360AF8200ED0614 /* RKRequestQueueExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAA681360AF8200ED0614 /* RKRequestQueueExample.m */; };
258BAA6B1360AF8200ED0614 /* RKRequestQueueExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAA691360AF8200ED0614 /* RKRequestQueueExample.xib */; };
258BAAEF1360BB3800ED0614 /* RKReachabilityExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAAED1360BB3800ED0614 /* RKReachabilityExample.m */; };
258BAAF01360BB3800ED0614 /* RKReachabilityExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAAEE1360BB3800ED0614 /* RKReachabilityExample.xib */; };
258BAAF51360C15900ED0614 /* RKBackgroundRequestExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 258BAAF31360C15900ED0614 /* RKBackgroundRequestExample.m */; };
258BAAF61360C15900ED0614 /* RKBackgroundRequestExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258BAAF41360C15900ED0614 /* RKBackgroundRequestExample.xib */; };
258E219C1361BC42000D4DCF /* RKCoreDataExample.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 258E219A1361BC42000D4DCF /* RKCoreDataExample.xcdatamodeld */; };
258F33F41432CB11001EEEFC /* RKAuthenticationExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 258F33F21432CB11001EEEFC /* RKAuthenticationExample.m */; };
258F33F51432CB11001EEEFC /* RKAuthenticationExample.xib in Resources */ = {isa = PBXBuildFile; fileRef = 258F33F31432CB11001EEEFC /* RKAuthenticationExample.xib */; };
25A34207147C4C540009758D /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A341FF147C4C300009758D /* libRestKit.a */; };
25A3421D147D87800009758D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A3421C147D87800009758D /* Security.framework */; };
25BE938114F96CAD008BC1C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25BE938014F96CAD008BC1C0 /* QuartzCore.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2501DEB913607BD5003DE9E4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160D1514564E810060A5C5;
remoteInfo = RestKit;
};
257AB9DD150EB52000CCAA76 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25EC1AFF14F8078100C3CF3F;
remoteInfo = RestKitResources;
};
25A341FE147C4C300009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D1614564E810060A5C5;
remoteInfo = RestKit;
};
25A34200147C4C300009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D2614564E820060A5C5;
remoteInfo = RestKitTests;
};
25A34202147C4C300009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E62145651060060A5C5;
remoteInfo = RestKitFramework;
};
25A34204147C4C300009758D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E78145651060060A5C5;
remoteInfo = RestKitFrameworkTests;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2501DE5813607B67003DE9E4 /* RKCatalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKCatalog.app; sourceTree = BUILT_PRODUCTS_DIR; };
2501DE5C13607B67003DE9E4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
2501DE5E13607B67003DE9E4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
2501DE6013607B67003DE9E4 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
2501DE6213607B67003DE9E4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../../RestKit.xcodeproj; sourceTree = "
256F38891361053900CE0C58 /* RKKeyValueMappingExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKKeyValueMappingExample.h; sourceTree = "
256F388A1361053900CE0C58 /* RKKeyValueMappingExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKKeyValueMappingExample.m; sourceTree = "
256F388B1361053900CE0C58 /* RKKeyValueMappingExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKKeyValueMappingExample.xib; sourceTree = "
256F38941361188700CE0C58 /* RKRelationshipMappingExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRelationshipMappingExample.h; sourceTree = "
256F38951361188700CE0C58 /* RKRelationshipMappingExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRelationshipMappingExample.m; sourceTree = "
256F38961361188700CE0C58 /* RKRelationshipMappingExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKRelationshipMappingExample.xib; sourceTree = "
256F389913611B5E00CE0C58 /* User.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = "
256F389A13611B5E00CE0C58 /* User.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = User.m; sourceTree = "
256F389C13611B6700CE0C58 /* Task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Task.h; sourceTree = "
256F389D13611B6700CE0C58 /* Task.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Task.m; sourceTree = "
256F389F13611B7200CE0C58 /* Project.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Project.h; sourceTree = "
256F38A013611B7200CE0C58 /* Project.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Project.m; sourceTree = "
256F38AB13612E9400CE0C58 /* RKCoreDataExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKCoreDataExample.h; sourceTree = "
256F38AC13612E9400CE0C58 /* RKCoreDataExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKCoreDataExample.m; sourceTree = "
256F38AD13612E9400CE0C58 /* RKCoreDataExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKCoreDataExample.xib; sourceTree = "
25825DF21361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = RKRelationshipMappingExample.xcdatamodel; sourceTree = "
258BAA3613608BDB00ED0614 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "
258BAA3813608BDB00ED0614 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = "
258BAA3A13608BDB00ED0614 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = "
258BAA3B13608BDB00ED0614 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "
258BAA3C13608BDB00ED0614 /* RKCatalog-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RKCatalog-Info.plist"; sourceTree = "
258BAA3D13608BDB00ED0614 /* RKCatalog-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RKCatalog-Prefix.pch"; sourceTree = "
258BAA3E13608BDB00ED0614 /* RKCatalogAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKCatalogAppDelegate.h; sourceTree = "
258BAA3F13608BDB00ED0614 /* RKCatalogAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKCatalogAppDelegate.m; sourceTree = "
258BAA4013608BDB00ED0614 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = "
258BAA4113608BDB00ED0614 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = "
258BAA4413608BDB00ED0614 /* RestKit */ = {isa = PBXFileReference; lastKnownFileType = image ; path = RestKit ; sourceTree = "
258BAA4513608BDB00ED0614 /* RKParamsExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParamsExample.h; sourceTree = "
258BAA4613608BDB00ED0614 /* RKParamsExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsExample.m; sourceTree = "
258BAA4713608BDB00ED0614 /* RKParamsExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKParamsExample.xib; sourceTree = "
258BAA5E13609F5200ED0614 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
258BAA6013609F5D00ED0614 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
258BAA6213609F6400ED0614 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
258BAA6413609F6D00ED0614 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
258BAA671360AF8200ED0614 /* RKRequestQueueExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestQueueExample.h; sourceTree = "
258BAA681360AF8200ED0614 /* RKRequestQueueExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestQueueExample.m; sourceTree = "
258BAA691360AF8200ED0614 /* RKRequestQueueExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKRequestQueueExample.xib; sourceTree = "
258BAA6C1360AFC800ED0614 /* RKCatalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKCatalog.h; sourceTree = "
258BAAEC1360BB3800ED0614 /* RKReachabilityExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKReachabilityExample.h; sourceTree = "
258BAAED1360BB3800ED0614 /* RKReachabilityExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKReachabilityExample.m; sourceTree = "
258BAAEE1360BB3800ED0614 /* RKReachabilityExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKReachabilityExample.xib; sourceTree = "
258BAAF21360C15900ED0614 /* RKBackgroundRequestExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKBackgroundRequestExample.h; sourceTree = "
258BAAF31360C15900ED0614 /* RKBackgroundRequestExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKBackgroundRequestExample.m; sourceTree = "
258BAAF41360C15900ED0614 /* RKBackgroundRequestExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKBackgroundRequestExample.xib; sourceTree = "
258E219B1361BC42000D4DCF /* RKCoreDataExample.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = RKCoreDataExample.xcdatamodel; sourceTree = "
258F33F11432CB11001EEEFC /* RKAuthenticationExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKAuthenticationExample.h; path = RKAuthenticationExample/RKAuthenticationExample.h; sourceTree = "
258F33F21432CB11001EEEFC /* RKAuthenticationExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKAuthenticationExample.m; path = RKAuthenticationExample/RKAuthenticationExample.m; sourceTree = "
258F33F31432CB11001EEEFC /* RKAuthenticationExample.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RKAuthenticationExample.xib; path = RKAuthenticationExample/RKAuthenticationExample.xib; sourceTree = "
25A3421C147D87800009758D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
25BE938014F96CAD008BC1C0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2501DE5513607B67003DE9E4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
25BE938114F96CAD008BC1C0 /* QuartzCore.framework in Frameworks */,
25A3421D147D87800009758D /* Security.framework in Frameworks */,
25A34207147C4C540009758D /* libRestKit.a in Frameworks */,
258BAA6513609F6D00ED0614 /* MobileCoreServices.framework in Frameworks */,
258BAA6313609F6400ED0614 /* CFNetwork.framework in Frameworks */,
258BAA6113609F5D00ED0614 /* SystemConfiguration.framework in Frameworks */,
258BAA5F13609F5200ED0614 /* libxml2.dylib in Frameworks */,
2501DE5D13607B67003DE9E4 /* UIKit.framework in Frameworks */,
2501DE5F13607B67003DE9E4 /* Foundation.framework in Frameworks */,
2501DE6113607B67003DE9E4 /* CoreGraphics.framework in Frameworks */,
2501DE6313607B67003DE9E4 /* CoreData.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2501DE4D13607B67003DE9E4 = {
isa = PBXGroup;
children = (
258BAA3413608BDB00ED0614 /* App */,
258BAA4213608BDB00ED0614 /* Examples */,
2501DE5B13607B67003DE9E4 /* Frameworks */,
2501DE5913607B67003DE9E4 /* Products */,
);
sourceTree = "
};
2501DE5913607B67003DE9E4 /* Products */ = {
isa = PBXGroup;
children = (
2501DE5813607B67003DE9E4 /* RKCatalog.app */,
);
name = Products;
sourceTree = "
};
2501DE5B13607B67003DE9E4 /* Frameworks */ = {
isa = PBXGroup;
children = (
25BE938014F96CAD008BC1C0 /* QuartzCore.framework */,
2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */,
25A3421C147D87800009758D /* Security.framework */,
258BAA6413609F6D00ED0614 /* MobileCoreServices.framework */,
258BAA6213609F6400ED0614 /* CFNetwork.framework */,
258BAA6013609F5D00ED0614 /* SystemConfiguration.framework */,
258BAA5E13609F5200ED0614 /* libxml2.dylib */,
2501DE5C13607B67003DE9E4 /* UIKit.framework */,
2501DE5E13607B67003DE9E4 /* Foundation.framework */,
2501DE6013607B67003DE9E4 /* CoreGraphics.framework */,
2501DE6213607B67003DE9E4 /* CoreData.framework */,
);
name = Frameworks;
sourceTree = "
};
2501DE8213607B74003DE9E4 /* Products */ = {
isa = PBXGroup;
children = (
25A341FF147C4C300009758D /* libRestKit.a */,
25A34201147C4C300009758D /* RestKitTests.octest */,
25A34203147C4C300009758D /* RestKit.framework */,
25A34205147C4C300009758D /* RestKitFrameworkTests.octest */,
257AB9DE150EB52000CCAA76 /* RestKitResources.bundle */,
);
name = Products;
sourceTree = "
};
256F38881361052C00CE0C58 /* RKKeyValueMappingExample */ = {
isa = PBXGroup;
children = (
256F38891361053900CE0C58 /* RKKeyValueMappingExample.h */,
256F388A1361053900CE0C58 /* RKKeyValueMappingExample.m */,
256F388B1361053900CE0C58 /* RKKeyValueMappingExample.xib */,
);
path = RKKeyValueMappingExample;
sourceTree = "
};
256F388E136116C200CE0C58 /* RKRelationshipMappingExample */ = {
isa = PBXGroup;
children = (
256F38941361188700CE0C58 /* RKRelationshipMappingExample.h */,
256F38951361188700CE0C58 /* RKRelationshipMappingExample.m */,
256F38961361188700CE0C58 /* RKRelationshipMappingExample.xib */,
256F389913611B5E00CE0C58 /* User.h */,
256F389A13611B5E00CE0C58 /* User.m */,
256F389C13611B6700CE0C58 /* Task.h */,
256F389D13611B6700CE0C58 /* Task.m */,
256F389F13611B7200CE0C58 /* Project.h */,
256F38A013611B7200CE0C58 /* Project.m */,
25825DF11361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodeld */,
);
path = RKRelationshipMappingExample;
sourceTree = "
};
256F38A21361286400CE0C58 /* RKCoreDataExample */ = {
isa = PBXGroup;
children = (
258E219A1361BC42000D4DCF /* RKCoreDataExample.xcdatamodeld */,
256F38AB13612E9400CE0C58 /* RKCoreDataExample.h */,
256F38AC13612E9400CE0C58 /* RKCoreDataExample.m */,
256F38AD13612E9400CE0C58 /* RKCoreDataExample.xib */,
);
path = RKCoreDataExample;
sourceTree = "
};
258BAA3413608BDB00ED0614 /* App */ = {
isa = PBXGroup;
children = (
258BAA3513608BDB00ED0614 /* InfoPlist.strings */,
258BAA3713608BDB00ED0614 /* MainWindow.xib */,
258BAA3913608BDB00ED0614 /* RootViewController.xib */,
258BAA3B13608BDB00ED0614 /* main.m */,
258BAA3C13608BDB00ED0614 /* RKCatalog-Info.plist */,
258BAA3D13608BDB00ED0614 /* RKCatalog-Prefix.pch */,
258BAA3E13608BDB00ED0614 /* RKCatalogAppDelegate.h */,
258BAA3F13608BDB00ED0614 /* RKCatalogAppDelegate.m */,
258BAA4013608BDB00ED0614 /* RootViewController.h */,
258BAA4113608BDB00ED0614 /* RootViewController.m */,
258BAA6C1360AFC800ED0614 /* RKCatalog.h */,
);
path = App;
sourceTree = "
};
258BAA4213608BDB00ED0614 /* Examples */ = {
isa = PBXGroup;
children = (
258BAA4313608BDB00ED0614 /* RKParamsExample */,
258F33F01432CAC8001EEEFC /* RKAuthenticationExample */,
258BAA661360AF7000ED0614 /* RKRequestQueueExample */,
258BAAEB1360BB0300ED0614 /* RKReachabilityExample */,
258BAAF11360C0FE00ED0614 /* RKBackgroundRequestExample */,
256F38881361052C00CE0C58 /* RKKeyValueMappingExample */,
256F388E136116C200CE0C58 /* RKRelationshipMappingExample */,
256F38A21361286400CE0C58 /* RKCoreDataExample */,
);
path = Examples;
sourceTree = "
};
258BAA4313608BDB00ED0614 /* RKParamsExample */ = {
isa = PBXGroup;
children = (
258BAA4413608BDB00ED0614 /* RestKit */,
258BAA4513608BDB00ED0614 /* RKParamsExample.h */,
258BAA4613608BDB00ED0614 /* RKParamsExample.m */,
258BAA4713608BDB00ED0614 /* RKParamsExample.xib */,
);
path = RKParamsExample;
sourceTree = "
};
258BAA661360AF7000ED0614 /* RKRequestQueueExample */ = {
isa = PBXGroup;
children = (
258BAA671360AF8200ED0614 /* RKRequestQueueExample.h */,
258BAA681360AF8200ED0614 /* RKRequestQueueExample.m */,
258BAA691360AF8200ED0614 /* RKRequestQueueExample.xib */,
);
path = RKRequestQueueExample;
sourceTree = "
};
258BAAEB1360BB0300ED0614 /* RKReachabilityExample */ = {
isa = PBXGroup;
children = (
258BAAEC1360BB3800ED0614 /* RKReachabilityExample.h */,
258BAAED1360BB3800ED0614 /* RKReachabilityExample.m */,
258BAAEE1360BB3800ED0614 /* RKReachabilityExample.xib */,
);
path = RKReachabilityExample;
sourceTree = "
};
258BAAF11360C0FE00ED0614 /* RKBackgroundRequestExample */ = {
isa = PBXGroup;
children = (
258BAAF21360C15900ED0614 /* RKBackgroundRequestExample.h */,
258BAAF31360C15900ED0614 /* RKBackgroundRequestExample.m */,
258BAAF41360C15900ED0614 /* RKBackgroundRequestExample.xib */,
);
path = RKBackgroundRequestExample;
sourceTree = "
};
258F33F01432CAC8001EEEFC /* RKAuthenticationExample */ = {
isa = PBXGroup;
children = (
258F33F11432CB11001EEEFC /* RKAuthenticationExample.h */,
258F33F21432CB11001EEEFC /* RKAuthenticationExample.m */,
258F33F31432CB11001EEEFC /* RKAuthenticationExample.xib */,
);
name = RKAuthenticationExample;
sourceTree = "
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
2501DE5713607B67003DE9E4 /* RKCatalog */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2501DE7E13607B67003DE9E4 /* Build configuration list for PBXNativeTarget "RKCatalog" */;
buildPhases = (
2501DE5413607B67003DE9E4 /* Sources */,
2501DE5513607B67003DE9E4 /* Frameworks */,
2501DE5613607B67003DE9E4 /* Resources */,
);
buildRules = (
);
dependencies = (
2501DEBA13607BD5003DE9E4 /* PBXTargetDependency */,
);
name = RKCatalog;
productName = RKCatalog;
productReference = 2501DE5813607B67003DE9E4 /* RKCatalog.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2501DE4F13607B67003DE9E4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
ORGANIZATIONNAME = "Two Toasters";
};
buildConfigurationList = 2501DE5213607B67003DE9E4 /* Build configuration list for PBXProject "RKCatalog" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 2501DE4D13607B67003DE9E4;
productRefGroup = 2501DE5913607B67003DE9E4 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 2501DE8213607B74003DE9E4 /* Products */;
ProjectRef = 2501DE8113607B74003DE9E4 /* RestKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
2501DE5713607B67003DE9E4 /* RKCatalog */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
257AB9DE150EB52000CCAA76 /* RestKitResources.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitResources.bundle;
remoteRef = 257AB9DD150EB52000CCAA76 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A341FF147C4C300009758D /* libRestKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRestKit.a;
remoteRef = 25A341FE147C4C300009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A34201147C4C300009758D /* RestKitTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitTests.octest;
remoteRef = 25A34200147C4C300009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A34203147C4C300009758D /* RestKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = RestKit.framework;
remoteRef = 25A34202147C4C300009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25A34205147C4C300009758D /* RestKitFrameworkTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitFrameworkTests.octest;
remoteRef = 25A34204147C4C300009758D /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
2501DE5613607B67003DE9E4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
258BAA4813608BDB00ED0614 /* InfoPlist.strings in Resources */,
258BAA4913608BDB00ED0614 /* MainWindow.xib in Resources */,
258BAA4A13608BDB00ED0614 /* RootViewController.xib in Resources */,
258BAA4F13608BDB00ED0614 /* RestKit in Resources */,
258BAA5113608BDB00ED0614 /* RKParamsExample.xib in Resources */,
258BAA6B1360AF8200ED0614 /* RKRequestQueueExample.xib in Resources */,
258BAAF01360BB3800ED0614 /* RKReachabilityExample.xib in Resources */,
258BAAF61360C15900ED0614 /* RKBackgroundRequestExample.xib in Resources */,
256F388D1361053900CE0C58 /* RKKeyValueMappingExample.xib in Resources */,
256F38981361188700CE0C58 /* RKRelationshipMappingExample.xib in Resources */,
256F38AF13612E9400CE0C58 /* RKCoreDataExample.xib in Resources */,
258F33F51432CB11001EEEFC /* RKAuthenticationExample.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2501DE5413607B67003DE9E4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
258BAA4B13608BDB00ED0614 /* main.m in Sources */,
258BAA4D13608BDB00ED0614 /* RKCatalogAppDelegate.m in Sources */,
258BAA4E13608BDB00ED0614 /* RootViewController.m in Sources */,
258BAA5013608BDB00ED0614 /* RKParamsExample.m in Sources */,
258BAA6A1360AF8200ED0614 /* RKRequestQueueExample.m in Sources */,
258BAAEF1360BB3800ED0614 /* RKReachabilityExample.m in Sources */,
258BAAF51360C15900ED0614 /* RKBackgroundRequestExample.m in Sources */,
256F388C1361053900CE0C58 /* RKKeyValueMappingExample.m in Sources */,
256F38971361188700CE0C58 /* RKRelationshipMappingExample.m in Sources */,
256F389B13611B5E00CE0C58 /* User.m in Sources */,
256F389E13611B6700CE0C58 /* Task.m in Sources */,
256F38A113611B7200CE0C58 /* Project.m in Sources */,
256F38AE13612E9400CE0C58 /* RKCoreDataExample.m in Sources */,
258E219C1361BC42000D4DCF /* RKCoreDataExample.xcdatamodeld in Sources */,
25825DF31361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodeld in Sources */,
258F33F41432CB11001EEEFC /* RKAuthenticationExample.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
2501DEBA13607BD5003DE9E4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKit;
targetProxy = 2501DEB913607BD5003DE9E4 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
258BAA3513608BDB00ED0614 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
258BAA3613608BDB00ED0614 /* en */,
);
name = InfoPlist.strings;
sourceTree = "
};
258BAA3713608BDB00ED0614 /* MainWindow.xib */ = {
isa = PBXVariantGroup;
children = (
258BAA3813608BDB00ED0614 /* en */,
);
name = MainWindow.xib;
sourceTree = "
};
258BAA3913608BDB00ED0614 /* RootViewController.xib */ = {
isa = PBXVariantGroup;
children = (
258BAA3A13608BDB00ED0614 /* en */,
);
name = RootViewController.xib;
sourceTree = "
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
2501DE7C13607B67003DE9E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
OTHER_LDFLAGS = (
"-ObjC",
"-all_load",
);
SDKROOT = iphoneos;
};
name = Debug;
};
2501DE7D13607B67003DE9E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
OTHER_LDFLAGS = (
"-ObjC",
"-all_load",
);
SDKROOT = iphoneos;
};
name = Release;
};
2501DE7F13607B67003DE9E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "App/RKCatalog-Prefix.pch";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "App/RKCatalog-Info.plist";
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
2501DE8013607B67003DE9E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "App/RKCatalog-Prefix.pch";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "App/RKCatalog-Info.plist";
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)\"";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2501DE5213607B67003DE9E4 /* Build configuration list for PBXProject "RKCatalog" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2501DE7C13607B67003DE9E4 /* Debug */,
2501DE7D13607B67003DE9E4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2501DE7E13607B67003DE9E4 /* Build configuration list for PBXNativeTarget "RKCatalog" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2501DE7F13607B67003DE9E4 /* Debug */,
2501DE8013607B67003DE9E4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
25825DF11361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
25825DF21361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodel */,
);
currentVersion = 25825DF21361BCA6001A2902 /* RKRelationshipMappingExample.xcdatamodel */;
path = RKRelationshipMappingExample.xcdatamodeld;
sourceTree = "
versionGroupType = wrapper.xcdatamodel;
};
258E219A1361BC42000D4DCF /* RKCoreDataExample.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
258E219B1361BC42000D4DCF /* RKCoreDataExample.xcdatamodel */,
);
currentVersion = 258E219B1361BC42000D4DCF /* RKCoreDataExample.xcdatamodel */;
path = RKCoreDataExample.xcdatamodeld;
sourceTree = "
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 2501DE4F13607B67003DE9E4 /* Project object */;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/RKCatalog.xcodeproj/._project.pbxproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/RKCatalog.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/RKCatalog.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/RKCatalog.xcodeproj/._project.xcworkspace
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/._RKCatalog.xcodeproj
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKCatalog/._Server
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/._RKCatalog
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/Credits.rtf
Some people
Some other people
Hopefully not nobody
Whoever
Mom
Engineering:Human Interface Design:Testing:Documentation:With special thanks to:
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/._Credits.rtf
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/InfoPlist.strings/* Localized versions of Info.plist keys */
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/._InfoPlist.strings
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/MainMenu.xib
1060
10A324
719
1015
418.00
com.apple.InterfaceBuilder.CocoaPlugin
719
YES
YES
com.apple.InterfaceBuilder.CocoaPlugin
YES
YES
YES
YES
NSApplication
FirstResponder
NSApplication
AMainMenu
YES
RKMacOSX
1048576
2147483647
NSImage
NSMenuCheckmark
NSImage
NSMenuMixedState
submenuAction:
RKMacOSX
YES
About RKMacOSX
2147483647
YES
YES
1048576
2147483647
Preferences…
,
1048576
2147483647
YES
YES
1048576
2147483647
Services
1048576
2147483647
submenuAction:
Services
YES
_NSServicesMenu
YES
YES
1048576
2147483647
Hide RKMacOSX
h
1048576
2147483647
Hide Others
h
1572864
2147483647
Show All
1048576
2147483647
YES
YES
1048576
2147483647
Quit RKMacOSX
q
1048576
2147483647
_NSAppleMenu
File
1048576
2147483647
submenuAction:
File
YES
New
n
1048576
2147483647
Open…
o
1048576
2147483647
Open Recent
1048576
2147483647
submenuAction:
Open Recent
YES
Clear Menu
1048576
2147483647
_NSRecentDocumentsMenu
YES
YES
1048576
2147483647
Close
w
1048576
2147483647
Save
s
1048576
2147483647
Save As…
S
1179648
2147483647
Revert to Saved
2147483647
YES
YES
1048576
2147483647
Page Setup...
P
1179648
2147483647
Print…
p
1048576
2147483647
Edit
1048576
2147483647
submenuAction:
Edit
YES
Undo
z
1048576
2147483647
Redo
Z
1179648
2147483647
YES
YES
1048576
2147483647
Cut
x
1048576
2147483647
Copy
c
1048576
2147483647
Paste
v
1048576
2147483647
Paste and Match Style
V
1572864
2147483647
Delete
1048576
2147483647
Select All
a
1048576
2147483647
YES
YES
1048576
2147483647
Find
1048576
2147483647
submenuAction:
Find
YES
Find…
f
1048576
2147483647
1
Find Next
g
1048576
2147483647
2
Find Previous
G
1179648
2147483647
3
Use Selection for Find
e
1048576
2147483647
7
Jump to Selection
j
1048576
2147483647
Spelling and Grammar
1048576
2147483647
submenuAction:
Spelling and Grammar
YES
Show Spelling and Grammar
:
1048576
2147483647
Check Document Now
;
1048576
2147483647
YES
YES
2147483647
Check Spelling While Typing
1048576
2147483647
Check Grammar With Spelling
1048576
2147483647
Correct Spelling Automatically
2147483647
Substitutions
1048576
2147483647
submenuAction:
Substitutions
YES
Show Substitutions
2147483647
YES
YES
2147483647
Smart Copy/Paste
f
1048576
2147483647
1
Smart Quotes
g
1048576
2147483647
2
Smart Dashes
2147483647
Smart Links
G
1179648
2147483647
3
Text Replacement
2147483647
Transformations
2147483647
submenuAction:
Transformations
YES
Make Upper Case
2147483647
Make Lower Case
2147483647
Capitalize
2147483647
Speech
1048576
2147483647
submenuAction:
Speech
YES
Start Speaking
1048576
2147483647
Stop Speaking
1048576
2147483647
Format
2147483647
submenuAction:
Format
YES
Font
2147483647
submenuAction:
Font
YES
Show Fonts
t
1048576
2147483647
Bold
b
1048576
2147483647
2
Italic
i
1048576
2147483647
1
Underline
u
1048576
2147483647
YES
YES
2147483647
Bigger
+
1048576
2147483647
3
Smaller
-
1048576
2147483647
4
YES
YES
2147483647
Kern
2147483647
submenuAction:
Kern
YES
Use Default
2147483647
Use None
2147483647
Tighten
2147483647
Loosen
2147483647
Ligature
2147483647
submenuAction:
Ligature
YES
Use Default
2147483647
Use None
2147483647
Use All
2147483647
Baseline
2147483647
submenuAction:
Baseline
YES
Use Default
2147483647
Superscript
2147483647
Subscript
2147483647
Raise
2147483647
Lower
2147483647
YES
YES
2147483647
Show Colors
C
1048576
2147483647
YES
YES
2147483647
Copy Style
c
1572864
2147483647
Paste Style
v
1572864
2147483647
_NSFontMenu
Text
2147483647
submenuAction:
Text
YES
Align Left
{
1048576
2147483647
Center
|
1048576
2147483647
Justify
2147483647
Align Right
}
1048576
2147483647
YES
YES
2147483647
Writing Direction
2147483647
submenuAction:
Writing Direction
YES
YES
Paragraph
2147483647
CURlZmF1bHQ
2147483647
CUxlZnQgdG8gUmlnaHQ
2147483647
CVJpZ2h0IHRvIExlZnQ
2147483647
YES
YES
2147483647
YES
Selection
2147483647
CURlZmF1bHQ
2147483647
CUxlZnQgdG8gUmlnaHQ
2147483647
CVJpZ2h0IHRvIExlZnQ
2147483647
YES
YES
2147483647
Show Ruler
2147483647
Copy Ruler
c
1310720
2147483647
Paste Ruler
v
1310720
2147483647
View
1048576
2147483647
submenuAction:
View
YES
Show Toolbar
t
1572864
2147483647
Customize Toolbar…
1048576
2147483647
Window
1048576
2147483647
submenuAction:
Window
YES
Minimize
m
1048576
2147483647
Zoom
1048576
2147483647
YES
YES
1048576
2147483647
Bring All to Front
1048576
2147483647
_NSWindowsMenu
Help
2147483647
submenuAction:
Help
YES
RKMacOSX Help
?
1048576
2147483647
_NSHelpMenu
_NSMainMenu
15
2
{{335, 390}, {480, 360}}
1954021376
RKMacOSX
NSWindow
{1.79769e+308, 1.79769e+308}
256
{480, 360}
{{0, 0}, {1920, 1178}}
{1.79769e+308, 1.79769e+308}
RKMacOSXAppDelegate
NSFontManager
YES
performMiniaturize:
37
arrangeInFront:
39
print:
86
runPageLayout:
87
clearRecentDocuments:
127
orderFrontStandardAboutPanel:
142
performClose:
193
toggleContinuousSpellChecking:
222
undo:
223
copy:
224
checkSpelling:
225
paste:
226
stopSpeaking:
227
cut:
228
showGuessPanel:
230
redo:
231
selectAll:
232
startSpeaking:
233
delete:
235
performZoom:
240
performFindPanelAction:
241
centerSelectionInVisibleArea:
245
toggleGrammarChecking:
347
toggleSmartInsertDelete:
355
toggleAutomaticQuoteSubstitution:
356
toggleAutomaticLinkDetection:
357
saveDocument:
362
saveDocumentAs:
363
revertDocumentToSaved:
364
runToolbarCustomizationPalette:
365
toggleToolbarShown:
366
hide:
367
hideOtherApplications:
368
unhideAllApplications:
370
newDocument:
373
openDocument:
374
addFontTrait:
421
addFontTrait:
422
modifyFont:
423
orderFrontFontPanel:
424
modifyFont:
425
raiseBaseline:
426
lowerBaseline:
427
copyFont:
428
subscript:
429
superscript:
430
tightenKerning:
431
underline:
432
orderFrontColorPanel:
433
useAllLigatures:
434
loosenKerning:
435
pasteFont:
436
unscript:
437
useStandardKerning:
438
useStandardLigatures:
439
turnOffLigatures:
440
turnOffKerning:
441
terminate:
449
toggleAutomaticSpellingCorrection:
456
orderFrontSubstitutionsPanel:
458
toggleAutomaticDashSubstitution:
461
toggleAutomaticTextReplacement:
463
uppercaseWord:
464
capitalizeWord:
467
lowercaseWord:
468
pasteAsPlainText:
486
performFindPanelAction:
487
performFindPanelAction:
488
performFindPanelAction:
489
showHelp:
493
delegate
495
alignCenter:
518
pasteRuler:
519
toggleRuler:
520
alignRight:
521
copyRuler:
522
alignJustified:
523
alignLeft:
524
makeBaseWritingDirectionNatural:
525
makeBaseWritingDirectionLeftToRight:
526
makeBaseWritingDirectionRightToLeft:
527
makeTextWritingDirectionNatural:
528
makeTextWritingDirectionLeftToRight:
529
makeTextWritingDirectionRightToLeft:
530
window
532
YES
0
-2
File's Owner
-1
First Responder
-3
Application
29
YES
19
YES
56
YES
217
YES
83
YES
81
YES
75
80
78
72
82
124
YES
77
73
79
112
74
125
YES
126
205
YES
202
198
207
214
199
203
197
206
215
218
YES
216
YES
200
YES
219
201
204
220
YES
213
210
221
208
209
57
YES
58
134
150
136
144
129
143
236
131
YES
149
145
130
24
YES
92
5
239
23
295
YES
296
YES
297
298
211
YES
212
YES
195
196
346
348
YES
349
YES
350
351
354
371
YES
372
375
YES
376
YES
377
YES
388
YES
389
390
391
392
393
394
395
396
397
YES
398
YES
399
YES
400
401
402
403
404
405
YES
406
407
408
409
410
411
YES
412
413
414
415
YES
416
417
418
419
420
450
YES
451
YES
452
453
454
457
459
460
462
465
466
485
490
YES
491
YES
492
494
496
YES
497
YES
498
499
500
501
502
503
YES
504
505
506
507
508
YES
509
510
511
512
513
514
515
516
517
YES
YES
-3.IBPluginDependency
112.IBPluginDependency
112.ImportedFromIB2
124.IBPluginDependency
124.ImportedFromIB2
125.IBPluginDependency
125.ImportedFromIB2
125.editorWindowContentRectSynchronizationRect
126.IBPluginDependency
126.ImportedFromIB2
129.IBPluginDependency
129.ImportedFromIB2
130.IBPluginDependency
130.ImportedFromIB2
130.editorWindowContentRectSynchronizationRect
131.IBPluginDependency
131.ImportedFromIB2
134.IBPluginDependency
134.ImportedFromIB2
136.IBPluginDependency
136.ImportedFromIB2
143.IBPluginDependency
143.ImportedFromIB2
144.IBPluginDependency
144.ImportedFromIB2
145.IBPluginDependency
145.ImportedFromIB2
149.IBPluginDependency
149.ImportedFromIB2
150.IBPluginDependency
150.ImportedFromIB2
19.IBPluginDependency
19.ImportedFromIB2
195.IBPluginDependency
195.ImportedFromIB2
196.IBPluginDependency
196.ImportedFromIB2
197.IBPluginDependency
197.ImportedFromIB2
198.IBPluginDependency
198.ImportedFromIB2
199.IBPluginDependency
199.ImportedFromIB2
200.IBEditorWindowLastContentRect
200.IBPluginDependency
200.ImportedFromIB2
200.editorWindowContentRectSynchronizationRect
201.IBPluginDependency
201.ImportedFromIB2
202.IBPluginDependency
202.ImportedFromIB2
203.IBPluginDependency
203.ImportedFromIB2
204.IBPluginDependency
204.ImportedFromIB2
205.IBEditorWindowLastContentRect
205.IBPluginDependency
205.ImportedFromIB2
205.editorWindowContentRectSynchronizationRect
206.IBPluginDependency
206.ImportedFromIB2
207.IBPluginDependency
207.ImportedFromIB2
208.IBPluginDependency
208.ImportedFromIB2
209.IBPluginDependency
209.ImportedFromIB2
210.IBPluginDependency
210.ImportedFromIB2
211.IBPluginDependency
211.ImportedFromIB2
212.IBPluginDependency
212.ImportedFromIB2
212.editorWindowContentRectSynchronizationRect
213.IBPluginDependency
213.ImportedFromIB2
214.IBPluginDependency
214.ImportedFromIB2
215.IBPluginDependency
215.ImportedFromIB2
216.IBPluginDependency
216.ImportedFromIB2
217.IBPluginDependency
217.ImportedFromIB2
218.IBPluginDependency
218.ImportedFromIB2
219.IBPluginDependency
219.ImportedFromIB2
220.IBEditorWindowLastContentRect
220.IBPluginDependency
220.ImportedFromIB2
220.editorWindowContentRectSynchronizationRect
221.IBPluginDependency
221.ImportedFromIB2
23.IBPluginDependency
23.ImportedFromIB2
236.IBPluginDependency
236.ImportedFromIB2
239.IBPluginDependency
239.ImportedFromIB2
24.IBEditorWindowLastContentRect
24.IBPluginDependency
24.ImportedFromIB2
24.editorWindowContentRectSynchronizationRect
29.IBEditorWindowLastContentRect
29.IBPluginDependency
29.ImportedFromIB2
29.WindowOrigin
29.editorWindowContentRectSynchronizationRect
295.IBPluginDependency
296.IBEditorWindowLastContentRect
296.IBPluginDependency
296.editorWindowContentRectSynchronizationRect
297.IBPluginDependency
298.IBPluginDependency
346.IBPluginDependency
346.ImportedFromIB2
348.IBPluginDependency
348.ImportedFromIB2
349.IBEditorWindowLastContentRect
349.IBPluginDependency
349.ImportedFromIB2
349.editorWindowContentRectSynchronizationRect
350.IBPluginDependency
350.ImportedFromIB2
351.IBPluginDependency
351.ImportedFromIB2
354.IBPluginDependency
354.ImportedFromIB2
371.IBEditorWindowLastContentRect
371.IBPluginDependency
371.IBWindowTemplateEditedContentRect
371.NSWindowTemplate.visibleAtLaunch
371.editorWindowContentRectSynchronizationRect
371.windowTemplate.maxSize
372.IBPluginDependency
375.IBPluginDependency
376.IBEditorWindowLastContentRect
376.IBPluginDependency
377.IBPluginDependency
388.IBEditorWindowLastContentRect
388.IBPluginDependency
389.IBPluginDependency
390.IBPluginDependency
391.IBPluginDependency
392.IBPluginDependency
393.IBPluginDependency
394.IBPluginDependency
395.IBPluginDependency
396.IBPluginDependency
397.IBPluginDependency
398.IBPluginDependency
399.IBPluginDependency
400.IBPluginDependency
401.IBPluginDependency
402.IBPluginDependency
403.IBPluginDependency
404.IBPluginDependency
405.IBPluginDependency
406.IBPluginDependency
407.IBPluginDependency
408.IBPluginDependency
409.IBPluginDependency
410.IBPluginDependency
411.IBPluginDependency
412.IBPluginDependency
413.IBPluginDependency
414.IBPluginDependency
415.IBPluginDependency
416.IBPluginDependency
417.IBPluginDependency
418.IBPluginDependency
419.IBPluginDependency
450.IBPluginDependency
451.IBEditorWindowLastContentRect
451.IBPluginDependency
452.IBPluginDependency
453.IBPluginDependency
454.IBPluginDependency
457.IBPluginDependency
459.IBPluginDependency
460.IBPluginDependency
462.IBPluginDependency
465.IBPluginDependency
466.IBPluginDependency
485.IBPluginDependency
490.IBPluginDependency
491.IBEditorWindowLastContentRect
491.IBPluginDependency
492.IBPluginDependency
496.IBPluginDependency
497.IBEditorWindowLastContentRect
497.IBPluginDependency
498.IBPluginDependency
499.IBPluginDependency
5.IBPluginDependency
5.ImportedFromIB2
500.IBPluginDependency
501.IBPluginDependency
502.IBPluginDependency
503.IBPluginDependency
504.IBPluginDependency
505.IBPluginDependency
506.IBPluginDependency
507.IBPluginDependency
508.IBEditorWindowLastContentRect
508.IBPluginDependency
509.IBPluginDependency
510.IBPluginDependency
511.IBPluginDependency
512.IBPluginDependency
513.IBPluginDependency
514.IBPluginDependency
515.IBPluginDependency
516.IBPluginDependency
517.IBPluginDependency
56.IBPluginDependency
56.ImportedFromIB2
57.IBEditorWindowLastContentRect
57.IBPluginDependency
57.ImportedFromIB2
57.editorWindowContentRectSynchronizationRect
58.IBPluginDependency
58.ImportedFromIB2
72.IBPluginDependency
72.ImportedFromIB2
73.IBPluginDependency
73.ImportedFromIB2
74.IBPluginDependency
74.ImportedFromIB2
75.IBPluginDependency
75.ImportedFromIB2
77.IBPluginDependency
77.ImportedFromIB2
78.IBPluginDependency
78.ImportedFromIB2
79.IBPluginDependency
79.ImportedFromIB2
80.IBPluginDependency
80.ImportedFromIB2
81.IBEditorWindowLastContentRect
81.IBPluginDependency
81.ImportedFromIB2
81.editorWindowContentRectSynchronizationRect
82.IBPluginDependency
82.ImportedFromIB2
83.IBPluginDependency
83.ImportedFromIB2
92.IBPluginDependency
92.ImportedFromIB2
YES
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{522, 812}, {146, 23}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{436, 809}, {64, 6}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{753, 187}, {275, 113}}
com.apple.InterfaceBuilder.CocoaPlugin
{{608, 612}, {275, 83}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{547, 180}, {254, 283}}
com.apple.InterfaceBuilder.CocoaPlugin
{{187, 434}, {243, 243}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{608, 612}, {167, 43}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{753, 217}, {238, 103}}
com.apple.InterfaceBuilder.CocoaPlugin
{{608, 612}, {241, 103}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{654, 239}, {194, 73}}
com.apple.InterfaceBuilder.CocoaPlugin
{{525, 802}, {197, 73}}
{{380, 836}, {512, 20}}
com.apple.InterfaceBuilder.CocoaPlugin
{74, 862}
{{6, 978}, {478, 20}}
com.apple.InterfaceBuilder.CocoaPlugin
{{604, 269}, {231, 43}}
com.apple.InterfaceBuilder.CocoaPlugin
{{475, 832}, {234, 43}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{746, 287}, {220, 133}}
com.apple.InterfaceBuilder.CocoaPlugin
{{608, 612}, {215, 63}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{380, 496}, {480, 360}}
com.apple.InterfaceBuilder.CocoaPlugin
{{380, 496}, {480, 360}}
{{33, 99}, {480, 360}}
{3.40282e+38, 3.40282e+38}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{591, 420}, {83, 43}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{523, 2}, {178, 283}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{753, 197}, {170, 63}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{725, 289}, {246, 23}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{674, 260}, {204, 183}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{878, 180}, {164, 173}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{286, 129}, {275, 183}}
com.apple.InterfaceBuilder.CocoaPlugin
{{23, 794}, {245, 183}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
{{452, 109}, {196, 203}}
com.apple.InterfaceBuilder.CocoaPlugin
{{145, 474}, {199, 203}}
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
YES
YES
YES
YES
532
YES
RKMacOSXAppDelegate
NSObject
window
NSWindow
IBProjectSource
RKMacOSXAppDelegate.h
YES
NSApplication
NSResponder
IBFrameworkSource
AppKit.framework/Headers/NSApplication.h
NSApplication
IBFrameworkSource
AppKit.framework/Headers/NSApplicationScripting.h
NSApplication
IBFrameworkSource
AppKit.framework/Headers/NSColorPanel.h
NSApplication
IBFrameworkSource
AppKit.framework/Headers/NSHelpManager.h
NSApplication
IBFrameworkSource
AppKit.framework/Headers/NSPageLayout.h
NSApplication
IBFrameworkSource
AppKit.framework/Headers/NSUserInterfaceItemSearching.h
NSBrowser
NSControl
IBFrameworkSource
AppKit.framework/Headers/NSBrowser.h
NSControl
NSView
IBFrameworkSource
AppKit.framework/Headers/NSControl.h
NSDocument
NSObject
YES
YES
printDocument:
revertDocumentToSaved:
runPageLayout:
saveDocument:
saveDocumentAs:
saveDocumentTo:
YES
id
id
id
id
id
id
IBFrameworkSource
AppKit.framework/Headers/NSDocument.h
NSDocument
IBFrameworkSource
AppKit.framework/Headers/NSDocumentScripting.h
NSDocumentController
NSObject
YES
YES
clearRecentDocuments:
newDocument:
openDocument:
saveAllDocuments:
YES
id
id
id
id
IBFrameworkSource
AppKit.framework/Headers/NSDocumentController.h
NSFontManager
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSFontManager.h
NSFormatter
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSFormatter.h
NSMatrix
NSControl
IBFrameworkSource
AppKit.framework/Headers/NSMatrix.h
NSMenu
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSMenu.h
NSMenuItem
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSMenuItem.h
NSMovieView
NSView
IBFrameworkSource
AppKit.framework/Headers/NSMovieView.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSAccessibility.h
NSObject
NSObject
NSObject
NSObject
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSDictionaryController.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSDragging.h
NSObject
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSFontPanel.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSKeyValueBinding.h
NSObject
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSNibLoading.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSOutlineView.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSPasteboard.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSSavePanel.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSTableView.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSToolbarItem.h
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSView.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSArchiver.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSClassDescription.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSError.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSFileManager.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyValueCoding.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyValueObserving.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSKeyedArchiver.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSObject.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSObjectScripting.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSPortCoder.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSRunLoop.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSScriptClassDescription.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSScriptKeyValueCoding.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSScriptObjectSpecifiers.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSScriptWhoseTests.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSThread.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSURL.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSURLConnection.h
NSObject
IBFrameworkSource
Foundation.framework/Headers/NSURLDownload.h
NSResponder
IBFrameworkSource
AppKit.framework/Headers/NSInterfaceStyle.h
NSResponder
NSObject
IBFrameworkSource
AppKit.framework/Headers/NSResponder.h
NSTableView
NSControl
NSText
NSView
IBFrameworkSource
AppKit.framework/Headers/NSText.h
NSTextView
NSText
IBFrameworkSource
AppKit.framework/Headers/NSTextView.h
NSView
IBFrameworkSource
AppKit.framework/Headers/NSClipView.h
NSView
NSView
IBFrameworkSource
AppKit.framework/Headers/NSRulerView.h
NSView
NSResponder
NSWindow
IBFrameworkSource
AppKit.framework/Headers/NSDrawer.h
NSWindow
NSResponder
IBFrameworkSource
AppKit.framework/Headers/NSWindow.h
NSWindow
IBFrameworkSource
AppKit.framework/Headers/NSWindowScripting.h
0
com.apple.InterfaceBuilder.CocoaPlugin.macosx
com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
YES
../RKMacOSX.xcodeproj
3
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/en.lproj/._MainMenu.xib
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._en.lproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/main.m//
// main.m
// RKMacOSX
//
// Created by Blake Watters on 4/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._main.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/RKMacOSX-Info.plist
CFBundleDevelopmentRegion
en
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
com.twotoasters.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
LSMinimumSystemVersion
${MACOSX_DEPLOYMENT_TARGET}
NSMainNibFile
MainMenu
NSPrincipalClass
NSApplication
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._RKMacOSX-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/RKMacOSX-Prefix.pch//
// Prefix header for all source files of the 'RKMacOSX' target in the 'RKMacOSX' project
//
#ifdef __OBJC__
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._RKMacOSX-Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/RKMacOSXAppDelegate.h//
// RKMacOSXAppDelegate.h
// RKMacOSX
//
// Created by Blake Watters on 4/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
@interface RKMacOSXAppDelegate : NSObject
@property (nonatomic, retain) RKClient *client;
@property (assign) IBOutlet NSWindow *window;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._RKMacOSXAppDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/RKMacOSXAppDelegate.m//
// RKMacOSXAppDelegate.m
// RKMacOSX
//
// Created by Blake Watters on 4/10/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKMacOSXAppDelegate.h"
@implementation RKMacOSXAppDelegate
@synthesize client = _client;
@synthesize window = _window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Initialize RestKit
self.client = [RKClient clientWithBaseURL:[RKURL URLWithBaseURLString:@"http://twitter.com"]];
[self.client get:@"/status/user_timeline/RestKit.json" delegate:self];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse *)response {
NSLog(@"Loaded JSON: %@", [response bodyAsString]);
}
- (void)dealloc {
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX/._RKMacOSXAppDelegate.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/._RKMacOSX
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
250DF24F14C67F560001DEFA /* RestKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250DF24B14C67E9A0001DEFA /* RestKit.framework */; };
25D63919135184CE000879B1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D63918135184CE000879B1 /* Cocoa.framework */; };
25D63923135184CE000879B1 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 25D63921135184CE000879B1 /* InfoPlist.strings */; };
25D63926135184CE000879B1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 25D63925135184CE000879B1 /* main.m */; };
25D63929135184CE000879B1 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 25D63927135184CE000879B1 /* Credits.rtf */; };
25D6392C135184CE000879B1 /* RKMacOSXAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 25D6392B135184CE000879B1 /* RKMacOSXAppDelegate.m */; };
25D6392F135184CF000879B1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 25D6392D135184CF000879B1 /* MainMenu.xib */; };
25D6397F13518574000879B1 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D6397E13518574000879B1 /* CoreData.framework */; };
25D639811351858A000879B1 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D639801351858A000879B1 /* AppKit.framework */; };
25D63983135185B6000879B1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25D63982135185B6000879B1 /* SystemConfiguration.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
250DF24614C67E9A0001DEFA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D1614564E810060A5C5;
remoteInfo = RestKit;
};
250DF24814C67E9A0001DEFA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D2614564E820060A5C5;
remoteInfo = RestKitTests;
};
250DF24A14C67E9A0001DEFA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E62145651060060A5C5;
remoteInfo = RestKitFramework;
};
250DF24C14C67E9A0001DEFA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E78145651060060A5C5;
remoteInfo = RestKitFrameworkTests;
};
250DF25014C67F630001DEFA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160E61145651060060A5C5;
remoteInfo = RestKitFramework;
};
256780AF152D1771000725F5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 259C301615128079003066A2;
remoteInfo = RestKitResources;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
25D63914135184CE000879B1 /* RKMacOSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKMacOSX.app; sourceTree = BUILT_PRODUCTS_DIR; };
25D63918135184CE000879B1 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
25D6391B135184CE000879B1 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
25D6391C135184CE000879B1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
25D6391D135184CE000879B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
25D63920135184CE000879B1 /* RKMacOSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RKMacOSX-Info.plist"; sourceTree = "
25D63922135184CE000879B1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "
25D63924135184CE000879B1 /* RKMacOSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RKMacOSX-Prefix.pch"; sourceTree = "
25D63925135184CE000879B1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "
25D63928135184CE000879B1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "
25D6392A135184CE000879B1 /* RKMacOSXAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RKMacOSXAppDelegate.h; sourceTree = "
25D6392B135184CE000879B1 /* RKMacOSXAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RKMacOSXAppDelegate.m; sourceTree = "
25D6392E135184CF000879B1 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "
25D63938135184F0000879B1 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../../RestKit.xcodeproj; sourceTree = "
25D6397E13518574000879B1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
25D639801351858A000879B1 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
25D63982135185B6000879B1 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
25D63911135184CE000879B1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
250DF24F14C67F560001DEFA /* RestKit.framework in Frameworks */,
25D63983135185B6000879B1 /* SystemConfiguration.framework in Frameworks */,
25D639811351858A000879B1 /* AppKit.framework in Frameworks */,
25D6397F13518574000879B1 /* CoreData.framework in Frameworks */,
25D63919135184CE000879B1 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
25D63909135184CE000879B1 = {
isa = PBXGroup;
children = (
25D6391E135184CE000879B1 /* RKMacOSX */,
25D639841351868E000879B1 /* RestKit */,
25D63917135184CE000879B1 /* Frameworks */,
25D63915135184CE000879B1 /* Products */,
);
sourceTree = "
};
25D63915135184CE000879B1 /* Products */ = {
isa = PBXGroup;
children = (
25D63914135184CE000879B1 /* RKMacOSX.app */,
);
name = Products;
sourceTree = "
};
25D63917135184CE000879B1 /* Frameworks */ = {
isa = PBXGroup;
children = (
25D63982135185B6000879B1 /* SystemConfiguration.framework */,
25D639801351858A000879B1 /* AppKit.framework */,
25D6397E13518574000879B1 /* CoreData.framework */,
25D63918135184CE000879B1 /* Cocoa.framework */,
25D6391A135184CE000879B1 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "
};
25D6391A135184CE000879B1 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
25D6391B135184CE000879B1 /* AppKit.framework */,
25D6391C135184CE000879B1 /* CoreData.framework */,
25D6391D135184CE000879B1 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "
};
25D6391E135184CE000879B1 /* RKMacOSX */ = {
isa = PBXGroup;
children = (
25D6392A135184CE000879B1 /* RKMacOSXAppDelegate.h */,
25D6392B135184CE000879B1 /* RKMacOSXAppDelegate.m */,
25D6392D135184CF000879B1 /* MainMenu.xib */,
25D6391F135184CE000879B1 /* Supporting Files */,
);
path = RKMacOSX;
sourceTree = "
};
25D6391F135184CE000879B1 /* Supporting Files */ = {
isa = PBXGroup;
children = (
25D63920135184CE000879B1 /* RKMacOSX-Info.plist */,
25D63921135184CE000879B1 /* InfoPlist.strings */,
25D63924135184CE000879B1 /* RKMacOSX-Prefix.pch */,
25D63925135184CE000879B1 /* main.m */,
25D63927135184CE000879B1 /* Credits.rtf */,
);
name = "Supporting Files";
sourceTree = "
};
25D63939135184F0000879B1 /* Products */ = {
isa = PBXGroup;
children = (
250DF24714C67E9A0001DEFA /* libRestKit.a */,
250DF24914C67E9A0001DEFA /* RestKitTests.octest */,
250DF24B14C67E9A0001DEFA /* RestKit.framework */,
250DF24D14C67E9A0001DEFA /* RestKitFrameworkTests.octest */,
256780B0152D1771000725F5 /* RestKitResources.bundle */,
);
name = Products;
sourceTree = "
};
25D639841351868E000879B1 /* RestKit */ = {
isa = PBXGroup;
children = (
25D63938135184F0000879B1 /* RestKit.xcodeproj */,
);
name = RestKit;
sourceTree = "
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
25D63913135184CE000879B1 /* RKMacOSX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 25D63935135184CF000879B1 /* Build configuration list for PBXNativeTarget "RKMacOSX" */;
buildPhases = (
25D63910135184CE000879B1 /* Sources */,
25D63911135184CE000879B1 /* Frameworks */,
25D63912135184CE000879B1 /* Resources */,
);
buildRules = (
);
dependencies = (
250DF25114C67F630001DEFA /* PBXTargetDependency */,
);
name = RKMacOSX;
productName = RKMacOSX;
productReference = 25D63914135184CE000879B1 /* RKMacOSX.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
25D6390B135184CE000879B1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
};
buildConfigurationList = 25D6390E135184CE000879B1 /* Build configuration list for PBXProject "RKMacOSX" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 25D63909135184CE000879B1;
productRefGroup = 25D63915135184CE000879B1 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 25D63939135184F0000879B1 /* Products */;
ProjectRef = 25D63938135184F0000879B1 /* RestKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
25D63913135184CE000879B1 /* RKMacOSX */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
250DF24714C67E9A0001DEFA /* libRestKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRestKit.a;
remoteRef = 250DF24614C67E9A0001DEFA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250DF24914C67E9A0001DEFA /* RestKitTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitTests.octest;
remoteRef = 250DF24814C67E9A0001DEFA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250DF24B14C67E9A0001DEFA /* RestKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = RestKit.framework;
remoteRef = 250DF24A14C67E9A0001DEFA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250DF24D14C67E9A0001DEFA /* RestKitFrameworkTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitFrameworkTests.octest;
remoteRef = 250DF24C14C67E9A0001DEFA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
256780B0152D1771000725F5 /* RestKitResources.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitResources.bundle;
remoteRef = 256780AF152D1771000725F5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
25D63912135184CE000879B1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
25D63923135184CE000879B1 /* InfoPlist.strings in Resources */,
25D63929135184CE000879B1 /* Credits.rtf in Resources */,
25D6392F135184CF000879B1 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
25D63910135184CE000879B1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
25D63926135184CE000879B1 /* main.m in Sources */,
25D6392C135184CE000879B1 /* RKMacOSXAppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
250DF25114C67F630001DEFA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKitFramework;
targetProxy = 250DF25014C67F630001DEFA /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
25D63921135184CE000879B1 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
25D63922135184CE000879B1 /* en */,
);
name = InfoPlist.strings;
sourceTree = "
};
25D63927135184CE000879B1 /* Credits.rtf */ = {
isa = PBXVariantGroup;
children = (
25D63928135184CE000879B1 /* en */,
);
name = Credits.rtf;
sourceTree = "
};
25D6392D135184CF000879B1 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
25D6392E135184CF000879B1 /* en */,
);
name = MainMenu.xib;
sourceTree = "
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
25D63933135184CF000879B1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC";
SDKROOT = macosx;
};
name = Debug;
};
25D63934135184CF000879B1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_LDFLAGS = "-ObjC";
SDKROOT = macosx;
};
name = Release;
};
25D63936135184CF000879B1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RKMacOSX/RKMacOSX-Prefix.pch";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "RKMacOSX/RKMacOSX-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
25D63937135184CF000879B1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "RKMacOSX/RKMacOSX-Prefix.pch";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "RKMacOSX/RKMacOSX-Info.plist";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
25D6390E135184CE000879B1 /* Build configuration list for PBXProject "RKMacOSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
25D63933135184CF000879B1 /* Debug */,
25D63934135184CF000879B1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
25D63935135184CF000879B1 /* Build configuration list for PBXNativeTarget "RKMacOSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
25D63936135184CF000879B1 /* Debug */,
25D63937135184CF000879B1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 25D6390B135184CE000879B1 /* Project object */;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX.xcodeproj/._project.pbxproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/RKMacOSX.xcodeproj/._project.xcworkspace
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKMacOSX/._RKMacOSX.xcodeproj
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/._RKMacOSX
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTStatus.h//
// RKTStatus.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTUser.h"
@interface RKTStatus : NSObject {
NSNumber* _statusID;
NSDate* _createdAt;
NSString* _text;
NSString* _urlString;
NSString* _inReplyToScreenName;
NSNumber* _isFavorited;
RKTUser* _user;
}
/**
* The unique ID of this Status
*/
@property (nonatomic, retain) NSNumber* statusID;
/**
* Timestamp the Status was sent
*/
@property (nonatomic, retain) NSDate* createdAt;
/**
* Text of the Status
*/
@property (nonatomic, retain) NSString* text;
/**
* String version of the URL associated with the Status
*/
@property (nonatomic, retain) NSString* urlString;
/**
* The screen name of the User this Status was in response to
*/
@property (nonatomic, retain) NSString* inReplyToScreenName;
/**
* Is this status a favorite?
*/
@property (nonatomic, retain) NSNumber* isFavorited;
/**
* The User who posted this status
*/
@property (nonatomic, retain) RKTUser* user;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTStatus.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTStatus.m//
// RKTStatus.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTStatus.h"
@implementation RKTStatus
@synthesize statusID = _statusID;
@synthesize createdAt = _createdAt;
@synthesize text = _text;
@synthesize urlString = _urlString;
@synthesize inReplyToScreenName = _inReplyToScreenName;
@synthesize isFavorited = _isFavorited;
@synthesize user = _user;
- (NSString*)description {
return [NSString stringWithFormat:@"%@ (ID: %@)", self.text, self.statusID];
}
- (void)dealloc {
[_statusID release];
[_createdAt release];
[_text release];
[_urlString release];
[_inReplyToScreenName release];
[_user release];
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTStatus.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTUser.h//
// RKTUser.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
@interface RKTUser : NSObject {
NSNumber* _userID;
NSString* _name;
NSString* _screenName;
}
@property (nonatomic, retain) NSNumber* userID;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* screenName;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTUser.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTUser.m//
// RKTUser.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTUser.h"
@implementation RKTUser
@synthesize userID = _userID;
@synthesize name = _name;
@synthesize screenName = _screenName;
- (void)dealloc {
[_userID release];
[_name release];
[_screenName release];
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTUser.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTwitterAppDelegate.h//
// RKTwitterAppDelegate.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@interface RKTwitterAppDelegate : NSObject
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTwitterAppDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTwitterAppDelegate.m//
// RKTwitterAppDelegate.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import "RKTwitterAppDelegate.h"
#import "RKTwitterViewController.h"
#import "RKTStatus.h"
#import "RKTUser.h"
@implementation RKTwitterAppDelegate
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
RKLogConfigureByName("RestKit/Network*", RKLogLevelTrace);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
// Initialize RestKit
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURLString:@"http://twitter.com"];
// Enable automatic network activity indicator management
objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
// Setup our object mappings
RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[RKTUser class]];
[userMapping mapKeyPath:@"id" toAttribute:@"userID"];
[userMapping mapKeyPath:@"screen_name" toAttribute:@"screenName"];
[userMapping mapAttributes:@"name", nil];
RKObjectMapping* statusMapping = [RKObjectMapping mappingForClass:[RKTStatus class]];
[statusMapping mapKeyPathsToAttributes:@"id", @"statusID",
@"created_at", @"createdAt",
@"text", @"text",
@"url", @"urlString",
@"in_reply_to_screen_name", @"inReplyToScreenName",
@"favorited", @"isFavorited",
nil];
[statusMapping mapRelationship:@"user" withMapping:userMapping];
// Update date format so that we can parse Twitter dates properly
// Wed Sep 29 15:31:08 +0000 2010
[RKObjectMapping addDefaultDateFormatterForString:@"E MMM d HH:mm:ss Z y" inTimeZone:nil];
// Uncomment these lines to use XML, comment it to use JSON
// objectManager.acceptMIMEType = RKMIMETypeXML;
// statusMapping.rootKeyPath = @"statuses.status";
// Register our mappings with the provider using a resource path pattern
[objectManager.mappingProvider setObjectMapping:statusMapping forResourcePathPattern:@"/status/user_timeline/:username"];
// Create Window and View Controllers
RKTwitterViewController* viewController = [[[RKTwitterViewController alloc] initWithNibName:nil bundle:nil] autorelease];
UINavigationController* controller = [[UINavigationController alloc] initWithRootViewController:viewController];
UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[window addSubview:controller.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTwitterAppDelegate.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTwitterViewController.h//
// RKTwitterViewController.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
@interface RKTwitterViewController : UIViewController
UITableView* _tableView;
NSArray* _statuses;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTwitterViewController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/RKTwitterViewController.m//
// RKTwitterViewController.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTwitterViewController.h"
#import "RKTStatus.h"
@interface RKTwitterViewController (Private)
- (void)loadData;
@end
@implementation RKTwitterViewController
- (void)loadTimeline {
// Load the object model via RestKit
RKObjectManager* objectManager = [RKObjectManager sharedManager];
objectManager.client.baseURL = [RKURL URLWithString:@"http://www.twitter.com"];
[objectManager loadObjectsAtResourcePath:@"/status/user_timeline/RestKit" delegate:self];
}
- (void)loadView {
[super loadView];
// Setup View and Table View
self.title = @"RestKit Tweets";
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(loadTimeline)] autorelease];
UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"BG "]] autorelease];
imageView.frame = CGRectOffset(imageView.frame, 0, -64);
[self.view insertSubview:imageView atIndex:0];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480-64) style:UITableViewStylePlain];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:_tableView];
[self loadTimeline];
}
- (void)dealloc {
[_tableView release];
[_statuses release];
[super dealloc];
}
#pragma mark RKObjectLoaderDelegate methods
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
NSLog(@"Loaded payload: %@", [response bodyAsString]);
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
NSLog(@"Loaded statuses: %@", objects);
[_statuses release];
_statuses = [objects retain];
[_tableView reloadData];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[alert show];
NSLog(@"Hit error: %@", error);
}
#pragma mark UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [[[_statuses objectAtIndex:indexPath.row] text] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, 9000)];
return size.height + 10;
}
#pragma mark UITableViewDataSource methods
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return [_statuses count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* reuseIdentifier = @"Tweet Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (nil == cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.numberOfLines = 0;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"listbg "]];
}
cell.textLabel.text = [[_statuses objectAtIndex:indexPath.row] text];
return cell;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Classes/._RKTwitterViewController.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/._Classes
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/main.m//
// main.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"RKTwitterAppDelegate");
[pool release];
return retVal;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/._main.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/BG
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._BG
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/BG@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._BG@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/Default
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._Default
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/Default@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._Default@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/listbg
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._listbg
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/listbg@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._listbg@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/RKTwitter-Info.plist
CFBundleDevelopmentRegion
English
CFBundleDisplayName
${PRODUCT_NAME}
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
com.yourcompany.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
APPL
CFBundleSignature
????
CFBundleVersion
1.0
LSRequiresIPhoneOS
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/Resources/._RKTwitter-Info.plist
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/._Resources
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */; };
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
250CA69A147D8FCC0047D347 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA699147D8FCC0047D347 /* Security.framework */; };
250CA69B147D8FD30047D347 /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160FB31456E8A30060A5C5 /* libRestKit.a */; };
250CA69C147D8FFD0047D347 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E864123424F000ACB5D7 /* CoreData.framework */; };
2538E811123419CA00ACB5D7 /* RKTUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E810123419CA00ACB5D7 /* RKTUser.m */; };
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E813123419EC00ACB5D7 /* RKTStatus.m */; };
2538E8671234250100ACB5D7 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E8661234250100ACB5D7 /* SystemConfiguration.framework */; };
25BE936614F96729008BC1C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25BE936514F96729008BC1C0 /* QuartzCore.framework */; };
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */; };
3F02F592131D683A004E1F54 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F02F591131D683A004E1F54 /* libxml2.dylib */; };
3F3CE3FC125B9A6E0083FDCB /* listbg in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FA125B9A6E0083FDCB /* listbg */; };
3F3CE3FD125B9A6E0083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FB125B9A6E0083FDCB /* */; };
3F3CE40E125B9B450083FDCB /* BG in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40A125B9B450083FDCB /* BG */; };
3F3CE40F125B9B450083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40B125B9B450083FDCB /* */; };
3F3CE410125B9B450083FDCB /* Default in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40C125B9B450083FDCB /* Default */; };
3F3CE411125B9B450083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40D125B9B450083FDCB /* */; };
84F524C212824D5000C370EA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F524C112824D5000C370EA /* CFNetwork.framework */; };
84F524C612824D5B00C370EA /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F524C512824D5B00C370EA /* MobileCoreServices.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
250AC4BA1358C7A8006F084F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160D1514564E810060A5C5;
remoteInfo = RestKit;
};
25160FB21456E8A30060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D1614564E810060A5C5;
remoteInfo = RestKit;
};
25160FB41456E8A30060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D2614564E820060A5C5;
remoteInfo = RestKitTests;
};
25160FB61456E8A30060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E62145651060060A5C5;
remoteInfo = RestKitFramework;
};
25160FB81456E8A30060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E78145651060060A5C5;
remoteInfo = RestKitFrameworkTests;
};
D3FAFBE1151B815C00468702 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 259C301615128079003066A2;
remoteInfo = RestKitResources;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterAppDelegate.h; sourceTree = "
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterAppDelegate.m; sourceTree = "
1D6058910D05DD3D006BFB54 /* RKTwitter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKTwitter.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
250AC48A1358C79C006F084F /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../../RestKit.xcodeproj; sourceTree = "
250CA699147D8FCC0047D347 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
2538E80F123419CA00ACB5D7 /* RKTUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTUser.h; sourceTree = "
2538E810123419CA00ACB5D7 /* RKTUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTUser.m; sourceTree = "
2538E812123419EC00ACB5D7 /* RKTStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTStatus.h; sourceTree = "
2538E813123419EC00ACB5D7 /* RKTStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTStatus.m; sourceTree = "
2538E864123424F000ACB5D7 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
2538E8661234250100ACB5D7 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
25BE936514F96729008BC1C0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterViewController.h; sourceTree = "
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterViewController.m; sourceTree = "
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitter_Prefix.pch; sourceTree = "
3F02F591131D683A004E1F54 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
3F3CE3FA125B9A6E0083FDCB /* listbg */ = {isa = PBXFileReference; lastKnownFileType = image ; path = listbg ; sourceTree = "
3F3CE3FB125B9A6E0083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
3F3CE40A125B9B450083FDCB /* BG */ = {isa = PBXFileReference; lastKnownFileType = image ; path = BG ; sourceTree = "
3F3CE40B125B9B450083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
3F3CE40C125B9B450083FDCB /* Default */ = {isa = PBXFileReference; lastKnownFileType = image ; path = Default ; sourceTree = "
3F3CE40D125B9B450083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
84F524C112824D5000C370EA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
84F524C512824D5B00C370EA /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RKTwitter-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
25BE936614F96729008BC1C0 /* QuartzCore.framework in Frameworks */,
250CA69C147D8FFD0047D347 /* CoreData.framework in Frameworks */,
250CA69B147D8FD30047D347 /* libRestKit.a in Frameworks */,
250CA69A147D8FCC0047D347 /* Security.framework in Frameworks */,
3F02F592131D683A004E1F54 /* libxml2.dylib in Frameworks */,
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
2538E8671234250100ACB5D7 /* SystemConfiguration.framework in Frameworks */,
84F524C212824D5000C370EA /* CFNetwork.framework in Frameworks */,
84F524C612824D5B00C370EA /* MobileCoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */,
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */,
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */,
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */,
2538E80F123419CA00ACB5D7 /* RKTUser.h */,
2538E810123419CA00ACB5D7 /* RKTUser.m */,
2538E812123419EC00ACB5D7 /* RKTStatus.h */,
2538E813123419EC00ACB5D7 /* RKTStatus.m */,
);
path = Classes;
sourceTree = "
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
1D6058910D05DD3D006BFB54 /* RKTwitter.app */,
);
name = Products;
sourceTree = "
};
250AC48B1358C79C006F084F /* Products */ = {
isa = PBXGroup;
children = (
25160FB31456E8A30060A5C5 /* libRestKit.a */,
25160FB51456E8A30060A5C5 /* RestKitTests.octest */,
25160FB71456E8A30060A5C5 /* RestKit.framework */,
25160FB91456E8A30060A5C5 /* RestKitFrameworkTests.octest */,
D3FAFBE2151B815C00468702 /* RestKitResources.bundle */,
);
name = Products;
sourceTree = "
};
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
250AC48A1358C79C006F084F /* RestKit.xcodeproj */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = CustomTemplate;
sourceTree = "
};
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */,
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
3F3CE40A125B9B450083FDCB /* BG */,
3F3CE40B125B9B450083FDCB /* */,
3F3CE40C125B9B450083FDCB /* Default */,
3F3CE40D125B9B450083FDCB /* */,
3F3CE3FA125B9A6E0083FDCB /* listbg */,
3F3CE3FB125B9A6E0083FDCB /* */,
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */,
);
path = Resources;
sourceTree = "
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
25BE936514F96729008BC1C0 /* QuartzCore.framework */,
250CA699147D8FCC0047D347 /* Security.framework */,
3F02F591131D683A004E1F54 /* libxml2.dylib */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
288765A40DF7441C002DB57D /* CoreGraphics.framework */,
2538E864123424F000ACB5D7 /* CoreData.framework */,
2538E8661234250100ACB5D7 /* SystemConfiguration.framework */,
84F524C112824D5000C370EA /* CFNetwork.framework */,
84F524C512824D5B00C370EA /* MobileCoreServices.framework */,
);
name = Frameworks;
sourceTree = "
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1D6058900D05DD3D006BFB54 /* RKTwitter */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitter" */;
buildPhases = (
1D60588D0D05DD3D006BFB54 /* Resources */,
1D60588E0D05DD3D006BFB54 /* Sources */,
1D60588F0D05DD3D006BFB54 /* Frameworks */,
);
buildRules = (
);
dependencies = (
250AC4BB1358C7A8006F084F /* PBXTargetDependency */,
);
name = RKTwitter;
productName = RKTwitter;
productReference = 1D6058910D05DD3D006BFB54 /* RKTwitter.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitter" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 250AC48B1358C79C006F084F /* Products */;
ProjectRef = 250AC48A1358C79C006F084F /* RestKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
1D6058900D05DD3D006BFB54 /* RKTwitter */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
25160FB31456E8A30060A5C5 /* libRestKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRestKit.a;
remoteRef = 25160FB21456E8A30060A5C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25160FB51456E8A30060A5C5 /* RestKitTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitTests.octest;
remoteRef = 25160FB41456E8A30060A5C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25160FB71456E8A30060A5C5 /* RestKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = RestKit.framework;
remoteRef = 25160FB61456E8A30060A5C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25160FB91456E8A30060A5C5 /* RestKitFrameworkTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitFrameworkTests.octest;
remoteRef = 25160FB81456E8A30060A5C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D3FAFBE2151B815C00468702 /* RestKitResources.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitResources.bundle;
remoteRef = D3FAFBE1151B815C00468702 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
1D60588D0D05DD3D006BFB54 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3F3CE3FC125B9A6E0083FDCB /* listbg in Resources */,
3F3CE3FD125B9A6E0083FDCB /* in Resources */,
3F3CE40E125B9B450083FDCB /* BG in Resources */,
3F3CE40F125B9B450083FDCB /* in Resources */,
3F3CE410125B9B450083FDCB /* Default in Resources */,
3F3CE411125B9B450083FDCB /* in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1D60588E0D05DD3D006BFB54 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */,
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */,
2538E811123419CA00ACB5D7 /* RKTUser.m in Sources */,
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
250AC4BB1358C7A8006F084F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKit;
targetProxy = 250AC4BA1358C7A8006F084F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
1D6058940D05DD3E006BFB54 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Debug;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RKTwitter;
};
name = Debug;
};
1D6058950D05DD3E006BFB54 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Release;
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RKTwitter;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
BUILD_STYLE = Debug;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
BUILD_STYLE = Release;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitter" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1D6058940D05DD3E006BFB54 /* Debug */,
1D6058950D05DD3E006BFB54 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitter" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}
listbg@2x listbg@2x BG@2x BG@2x Default@2x Default@2x listbg@2x listbg@2x BG@2x BG@2x Default@2x Default@2x BG@2x Default@2x listbg@2x listbg@2x BG@2x Default@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter.xcodeproj/._project.pbxproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter.xcodeproj/._project.xcworkspace
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/._RKTwitter.xcodeproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/RKTwitter_Prefix.pch//
// Prefix header for all source files of the 'RKTwitter' target in the 'RKTwitter' project
//
#ifdef __OBJC__
#import
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitter/._RKTwitter_Prefix.pch
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/._RKTwitter
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTStatus.h//
// RKTStatus.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
@interface RKTStatus : NSManagedObject {
}
/**
* The unique ID of this Status
*/
@property (nonatomic, retain) NSNumber* statusID;
/**
* Timestamp the Status was sent
*/
@property (nonatomic, retain) NSDate* createdAt;
/**
* Text of the Status
*/
@property (nonatomic, retain) NSString* text;
/**
* String version of the URL associated with the Status
*/
@property (nonatomic, retain) NSString* urlString;
/**
* The screen name of the User this Status was in response to
*/
@property (nonatomic, retain) NSString* inReplyToScreenName;
/**
* Is this status a favorite?
*/
@property (nonatomic, assign) BOOL isFavorited;
/**
* The User who posted this status
*/
@property (nonatomic, retain) NSManagedObject* user;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTStatus.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTStatus.m//
// RKTStatus.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTStatus.h"
@implementation RKTStatus
@dynamic statusID;
@dynamic createdAt;
@dynamic text;
@dynamic urlString;
@dynamic inReplyToScreenName;
@dynamic isFavorited;
@dynamic user;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTStatus.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTwitterAppDelegate.h//
// RKTwitterAppDelegate.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
@interface RKTwitterAppDelegate : NSObject
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTwitterAppDelegate.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTwitterAppDelegate.m//
// RKTwitterAppDelegate.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
#import "RKTwitterAppDelegate.h"
#import "RKTwitterViewController.h"
#import "RKTStatus.h"
@implementation RKTwitterAppDelegate
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize RestKit
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURLString:@"http://twitter.com"];
// Enable automatic network activity indicator management
objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
// Initialize object store
#ifdef RESTKIT_GENERATE_SEED_DB
NSString *seedDatabaseName = nil;
NSString *databaseName = RKDefaultSeedDatabaseFileName;
#else
NSString *seedDatabaseName = RKDefaultSeedDatabaseFileName;
NSString *databaseName = @"RKTwitterData.sqlite";
#endif
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:databaseName usingSeedDatabaseName:seedDatabaseName managedObjectModel:nil delegate:self];
// Setup our object mappings
/*!
Mapping by entity. Here we are configuring a mapping by targetting a Core Data entity with a specific
name. This allows us to map back Twitter user objects directly onto NSManagedObject instances --
there is no backing model class!
*/
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForEntityWithName:@"RKTUser" inManagedObjectStore:objectManager.objectStore];
userMapping.primaryKeyAttribute = @"userID";
[userMapping mapKeyPath:@"id" toAttribute:@"userID"];
[userMapping mapKeyPath:@"screen_name" toAttribute:@"screenName"];
[userMapping mapAttributes:@"name", nil];
/*!
Map to a target object class -- just as you would for a non-persistent class. The entity is resolved
for you using the Active Record pattern where the class name corresponds to the entity name within Core Data.
Twitter status objects will be mapped onto RKTStatus instances.
*/
RKManagedObjectMapping* statusMapping = [RKManagedObjectMapping mappingForClass:[RKTStatus class] inManagedObjectStore:objectManager.objectStore];
statusMapping.primaryKeyAttribute = @"statusID";
[statusMapping mapKeyPathsToAttributes:@"id", @"statusID",
@"created_at", @"createdAt",
@"text", @"text",
@"url", @"urlString",
@"in_reply_to_screen_name", @"inReplyToScreenName",
@"favorited", @"isFavorited",
nil];
[statusMapping mapRelationship:@"user" withMapping:userMapping];
// Update date format so that we can parse Twitter dates properly
// Wed Sep 29 15:31:08 +0000 2010
[RKObjectMapping addDefaultDateFormatterForString:@"E MMM d HH:mm:ss Z y" inTimeZone:nil];
// Register our mappings with the provider
[objectManager.mappingProvider setObjectMapping:statusMapping forResourcePathPattern:@"/status/user_timeline/:username"];
// Uncomment this to use XML, comment it to use JSON
// objectManager.acceptMIMEType = RKMIMETypeXML;
// [objectManager.mappingProvider setMapping:statusMapping forKeyPath:@"statuses.status"];
// Database seeding is configured as a copied target of the main application. There are only two differences
// between the main application target and the 'Generate Seed Database' target:
// 1) RESTKIT_GENERATE_SEED_DB is defined in the 'Preprocessor Macros' section of the build setting for the target
// This is what triggers the conditional compilation to cause the seed database to be built
// 2) Source JSON files are added to the 'Generate Seed Database' target to be copied into the bundle. This is required
// so that the object seeder can find the files when run in the simulator.
#ifdef RESTKIT_GENERATE_SEED_DB
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelInfo);
RKLogConfigureByName("RestKit/CoreData", RKLogLevelTrace);
RKManagedObjectSeeder* seeder = [RKManagedObjectSeeder objectSeederWithObjectManager:objectManager];
// Seed the database with instances of RKTStatus from a snapshot of the RestKit Twitter timeline
[seeder seedObjectsFromFile:@"restkit.json" withObjectMapping:statusMapping];
// Seed the database with RKTUser objects. The class will be inferred via element registration
[seeder seedObjectsFromFiles:@"users.json", nil];
// Finalize the seeding operation and output a helpful informational message
[seeder finalizeSeedingAndExit];
// NOTE: If all of your mapped objects use keyPath -> objectMapping registration, you can perform seeding in one line of code:
// [RKManagedObjectSeeder generateSeedDatabaseWithObjectManager:objectManager fromFiles:@"users.json", nil];
#endif
// Create Window and View Controllers
RKTwitterViewController* viewController = [[[RKTwitterViewController alloc] initWithNibName:nil bundle:nil] autorelease];
UINavigationController* controller = [[UINavigationController alloc] initWithRootViewController:viewController];
UIWindow* window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[window addSubview:controller.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[super dealloc];
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTwitterAppDelegate.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTwitterViewController.h//
// RKTwitterViewController.h
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
#import
@interface RKTwitterViewController : UIViewController
UITableView* _tableView;
NSArray* _statuses;
}
- (void)loadObjectsFromDataStore;
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTwitterViewController.h
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/RKTwitterViewController.m//
// RKTwitterViewController.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTwitterViewController.h"
#import "RKTStatus.h"
@implementation RKTwitterViewController
- (void)loadView {
[super loadView];
// Setup View and Table View
self.title = @"RestKit Tweets";
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(reloadButtonWasPressed:)] autorelease];
UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"BG "]] autorelease];
imageView.frame = CGRectOffset(imageView.frame, 0, -64);
[self.view insertSubview:imageView atIndex:0];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480-64) style:UITableViewStylePlain];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:_tableView];
// Load statuses from core data
[self loadObjectsFromDataStore];
}
- (void)dealloc {
[_tableView release];
[_statuses release];
[super dealloc];
}
- (void)loadObjectsFromDataStore {
[_statuses release];
NSFetchRequest* request = [RKTStatus fetchRequest];
NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO];
[request setSortDescriptors:[NSArray arrayWithObject:descriptor]];
_statuses = [[RKTStatus objectsWithFetchRequest:request] retain];
}
- (void)loadData {
// Load the object model via RestKit
RKObjectManager* objectManager = [RKObjectManager sharedManager];
[objectManager loadObjectsAtResourcePath:@"/status/user_timeline/RestKit" delegate:self];
}
- (void)reloadButtonWasPressed:(id)sender {
// Load the object model via RestKit
[self loadData];
}
#pragma mark RKObjectLoaderDelegate methods
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"LastUpdatedAt"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"Loaded statuses: %@", objects);
[self loadObjectsFromDataStore];
[_tableView reloadData];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:@"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
[alert show];
NSLog(@"Hit error: %@", error);
}
#pragma mark UITableViewDelegate methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [[[_statuses objectAtIndex:indexPath.row] text] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, 9000)];
return size.height + 10;
}
#pragma mark UITableViewDataSource methods
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return [_statuses count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSDate* lastUpdatedAt = [[NSUserDefaults standardUserDefaults] objectForKey:@"LastUpdatedAt"];
NSString* dateString = [NSDateFormatter localizedStringFromDate:lastUpdatedAt dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterMediumStyle];
if (nil == dateString) {
dateString = @"Never";
}
return [NSString stringWithFormat:@"Last Load: %@", dateString];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* reuseIdentifier = @"Tweet Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (nil == cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.numberOfLines = 0;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"listbg "]];
}
RKTStatus* status = [_statuses objectAtIndex:indexPath.row];
cell.textLabel.text = status.text;
return cell;
}
@end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Classes/._RKTwitterViewController.m
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._Classes
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/main.m//
// main.m
// RKTwitter
//
// Created by Blake Watters on 9/5/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"RKTwitterAppDelegate");
[pool release];
return retVal;
}
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._main.m
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/BG
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._BG
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/BG@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._BG@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/Default
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._Default
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/Default@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._Default@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/listbg
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._listbg
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/listbg@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._listbg@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/RKTwitter-Info.plist
CFBundleDevelopmentRegion
English
CFBundleDisplayName
${PRODUCT_NAME}
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
com.yourcompany.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
APPL
CFBundleSignature
????
CFBundleVersion
1.0
LSRequiresIPhoneOS
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._RKTwitter-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/RKTwitterCoreData.xcdatamodel/elements
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/RKTwitterCoreData.xcdatamodel/._elements
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/RKTwitterCoreData.xcdatamodel/layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/RKTwitterCoreData.xcdatamodel/._layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/Resources/._RKTwitterCoreData.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._Resources
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/restkit.json[{"in_reply_to_status_id_str":"42716229147967491","text":"@JustJenFelice Be sure to join the Google Group and reach out if you need any support!","contributors":null,"retweeted":false,"in_reply_to_user_id_str":"7426812","retweet_count":0,"id_str":"44029179364253696","source":"\u003Ca href=\"http:\/\/twitter.com\" rel=\"nofollow\"\u003ETweetie for Mac\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Sat Mar 05 13:39:09 +0000 2011","place":null,"in_reply_to_status_id":42716229147967491,"coordinates":null,"favorited":false,"user":{"following":true,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","is_translator":false,"show_all_inline_media":false,"geo_enabled":false,"time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","follow_request_sent":false,"profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","profile_background_tile":true,"location":"","contributors_enabled":false,"statuses_count":136,"lang":"en","verified":false,"notifications":false,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","listed_count":5,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":44029179364253696,"in_reply_to_screen_name":"JustJenFelice","in_reply_to_user_id":7426812},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/h180ef Blake Watters - Added new initializer for starting from a seed database. Need to finish cleaning up API an...","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"43646264163844096","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Fri Mar 04 12:17:34 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":43646264163844096,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/fa2Law Blake Watters - Silenced a couple of Xcode 4 warning. Don't send a serialization with a GET request by def...","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"43074105142026241","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Mar 02 22:24:01 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":43074105142026241,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/fBWUre Jeremy Ellison - update projects to link libxml2 (verified working). Update readme to mention changes","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"42660583622975488","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Tue Mar 01 19:00:50 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":42660583622975488,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/ho92wG Jeremy Ellison - Working XML Support. Twitter example working (XML and JSON)","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"42660582243049472","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Tue Mar 01 19:00:50 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":42660582243049472,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/dPAmx6 Jeremy Ellison - make RKXMLParser support RKParser protocol","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"42660580796022784","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Tue Mar 01 19:00:49 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":42660580796022784,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/gfGynL Jeremy Ellison - add RKXMLParser","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"42660579399307264","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Tue Mar 01 19:00:49 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":42660579399307264,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/fVQI5Q Blake Watters - Fixed crash during dealloc of RKClient due to initialization of baseURL observer using a b...","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"41221933492076544","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Fri Feb 25 19:44:09 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":41221933492076544,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/hJtNCV Jeremy Ellison - Merge branch 'gtio-mapping-updates' of github.com:twotoasters\/RestKit into gtio-mapping-u...","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"41221089635864576","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Fri Feb 25 19:40:48 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":41221089635864576,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/fZYIyg Jeremy Ellison - Add did cancel delegate","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"41221088297877504","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Fri Feb 25 19:40:47 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":41221088297877504,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":"36907142883573761","text":"@chrisabruce New Xcode 4 specific install instructions are now included. Should be fully compatible with Xcode 3 and 4 now","contributors":null,"retweeted":false,"in_reply_to_user_id_str":"104933758","retweet_count":0,"id_str":"37909707221897216","source":"\u003Ca href=\"http:\/\/twitter.com\" rel=\"nofollow\"\u003ETweetie for Mac\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 16:22:33 +0000 2011","place":null,"in_reply_to_status_id":36907142883573761,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37909707221897216,"in_reply_to_screen_name":"chrisabruce","in_reply_to_user_id":104933758},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/gUIrfk Blake Watters - Updates to quick start section","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37906943557369856","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 16:11:34 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37906943557369856,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/eabC8R Blake Watters - Trying to get formatting right for Github flavored markdown","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37905652214923264","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 16:06:26 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37905652214923264,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/g8b9VX Blake Watters - Merge branch 'master' of github.com:twotoasters\/RestKit\n\nConflicts:\n\tRestKit.xcodeproj\/pro...","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37905228544217089","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 16:04:45 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37905228544217089,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/f1DpxP Blake Watters - Xcode 4 specific install instructions","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37905226803589120","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 16:04:44 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37905226803589120,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/dNaG1Z Blake Watters - Fix for whitespace. Really annoyed at Xcode 4","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37713900346548224","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 03:24:29 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37713900346548224,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/g72vPt Blake Watters - trying to get the project to work with various Xcode output path settings","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37697830005112832","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 02:20:37 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37697830005112832,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"Xcode 4 build environment changes are very frustrating.","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37686673852604416","source":"\u003Ca href=\"http:\/\/twitter.com\" rel=\"nofollow\"\u003ETweetie for Mac\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 01:36:17 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37686673852604416,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":null,"text":"[RestKit] http:\/\/bit.ly\/dPjF4h Blake Watters - More Xcode 4 crap","contributors":null,"retweeted":false,"in_reply_to_user_id_str":null,"retweet_count":0,"id_str":"37684000310951936","source":"\u003Ca href=\"http:\/\/github.com\" rel=\"nofollow\"\u003EGitHub Service Hooks\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 01:25:40 +0000 2011","place":null,"in_reply_to_status_id":null,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37684000310951936,"in_reply_to_screen_name":null,"in_reply_to_user_id":null},{"in_reply_to_status_id_str":"36907142883573761","text":"@chrisabruce Xcode 4 fixes were recently pushed","contributors":null,"retweeted":false,"in_reply_to_user_id_str":"104933758","retweet_count":0,"id_str":"37676602791821312","source":"\u003Ca href=\"http:\/\/twitter.com\" rel=\"nofollow\"\u003ETweetie for Mac\u003C\/a\u003E","geo":null,"truncated":false,"created_at":"Wed Feb 16 00:56:16 +0000 2011","place":null,"in_reply_to_status_id":36907142883573761,"coordinates":null,"favorited":false,"user":{"is_translator":false,"contributors_enabled":false,"following":null,"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/181380497\/twitter-bg ","favourites_count":0,"follow_request_sent":null,"statuses_count":136,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1190091434\/restkit-twitter-logo_normal ","description":"RestKit is a framework for consuming and modeling restful web resources on OS X and iOS (iPhone, iPad & iPod Touch) - Built by @twotoasters","time_zone":null,"friends_count":87,"profile_text_color":"333333","url":"http:\/\/restkit.org","profile_sidebar_fill_color":"efefef","screen_name":"RestKit","id_str":"208727870","geo_enabled":false,"profile_background_tile":true,"location":"","listed_count":5,"lang":"en","verified":false,"notifications":null,"created_at":"Wed Oct 27 20:46:12 +0000 2010","profile_link_color":"009999","show_all_inline_media":false,"profile_sidebar_border_color":"eeeeee","protected":false,"followers_count":122,"name":"RestKit","profile_use_background_image":true,"id":208727870,"utc_offset":null,"profile_background_color":"131516"},"id":37676602791821312,"in_reply_to_screen_name":"chrisabruce","in_reply_to_user_id":104933758}]
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._restkit.json
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKSeedDatabase.sqlite
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._RKSeedDatabase.sqlite
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitter_Prefix.pch//
// Prefix header for all source files of the 'RKTwitter' target in the 'RKTwitter' project
//
#ifdef __OBJC__
#import
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._RKTwitter_Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitterCoreData.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */; };
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
25014071153706FD004E0466 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA6CF147D90C50047D347 /* Security.framework */; };
25014085153707CB004E0466 /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA6C6147D90A50047D347 /* libRestKit.a */; };
25014086153707E2004E0466 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD39C14D14EEED8700E84874 /* QuartzCore.framework */; };
250CA6CE147D90BA0047D347 /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA6C6147D90A50047D347 /* libRestKit.a */; };
250CA6D0147D90C50047D347 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA6CF147D90C50047D347 /* Security.framework */; };
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E813123419EC00ACB5D7 /* RKTStatus.m */; };
2538E865123424F000ACB5D7 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E864123424F000ACB5D7 /* CoreData.framework */; };
2538E8671234250100ACB5D7 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E8661234250100ACB5D7 /* SystemConfiguration.framework */; };
25F2A1791322D59400A33DE4 /* listbg in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FA125B9A6E0083FDCB /* listbg */; };
25F2A17A1322D59400A33DE4 /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FB125B9A6E0083FDCB /* */; };
25F2A17B1322D59400A33DE4 /* BG in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40A125B9B450083FDCB /* BG */; };
25F2A17C1322D59400A33DE4 /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40B125B9B450083FDCB /* */; };
25F2A17D1322D59400A33DE4 /* Default in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40C125B9B450083FDCB /* Default */; };
25F2A17E1322D59400A33DE4 /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40D125B9B450083FDCB /* */; };
25F2A1801322D59400A33DE4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
25F2A1811322D59400A33DE4 /* RKTwitterAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */; };
25F2A1821322D59400A33DE4 /* RKTwitterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */; };
25F2A1841322D59400A33DE4 /* RKTStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538E813123419EC00ACB5D7 /* RKTStatus.m */; };
25F2A1851322D59400A33DE4 /* RKTwitterCoreData.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 3F94E0C6125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel */; };
25F2A1871322D59400A33DE4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
25F2A1881322D59400A33DE4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
25F2A1891322D59400A33DE4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
25F2A18A1322D59400A33DE4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E864123424F000ACB5D7 /* CoreData.framework */; };
25F2A18B1322D59400A33DE4 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2538E8661234250100ACB5D7 /* SystemConfiguration.framework */; };
25F2A1911322D59400A33DE4 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8452D3F8128244D90069F4A9 /* CFNetwork.framework */; };
25F2A1921322D59400A33DE4 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8452D3FC128244E60069F4A9 /* MobileCoreServices.framework */; };
25F2A1991322D93500A33DE4 /* restkit.json in Resources */ = {isa = PBXBuildFile; fileRef = 25F2A1981322D93500A33DE4 /* restkit.json */; };
25F2A19C1322DD1800A33DE4 /* users.json in Resources */ = {isa = PBXBuildFile; fileRef = 25F2A19A1322DCDC00A33DE4 /* users.json */; };
25F2A2D913240CEC00A33DE4 /* RKSeedDatabase.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 25F2A2D813240CEC00A33DE4 /* RKSeedDatabase.sqlite */; };
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */; };
3F3CE3FC125B9A6E0083FDCB /* listbg in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FA125B9A6E0083FDCB /* listbg */; };
3F3CE3FD125B9A6E0083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE3FB125B9A6E0083FDCB /* */; };
3F3CE40E125B9B450083FDCB /* BG in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40A125B9B450083FDCB /* BG */; };
3F3CE40F125B9B450083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40B125B9B450083FDCB /* */; };
3F3CE410125B9B450083FDCB /* Default in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40C125B9B450083FDCB /* Default */; };
3F3CE411125B9B450083FDCB /* in Resources */ = {isa = PBXBuildFile; fileRef = 3F3CE40D125B9B450083FDCB /* */; };
3F94E0C7125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 3F94E0C6125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel */; };
3FB46641131D78A400E37C51 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3FB46640131D78A400E37C51 /* libxml2.dylib */; };
8452D3F9128244D90069F4A9 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8452D3F8128244D90069F4A9 /* CFNetwork.framework */; };
8452D3FD128244E60069F4A9 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8452D3FC128244E60069F4A9 /* MobileCoreServices.framework */; };
CD39C14E14EEED8700E84874 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD39C14D14EEED8700E84874 /* QuartzCore.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
250CA6C5147D90A50047D347 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D1614564E810060A5C5;
remoteInfo = RestKit;
};
250CA6C7147D90A50047D347 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160D2614564E820060A5C5;
remoteInfo = RestKitTests;
};
250CA6C9147D90A50047D347 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E62145651060060A5C5;
remoteInfo = RestKitFramework;
};
250CA6CB147D90A50047D347 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 25160E78145651060060A5C5;
remoteInfo = RestKitFrameworkTests;
};
256780DD152D1A92000725F5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 259C301615128079003066A2;
remoteInfo = RestKitResources;
};
25F2A1771322D59400A33DE4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160D1514564E810060A5C5;
remoteInfo = RestKit;
};
3F3CE2E3125B93EB0083FDCB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 25160D1514564E810060A5C5;
remoteInfo = RestKit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterAppDelegate.h; sourceTree = "
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterAppDelegate.m; sourceTree = "
1D6058910D05DD3D006BFB54 /* RKTwitterCoreData.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKTwitterCoreData.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
250CA6CF147D90C50047D347 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../../RestKit.xcodeproj; sourceTree = SOURCE_ROOT; };
2538E812123419EC00ACB5D7 /* RKTStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTStatus.h; sourceTree = "
2538E813123419EC00ACB5D7 /* RKTStatus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTStatus.m; sourceTree = "
2538E864123424F000ACB5D7 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
2538E8661234250100ACB5D7 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
25F2A1961322D59400A33DE4 /* Generate Seed Database.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Generate Seed Database.app"; sourceTree = BUILT_PRODUCTS_DIR; };
25F2A1981322D93500A33DE4 /* restkit.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = restkit.json; sourceTree = SOURCE_ROOT; };
25F2A19A1322DCDC00A33DE4 /* users.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = users.json; path = ../users.json; sourceTree = "
25F2A2D813240CEC00A33DE4 /* RKSeedDatabase.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = RKSeedDatabase.sqlite; sourceTree = SOURCE_ROOT; };
288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitterViewController.h; sourceTree = "
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTwitterViewController.m; sourceTree = "
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTwitter_Prefix.pch; sourceTree = "
3F3CE3FA125B9A6E0083FDCB /* listbg */ = {isa = PBXFileReference; lastKnownFileType = image ; path = listbg ; sourceTree = "
3F3CE3FB125B9A6E0083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
3F3CE40A125B9B450083FDCB /* BG */ = {isa = PBXFileReference; lastKnownFileType = image ; path = BG ; sourceTree = "
3F3CE40B125B9B450083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
3F3CE40C125B9B450083FDCB /* Default */ = {isa = PBXFileReference; lastKnownFileType = image ; path = Default ; sourceTree = "
3F3CE40D125B9B450083FDCB /* */ = {isa = PBXFileReference; lastKnownFileType = image ; path = ""; sourceTree = "
3F94E0C6125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = RKTwitterCoreData.xcdatamodel; sourceTree = "
3FB46640131D78A400E37C51 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
8452D3F8128244D90069F4A9 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
8452D3FC128244E60069F4A9 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RKTwitter-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "
CD39C14D14EEED8700E84874 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CD39C14E14EEED8700E84874 /* QuartzCore.framework in Frameworks */,
250CA6D0147D90C50047D347 /* Security.framework in Frameworks */,
250CA6CE147D90BA0047D347 /* libRestKit.a in Frameworks */,
3FB46641131D78A400E37C51 /* libxml2.dylib in Frameworks */,
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
2538E865123424F000ACB5D7 /* CoreData.framework in Frameworks */,
2538E8671234250100ACB5D7 /* SystemConfiguration.framework in Frameworks */,
8452D3F9128244D90069F4A9 /* CFNetwork.framework in Frameworks */,
8452D3FD128244E60069F4A9 /* MobileCoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
25F2A1861322D59400A33DE4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
25014086153707E2004E0466 /* QuartzCore.framework in Frameworks */,
25014085153707CB004E0466 /* libRestKit.a in Frameworks */,
25014071153706FD004E0466 /* Security.framework in Frameworks */,
25F2A1871322D59400A33DE4 /* Foundation.framework in Frameworks */,
25F2A1881322D59400A33DE4 /* UIKit.framework in Frameworks */,
25F2A1891322D59400A33DE4 /* CoreGraphics.framework in Frameworks */,
25F2A18A1322D59400A33DE4 /* CoreData.framework in Frameworks */,
25F2A18B1322D59400A33DE4 /* SystemConfiguration.framework in Frameworks */,
25F2A1911322D59400A33DE4 /* CFNetwork.framework in Frameworks */,
25F2A1921322D59400A33DE4 /* MobileCoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
1D3623240D0F684500981E51 /* RKTwitterAppDelegate.h */,
1D3623250D0F684500981E51 /* RKTwitterAppDelegate.m */,
28D7ACF60DDB3853001CB0EB /* RKTwitterViewController.h */,
28D7ACF70DDB3853001CB0EB /* RKTwitterViewController.m */,
2538E812123419EC00ACB5D7 /* RKTStatus.h */,
2538E813123419EC00ACB5D7 /* RKTStatus.m */,
);
path = Classes;
sourceTree = "
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
1D6058910D05DD3D006BFB54 /* RKTwitterCoreData.app */,
25F2A1961322D59400A33DE4 /* Generate Seed Database.app */,
);
name = Products;
sourceTree = "
};
2538E800123417E500ACB5D7 /* Products */ = {
isa = PBXGroup;
children = (
250CA6C6147D90A50047D347 /* libRestKit.a */,
250CA6C8147D90A50047D347 /* RestKitTests.octest */,
250CA6CA147D90A50047D347 /* RestKit.framework */,
250CA6CC147D90A50047D347 /* RestKitFrameworkTests.octest */,
256780DE152D1A92000725F5 /* RestKitResources.bundle */,
);
name = Products;
sourceTree = "
};
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = CustomTemplate;
sourceTree = "
};
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
32CA4F630368D1EE00C91783 /* RKTwitter_Prefix.pch */,
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
25F2A2D813240CEC00A33DE4 /* RKSeedDatabase.sqlite */,
25F2A19A1322DCDC00A33DE4 /* users.json */,
25F2A1981322D93500A33DE4 /* restkit.json */,
3F3CE40A125B9B450083FDCB /* BG */,
3F3CE40B125B9B450083FDCB /* */,
3F3CE40C125B9B450083FDCB /* Default */,
3F3CE40D125B9B450083FDCB /* */,
3F3CE3FA125B9A6E0083FDCB /* listbg */,
3F3CE3FB125B9A6E0083FDCB /* */,
8D1107310486CEB800E47090 /* RKTwitter-Info.plist */,
3F94E0C6125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel */,
);
path = Resources;
sourceTree = "
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
CD39C14D14EEED8700E84874 /* QuartzCore.framework */,
250CA6CF147D90C50047D347 /* Security.framework */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
288765A40DF7441C002DB57D /* CoreGraphics.framework */,
2538E864123424F000ACB5D7 /* CoreData.framework */,
2538E8661234250100ACB5D7 /* SystemConfiguration.framework */,
8452D3F8128244D90069F4A9 /* CFNetwork.framework */,
8452D3FC128244E60069F4A9 /* MobileCoreServices.framework */,
3FB46640131D78A400E37C51 /* libxml2.dylib */,
);
name = Frameworks;
sourceTree = "
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1D6058900D05DD3D006BFB54 /* RKTwitterCoreData */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitterCoreData" */;
buildPhases = (
1D60588D0D05DD3D006BFB54 /* Resources */,
1D60588E0D05DD3D006BFB54 /* Sources */,
1D60588F0D05DD3D006BFB54 /* Frameworks */,
);
buildRules = (
);
dependencies = (
3F3CE2E4125B93EB0083FDCB /* PBXTargetDependency */,
);
name = RKTwitterCoreData;
productName = RKTwitter;
productReference = 1D6058910D05DD3D006BFB54 /* RKTwitterCoreData.app */;
productType = "com.apple.product-type.application";
};
25F2A1751322D59400A33DE4 /* Generate Seed Database */ = {
isa = PBXNativeTarget;
buildConfigurationList = 25F2A1931322D59400A33DE4 /* Build configuration list for PBXNativeTarget "Generate Seed Database" */;
buildPhases = (
25F2A1781322D59400A33DE4 /* Resources */,
25F2A17F1322D59400A33DE4 /* Sources */,
25F2A1861322D59400A33DE4 /* Frameworks */,
);
buildRules = (
);
dependencies = (
25F2A1761322D59400A33DE4 /* PBXTargetDependency */,
);
name = "Generate Seed Database";
productName = RKTwitter;
productReference = 25F2A1961322D59400A33DE4 /* Generate Seed Database.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitterCoreData" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 2538E800123417E500ACB5D7 /* Products */;
ProjectRef = 2538E7FF123417E500ACB5D7 /* RestKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
1D6058900D05DD3D006BFB54 /* RKTwitterCoreData */,
25F2A1751322D59400A33DE4 /* Generate Seed Database */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
250CA6C6147D90A50047D347 /* libRestKit.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRestKit.a;
remoteRef = 250CA6C5147D90A50047D347 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250CA6C8147D90A50047D347 /* RestKitTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitTests.octest;
remoteRef = 250CA6C7147D90A50047D347 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250CA6CA147D90A50047D347 /* RestKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = RestKit.framework;
remoteRef = 250CA6C9147D90A50047D347 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
250CA6CC147D90A50047D347 /* RestKitFrameworkTests.octest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitFrameworkTests.octest;
remoteRef = 250CA6CB147D90A50047D347 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
256780DE152D1A92000725F5 /* RestKitResources.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = RestKitResources.bundle;
remoteRef = 256780DD152D1A92000725F5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
1D60588D0D05DD3D006BFB54 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3F3CE3FC125B9A6E0083FDCB /* listbg in Resources */,
3F3CE3FD125B9A6E0083FDCB /* in Resources */,
3F3CE40E125B9B450083FDCB /* BG in Resources */,
3F3CE40F125B9B450083FDCB /* in Resources */,
3F3CE410125B9B450083FDCB /* Default in Resources */,
3F3CE411125B9B450083FDCB /* in Resources */,
25F2A2D913240CEC00A33DE4 /* RKSeedDatabase.sqlite in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
25F2A1781322D59400A33DE4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
25F2A19C1322DD1800A33DE4 /* users.json in Resources */,
25F2A1791322D59400A33DE4 /* listbg in Resources */,
25F2A17A1322D59400A33DE4 /* in Resources */,
25F2A17B1322D59400A33DE4 /* BG in Resources */,
25F2A17C1322D59400A33DE4 /* in Resources */,
25F2A17D1322D59400A33DE4 /* Default in Resources */,
25F2A17E1322D59400A33DE4 /* in Resources */,
25F2A1991322D93500A33DE4 /* restkit.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1D60588E0D05DD3D006BFB54 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
1D3623260D0F684500981E51 /* RKTwitterAppDelegate.m in Sources */,
28D7ACF80DDB3853001CB0EB /* RKTwitterViewController.m in Sources */,
2538E814123419EC00ACB5D7 /* RKTStatus.m in Sources */,
3F94E0C7125BA8C0001E8585 /* RKTwitterCoreData.xcdatamodel in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
25F2A17F1322D59400A33DE4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
25F2A1801322D59400A33DE4 /* main.m in Sources */,
25F2A1811322D59400A33DE4 /* RKTwitterAppDelegate.m in Sources */,
25F2A1821322D59400A33DE4 /* RKTwitterViewController.m in Sources */,
25F2A1841322D59400A33DE4 /* RKTStatus.m in Sources */,
25F2A1851322D59400A33DE4 /* RKTwitterCoreData.xcdatamodel in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
25F2A1761322D59400A33DE4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKit;
targetProxy = 25F2A1771322D59400A33DE4 /* PBXContainerItemProxy */;
};
3F3CE2E4125B93EB0083FDCB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = RestKit;
targetProxy = 3F3CE2E3125B93EB0083FDCB /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
1D6058940D05DD3E006BFB54 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Debug;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RKTwitterCoreData;
};
name = Debug;
};
1D6058950D05DD3E006BFB54 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Release;
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
HEADER_SEARCH_PATHS = "${TARGET_BUILD_DIR}/../../Headers";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RKTwitterCoreData;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
25F2A1941322D59400A33DE4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Debug;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = RESTKIT_GENERATE_SEED_DB;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "Generate Seed Database";
};
name = Debug;
};
25F2A1951322D59400A33DE4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_STYLE = Release;
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = RKTwitter_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = RESTKIT_GENERATE_SEED_DB;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/../../Headers\"";
INFOPLIST_FILE = "Resources/RKTwitter-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "Generate Seed Database";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
BUILD_STYLE = Debug;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
BUILD_STYLE = Release;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "RKTwitterCoreData" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1D6058940D05DD3E006BFB54 /* Debug */,
1D6058950D05DD3E006BFB54 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
25F2A1931322D59400A33DE4 /* Build configuration list for PBXNativeTarget "Generate Seed Database" */ = {
isa = XCConfigurationList;
buildConfigurations = (
25F2A1941322D59400A33DE4 /* Debug */,
25F2A1951322D59400A33DE4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RKTwitterCoreData" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}
listbg@2x listbg@2x BG@2x BG@2x Default@2x Default@2x listbg@2x listbg@2x BG@2x BG@2x Default@2x Default@2x listbg@2x listbg@2x BG@2x BG@2x Default@2x Default@2x BG@2x Default@2x listbg@2x listbg@2x BG@2x Default@2x listbg@2x BG@2x Default@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitterCoreData.xcodeproj/._project.pbxproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitterCoreData.xcodeproj/project.xcworkspace/contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitterCoreData.xcodeproj/project.xcworkspace/._contents.xcworkspacedata
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/RKTwitterCoreData.xcodeproj/._project.xcworkspace
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._RKTwitterCoreData.xcodeproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/users.json[{
"user": {
"id": 31337,
"name": "Blake Watters",
"screen_name": "Blake Watters"
}
}]
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/RKTwitterCoreData/._users.json
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Examples/._RKTwitterCoreData
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Examples
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Gemfilesource "http://rubygems.org"
gem "rake", "~> 0.9.0"
gem "bundler", "~> 1.1.0"
gem "sinatra", :git => "git://github.com/sinatra/sinatra.git"
gem "thin", "~> 1.3.1"
gem 'xcoder', :git => "git://github.com/rayh/xcoder.git"
gem 'restkit', :git => 'git://github.com/RestKit/RestKit-Gem.git'
gem 'ruby-debug19'
gem 'faker', '1.0.1'
## OAuth stuff
# gem 'oauth'
gem 'rack-oauth2-server', :git => 'https://github.com/assaf/rack-oauth2-server.git'
gem 'rspec'
gem 'rack-test'
gem 'mongo'
gem 'simple_oauth', :git => 'https://github.com/laserlemon/simple_oauth.git'
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Gemfile
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Gemfile.lockGIT
remote: git://github.com/RestKit/RestKit-Gem.git
revision: 96058139a46c46aa344c1481e8c75b390c82d5e9
specs:
restkit (0.0.0)
GIT
remote: git://github.com/rayh/xcoder.git
revision: e400000f29d959932cae2558fc77fd9ace13ead0
specs:
xcoder (0.1.12)
builder
json
nokogiri
plist
rest-client
GIT
remote: git://github.com/sinatra/sinatra.git
revision: cab56ed7d64b9ffb6d4df48cb8d7d3153890f3ee
specs:
sinatra (1.4.0)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
GIT
remote: https://github.com/assaf/rack-oauth2-server.git
revision: 8c03cdb4cbaf49fdd3d227d8a84a2486261818f8
specs:
rack-oauth2-server (2.6.0)
bson_ext
json
jwt (~> 0.1.4)
mongo (~> 1)
rack (~> 1.1)
sinatra (~> 1.1)
GIT
remote: https://github.com/laserlemon/simple_oauth.git
revision: e1146b615df769bfe7824a337122069cc2d5476d
specs:
simple_oauth (0.1.8)
GEM
remote: http://rubygems.org/
specs:
archive-tar-minitar (0.5.2)
bson (1.6.2)
bson_ext (1.6.2)
bson (~> 1.6.2)
builder (3.0.0)
columnize (0.3.6)
daemons (1.1.8)
diff-lcs (1.1.3)
eventmachine (0.12.10)
faker (1.0.1)
i18n (~> 0.4)
i18n (0.6.0)
json (1.7.3)
jwt (0.1.4)
json (>= 1.2.4)
linecache19 (0.5.12)
ruby_core_source (>= 0.1.4)
mime-types (1.18)
mongo (1.6.2)
bson (~> 1.6.2)
nokogiri (1.5.2)
plist (3.1.0)
rack (1.4.1)
rack-protection (1.2.0)
rack
rack-test (0.6.1)
rack (>= 1.0)
rake (0.9.2.2)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.10.0)
rspec-core (~> 2.10.0)
rspec-expectations (~> 2.10.0)
rspec-mocks (~> 2.10.0)
rspec-core (2.10.0)
rspec-expectations (2.10.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.10.1)
ruby-debug-base19 (0.11.25)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby_core_source (>= 0.1.4)
ruby-debug19 (0.11.6)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby-debug-base19 (>= 0.11.19)
ruby_core_source (0.1.5)
archive-tar-minitar (>= 0.5.2)
thin (1.3.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
tilt (1.3.3)
PLATFORMS
ruby
DEPENDENCIES
bundler (~> 1.1.0)
faker (= 1.0.1)
mongo
rack-oauth2-server!
rack-test
rake (~> 0.9.0)
restkit!
rspec
ruby-debug19
simple_oauth!
sinatra!
thin (~> 1.3.1)
xcoder!
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Gemfile.lock
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2009 Two Toasters
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._LICENSE
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Rakefilerequire 'rubygems'
require 'bundler/setup'
require 'xcoder'
require 'restkit/rake'
require 'ruby-debug'
RestKit::Rake::ServerTask.new do |t|
t.port = 4567
t.pid_file = 'Tests/Server/server.pid'
t.rackup_file = 'Tests/Server/server.ru'
t.log_file = 'Tests/Server/server.log'
t.adapter(:thin) do |thin|
thin.config_file = 'Tests/Server/thin.yml'
end
end
namespace :test do
task :kill_simulator do
system(%q{killall -m -KILL "iPhone Simulator"})
end
namespace :logic do
desc "Run the logic tests for iOS"
task :ios => :kill_simulator do
config = Xcode.project(:RestKit).target(:RestKitTests).config(:Debug)
builder = config.builder
build_dir = File.dirname(config.target.project.path) + '/Build'
builder.symroot = build_dir + '/Products'
builder.objroot = build_dir
builder.test(:sdk => 'iphonesimulator')
end
desc "Run the logic tests for OS X"
task :osx do
config = Xcode.project(:RestKit).target(:RestKitFrameworkTests).config(:Debug)
builder = config.builder
build_dir = File.dirname(config.target.project.path) + '/Build'
builder.symroot = build_dir + '/Products'
builder.objroot = build_dir
builder.test(:sdk => 'macosx')
end
end
desc "Run the unit tests for iOS and OS X"
task :logic => ['logic:ios', 'logic:osx']
namespace :application do
desc "Run the application tests for iOS"
task :ios => :kill_simulator do
config = Xcode.project(:RKApplicationTests).target('Application Tests').config(:Debug)
builder = config.builder
build_dir = File.dirname(config.target.project.path) + '/Build'
builder.symroot = build_dir + '/Products'
builder.objroot = build_dir
builder.test(:sdk => 'iphonesimulator')
end
end
desc "Run the application tests for iOS"
task :application => 'application:ios'
desc "Run all tests for iOS and OS X"
task :all do
Rake.application.invoke_task("test:logic")
unit_status = $?.exitstatus
Rake.application.invoke_task("test:application")
integration_status = $?.exitstatus
puts "\033[0;31m!! Unit Tests failed with exit status of #{unit_status}" if unit_status != 0
puts "\033[0;31m!! Integration Tests failed with exit status of #{integration_status}" if integration_status != 0
puts "\033[0;32m** All Tests executed successfully" if unit_status == 0 && integration_status == 0
end
task :check_mongodb do
port_check = RestKit::Server::PortCheck.new('127.0.0.1', 27017)
port_check.run
if port_check.closed?
puts "\033[0;33m!! Warning: MongoDB was not found running on port 27017"
puts "MongoDB is required for the execution of the OAuth tests. Tests in RKOAuthClientTest will NOT be executed"
`which mongo`
if $?.exitstatus == 0
puts "Execute MongoDB via `mongod run --config /usr/local/etc/mongod.conf`"
else
puts "Install mongodb with Homebrew via `brew install mongodb`"
end
puts "\033[0m"
sleep(5)
end
end
end
desc 'Run all the RestKit tests'
task :test => "test:all"
task :default => ["test:check_mongodb", "server:autostart", "test:all", "server:autostop"]
def restkit_version
@restkit_version ||= ENV['VERSION'] || File.read("VERSION").chomp
end
def apple_doc_command
"Vendor/appledoc/appledoc -t Vendor/appledoc/Templates -o Docs/API -p RestKit -v #{restkit_version} -c \"RestKit\" " +
"--company-id org.restkit --warn-undocumented-object --warn-undocumented-member --warn-empty-description --warn-unknown-directive " +
"--warn-invalid-crossref --warn-missing-arg --no-repeat-first-par "
end
def run(command, min_exit_status = 0)
puts "Executing: `#{command}`"
system(command)
if $?.exitstatus > min_exit_status
puts "[!] Failed with exit code #{$?.exitstatus} while running: `#{command}`"
exit($?.exitstatus)
end
return $?.exitstatus
end
desc "Build RestKit for iOS and Mac OS X"
task :build do
run("xcodebuild -workspace RestKit.xcodeproj/project.xcworkspace -scheme RestKit -sdk iphonesimulator5.0 clean build")
run("xcodebuild -workspace RestKit.xcodeproj/project.xcworkspace -scheme RestKit -sdk iphoneos clean build")
run("xcodebuild -workspace RestKit.xcodeproj/project.xcworkspace -scheme RestKit -sdk macosx10.6 clean build")
run("xcodebuild -workspace Examples/RKCatalog/RKCatalog.xcodeproj/project.xcworkspace -scheme RKCatalog -sdk iphoneos clean build")
end
desc "Generate documentation via appledoc"
task :docs => 'docs:generate'
namespace :docs do
task :generate do
command = apple_doc_command << " --no-create-docset --keep-intermediate-files --create-html Code/"
run(command, 1)
puts "Generated HTML documentationa at Docs/API/html"
end
desc "Check that documentation can be built from the source code via appledoc successfully."
task :check do
command = apple_doc_command << " --no-create-html --verbose 5 Code/"
exitstatus = run(command, 1)
if exitstatus == 0
puts "appledoc generation completed successfully!"
elsif exitstatus == 1
puts "appledoc generation produced warnings"
elsif exitstatus == 2
puts "! appledoc generation encountered an error"
exit(exitstatus)
else
puts "!! appledoc generation failed with a fatal error"
end
exit(exitstatus)
end
desc "Generate & install a docset into Xcode from the current sources"
task :install do
command = apple_doc_command << " --install-docset Code/"
run(command, 1)
end
desc "Build and publish the documentation set to the remote server (using rsync over SSH)"
task :publish, :version, :destination do |t, args|
args.with_defaults(:version => File.read("VERSION").chomp, :destination => "restkit.org:/var/www/public/restkit.org/public/api/")
version = args[:version]
destination = args[:destination]
puts "Generating RestKit docset for version #{version}..."
command = apple_doc_command <<
" --keep-intermediate-files" <<
" --docset-feed-name \"RestKit #{version} Documentation\"" <<
" --docset-feed-url http://restkit.org/api/%DOCSETATOMFILENAME" <<
" --docset-package-url http://restkit.org/api/%DOCSETPACKAGEFILENAME --publish-docset --verbose 3 Code/"
run(command, 1)
puts "Uploading docset to #{destination}..."
versioned_destination = File.join(destination, version)
command = "rsync -rvpPe ssh --delete Docs/API/html/ #{versioned_destination}"
run(command)
if $?.exitstatus == 0
command = "rsync -rvpPe ssh Docs/API/publish/ #{destination}"
run(command)
end
end
end
namespace :build do
desc "Build all Example projects to ensure they are building properly"
task :examples do
ios_sdks = %w{iphoneos iphonesimulator5.0}
osx_sdks = %w{macosx}
osx_projects = %w{RKMacOSX}
examples_path = File.join(File.expand_path(File.dirname(__FILE__)), 'Examples')
example_projects = `find #{examples_path} -name '*.xcodeproj'`.split("\n")
puts "Building #{example_projects.size} Example projects..."
example_projects.each do |example_project|
project_name = File.basename(example_project).gsub('.xcodeproj', '')
sdks = osx_projects.include?(project_name) ? osx_sdks : ios_sdks
sdks.each do |sdk|
puts "Building '#{example_project}' with SDK #{sdk}..."
scheme = project_name
run("xcodebuild -workspace #{example_project}/project.xcworkspace -scheme #{scheme} -sdk #{sdk} clean build")
#run("xcodebuild -project #{example_project} -alltargets -sdk #{sdk} clean build")
end
end
end
end
desc "Validate a branch is ready for merging by checking for common issues"
task :validate => [:build, 'docs:check', 'uispec:all'] do
puts "Project state validated successfully. Proceed with merge."
end
namespace :payload do
task :generate do
require 'json'
require 'faker'
ids = (1..25).to_a
child_ids = (50..100).to_a
child_counts = (10..25).to_a
hash = ids.inject({'parents' => []}) do |hash, parent_id|
child_count = child_counts.sample
children = (0..child_count).collect do
{'name' => Faker::Name.name, 'childID' => child_ids.sample}
end
parent = {'parentID' => parent_id, 'name' => Faker::Name.name, 'children' => children}
hash['parents'] << parent
hash
end
File.open('payload.json', 'w+') { |f| f << hash.to_json }
puts "Generated payload at: payload.json"
end
end
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Rakefile
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/README.mdIntroduction
=========================
RestKit is a Cocoa framework for interacting with RESTful web services in Objective C on iOS and Mac OS X. It provides a set of primitives for interacting with web services wrapping GET, POST, PUT and DELETE HTTP verbs behind a clean, simple interface. RestKit also provides a system for modeling remote resources by mapping them from JSON (or XML) payloads back into local domain objects. Object mapping functions with normal NSObject derived classes with properties. There is also an object mapping implementation included that provides a Core Data backed store for persisting objects loaded from the web.
RestKit was first publicly introduced in April of 2010.
To get started with installation, skip down the document below the Design & Dependencies section.
Design
-------------------------
RestKit is composed of three main components: **Network**, **Object Mapping**, and **Core Data**. Each layer provides a higher level of abstraction around the problem of accessing web services and representing the data returned as an object. The primary goal of RestKit is to allow the application programmer to think more in terms of their application's data model and less about the details of fetching, parsing, and representing resources. Functionally, each piece provides...
1. **Network** - The network layer provides a request/response abstraction on top of NSURLConnection. The main interface for the end developer is the *RKClient*, which provides an interface for sending GET, POST, PUT, and DELETE requests asynchronously. This wraps the construction and dispatch of *RKRequest* and *RKResponse* objects, that provide a nice interface for working with HTTP requests. Sending parameters with your request is as easy as providing an NSDictionary of key/value pairs. File uploading support from NSData and files is supported through the use of an *RKParams* object, which serializes into a multipart form representation suitable for submission to a remote web server for processing. SSL & HTTP AUTH is fully supported for requests. *RKResponse* objects provide access to the string of JSON parsed versions of the response body in one line of code. There are also a number of helpful method for inspecting the request and response such as isXHTML, isJSON, isRedirect, isOK, etc.
1. **Object Mapping** - The object mapping layer provides a simple API for turning remote JSON/XML responses into local domain objects declaratively. Rather than working directly with *RKClient*, the developer works with *RKObjectManager*. *RKObjectManager* provides support for loading a remote resource path (see below for discussion) and calling back a delegate with object representations of the data loaded. Remote payloads are parsed to an NSDictionary representation and are then mapped to local objects using Key-Value Coding. Any KVC compliant class can be targeted for object mapping. RestKit also provides support for serializing local objects back into a wire format for submission back to your remote backend system. Local domain objects can be serialized to JSON or URL Form Encoded string representations for transport. To simplify the generation of URL's that identify remote resources, RestKit ships with an object routing implementation that can
generate an appropriate URL based on the object and HTTP verb being utilized. Object mapping is a deep topic and is explored thoroughly in the [Object Mapping Design Document].
1. **Core Data** - The Core Data layer provides additional support on top of the object mapper for mapping from remote resources to persist local objects. This is useful for providing offline support, holding on to transient data, and speeding up user interfaces by avoiding expensive trips to the web server. The Core Data support requires that you initialize an instance of *RKManagedObjectStore* and assign it to the *RKObjectManager*. RestKit includes a library of extensions to NSManagedObject that provide an Active Record pattern on top of the Core Data primitives. See the Examples/ subdirectory for examples of how to get this running. The Core Data support also provides *RKManagedObjectSeeder*, a tool for creating a local "seed database" to bootstrap an object model from local JSON files. This allows you to ship an app to the store that already has data pre-loaded and then synchronize with the cloud to keep your clients up to date.
### Base URL and Resource Paths
RestKit utilizes the concepts of the Base URL and resource paths throughout the library. Basically the base URL is a prefix URL that all requests will be sent to. This prevents you from spreading server name details across the code base and repeatedly constructing URL fragments. The *RKClient* and *RKObjectManager* are both initialized with a base URL initially. All other operations dispatched through these objects work of a resource path, which is basically just a URL path fragment that is appended to the base URL before constructing the request. This allows you to switch between development, staging, and production servers very easily and reduces redundancy.
Note that you can send *RKRequest* objects to arbitrary URL's by constructing them yourself.
Parsers
-------------------------
RestKit provides a pluggable parser interface configurable by MIME Type. The standard RestKit distribution includes two parsers:
1. **RKJSONParserJSONKit** - A very fast JSON parser leveraging [JSONKit](http://github.com/johnezang/JSONKit)
1. **RKXMLParserLibXML** - A custom LibXML2 based parser. Only provides parsing, not serialization.
The JSONKit headers can be imported for direct use:
```objc
#import
```
Additional parsers can be added to your RestKit application by linking the parsers into your application and configuring it to handle the appropriate
MIME Type:
```objc
[[RKParserRegistry sharedRegistry] setParserClass:[SomeOtherParser class] forMIMEType:@"application/json"]];
```
The RestKit project also provides optional additional parsers that can be installed separately from the main library:
1. [**RKJSONParserSBJSON**](https://github.com/RestKit/RKJSONParserSBJSON) - A JSON parser built on top of SBJSON
1. [**RKJSONParserYAJL**](https://github.com/RestKit/RKJSONParserYAJL) - A JSON parser built on top of YAJL)
1. [**RKJSONParserNXJSON**](https://github.com/RestKit/RKJSONParserNXJSON) - A JSON parser built on top of the Nextive JSON parser
Documentation & Example Code
-------------------------
Documentation and example code is being added as quickly as possible. Please check the Docs/ and Examples/ subdirectories to see what's available. The [RestKit Google Group](http://groups.google.com/group/restkit) is an invaluable resource for getting help working with the library.
RestKit has API documentation available on the web. You can access the documentation in several ways:
1. Online in your web browser. Visit http://restkit.org/api/
1. Directly within Xcode. Visit your Xcode Preferences and view the Documentation tab. Click + and add the RestKit feed: feed://restkit.org/api/org.restkit.RestKit.atom
1. Generate the documentation directly from the project source code. Run `rake docs` to generate and `rake docs:install` to install into Xcode
Installation
=========================
Quick Start (aka TL;DR)
-----------
RestKit assumes that you are using a modern Xcode project building to the DerivedData directory. Confirm your settings
via the "File" menu > "Project Settings...". On the "Build" tab within the sheet that opens, click the "Advanced..."
button and confirm that your "Build Location" is the "Derived Data Location".
1. Add Git submodule to your project: `git submodule add git://github.com/RestKit/RestKit.git RestKit`
1. Add cross-project reference by dragging **RestKit.xcodeproj** to your project
1. Open build settings editor for your project
1. Add the following **Header Search Paths** (including the quotes): `"$(BUILT_PRODUCTS_DIR)/../../Headers"`
1. Add **Other Linker Flags** for `-ObjC -all_load`
1. Open target settings editor for the target you want to link RestKit into
1. Add direct dependency on the **RestKit** aggregate target
1. Link against required frameworks:
1. **CFNetwork.framework** on iOS
1. **CoreData.framework**
1. **Security.framework**
1. **MobileCoreServices.framework** on iOS or **CoreServices.framework** on OS X
1. **SystemConfiguration.framework**
1. **libxml2.dylib**
1. **QuartzCore.framework** on iOS
1. Link against RestKit:
1. **libRestKit.a** on iOS
1. **RestKit.framework** on OS X
1. Import the RestKit headers via `#import
1. Build the project to verify installation is successful.
Visual Install Guide
-------------------------
An step-by-step visual install guide for Xcode 4.x is available on the RestKit Wiki: https://github.com/RestKit/RestKit/wiki/Installing-RestKit-in-Xcode-4.x
Community Resources
-------------------------
A Google Group (high traffic) for development discussions and user support is available at: [http://groups.google.com/group/restkit](http://groups.google.com/group/restkit)
The preferred venue for discussing bugs and feature requests is on Github Issues. The mailing list support traffic can be overwhelming
for our small development team. Please file all bug reports and feature requests at:
For users interested in low traffic updates about the library, an announcements list is also available:
[http://groups.google.com/group/restkit-announce](http://groups.google.com/group/restkit-announce)
Follow RestKit on Twitter:[http://twitter.com/restkit](http://twitter.com/restkit)
Contributing
-------------------------
Forks, patches and other feedback are always welcome.
Credits
-------------------------
RestKit is brought to you by [Blake Watters](http://twitter.com/blakewatters) and the RestKit team.
Support is provided by the following organizations:
* [GateGuru](http://www.gateguruapp.com/)
* [Two Toasters](http://www.twotoasters.com/)
[Object Mapping Design Document]: https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._README.md
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/en.lproj/InfoPlist.strings/* Localized versions of Info.plist keys */
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/en.lproj/._InfoPlist.strings
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/._en.lproj
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/RestKitFramework-Info.plist
CFBundleDevelopmentRegion
English
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
org.restkit.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
FMWK
CFBundleShortVersionString
1.0
CFBundleSignature
RSTK
CFBundleVersion
1
NSHumanReadableCopyright
Copyright © 2011 RestKit. All rights reserved.
NSPrincipalClass
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/._RestKitFramework-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/RestKitFrameworkTests-Info.plist
CFBundleDevelopmentRegion
en
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
org.restkit.tests
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
BNDL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/._RestKitFrameworkTests-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/RestKitResources-Info.plist
CFBundleDevelopmentRegion
English
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIconFile
CFBundleIdentifier
org.restkit.${PRODUCT_NAME:rfc1034identifier}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
BNDL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
CFPlugInDynamicRegisterFunction
CFPlugInDynamicRegistration
NO
CFPlugInFactories
00000000-0000-0000-0000-000000000000
MyFactoryFunction
CFPlugInTypes
00000000-0000-0000-0000-000000000000
00000000-0000-0000-0000-000000000000
CFPlugInUnloadFunction
NSHumanReadableCopyright
Copyright © 2012 RestKit. All rights reserved.
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/._RestKitResources-Info.plist
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/RestKitTests-Info.plist
CFBundleDevelopmentRegion
en
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
org.restkit.tests
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
BNDL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/PLISTs/._RestKitTests-Info.plist
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/._PLISTs
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/.xccurrentversion
_XCCurrentVersionName
RestKitCoreData.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/._.xccurrentversion
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/RestKitCoreData.xcdatamodel/elements
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/RestKitCoreData.xcdatamodel/._elements
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/RestKitCoreData.xcdatamodel/layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/RestKitCoreData.xcdatamodel/._layout
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitCoreData.xcdatamodeld/._RestKitCoreData.xcdatamodel
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/._RestKitCoreData.xcdatamodeld
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RestKitResources-Prefix.pch//
// Prefix header for all source files of the 'RestKitResources' target in the 'RestKitResources' project
//
#ifdef __OBJC__
#import
#endif
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/._RestKitResources-Prefix.pch
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/blackArrow
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._blackArrow
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/blackArrow@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._blackArrow@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/blueArrow
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._blueArrow
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/blueArrow@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._blueArrow@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/grayArrow
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._grayArrow
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/grayArrow@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._grayArrow@2x
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/whiteArrow
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._whiteArrow
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/whiteArrow@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/RKRefreshTriggerViewAssets/._whiteArrow@2x
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/Resources/._RKRefreshTriggerViewAssets
__MACOSX/IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/._Resources
IT4781-U02A1-AlexBenavides/StoreLocator/Libraries/RestKit/RestKit.xcodeproj/project.pbxproj// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
2501405315366000004E0466 /* RKObjectiveCppTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2501405215366000004E0466 /* RKObjectiveCppTest.mm */; };
2501405415366000004E0466 /* RKObjectiveCppTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2501405215366000004E0466 /* RKObjectiveCppTest.mm */; };
25055B8414EEF32A00B9C4DD /* RKMappingTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8014EEF32A00B9C4DD /* RKMappingTest.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B8514EEF32A00B9C4DD /* RKMappingTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8014EEF32A00B9C4DD /* RKMappingTest.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B8614EEF32A00B9C4DD /* RKMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8114EEF32A00B9C4DD /* RKMappingTest.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B8714EEF32A00B9C4DD /* RKMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8114EEF32A00B9C4DD /* RKMappingTest.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B8814EEF32A00B9C4DD /* RKTestFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8214EEF32A00B9C4DD /* RKTestFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B8914EEF32A00B9C4DD /* RKTestFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8214EEF32A00B9C4DD /* RKTestFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B8A14EEF32A00B9C4DD /* RKTestFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8314EEF32A00B9C4DD /* RKTestFactory.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B8B14EEF32A00B9C4DD /* RKTestFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8314EEF32A00B9C4DD /* RKTestFactory.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B8F14EEF40000B9C4DD /* RKMappingTestExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8D14EEF40000B9C4DD /* RKMappingTestExpectation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B9014EEF40000B9C4DD /* RKMappingTestExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25055B8D14EEF40000B9C4DD /* RKMappingTestExpectation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25055B9114EEF40000B9C4DD /* RKMappingTestExpectation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8E14EEF40000B9C4DD /* RKMappingTestExpectation.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B9214EEF40000B9C4DD /* RKMappingTestExpectation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25055B8E14EEF40000B9C4DD /* RKMappingTestExpectation.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25055B9314EEFEC800B9C4DD /* libRestKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D1614564E810060A5C5 /* libRestKit.a */; };
25079C6F151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25079C6D151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25079C70151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25079C6D151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25079C71151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25079C6E151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m */; };
25079C72151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25079C6E151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m */; };
25079C76151B952200266AE7 /* NSEntityDescription+RKAdditionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25079C75151B952200266AE7 /* NSEntityDescription+RKAdditionsTest.m */; };
25079C77151B952200266AE7 /* NSEntityDescription+RKAdditionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25079C75151B952200266AE7 /* NSEntityDescription+RKAdditionsTest.m */; };
250B849E152B6F63002581F9 /* RKObjectMappingProvider+CoreData.m in Sources */ = {isa = PBXBuildFile; fileRef = 73DA8E1B14D1BA960054DD73 /* RKObjectMappingProvider+CoreData.m */; };
250CA67D147D8E8B0047D347 /* OCHamcrest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA67B147D8E800047D347 /* OCHamcrest.framework */; };
250CA67E147D8E8F0047D347 /* OCHamcrestIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 250CA67C147D8E800047D347 /* OCHamcrestIOS.framework */; };
250CA680147D8F050047D347 /* OCHamcrest.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 250CA67B147D8E800047D347 /* OCHamcrest.framework */; };
250DF22A14C5190E0001DEFA /* RKOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 250DF22814C5190E0001DEFA /* RKOrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
250DF22B14C5190E0001DEFA /* RKOrderedDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 250DF22814C5190E0001DEFA /* RKOrderedDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
250DF22C14C5190E0001DEFA /* RKOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 250DF22914C5190E0001DEFA /* RKOrderedDictionary.m */; };
250DF22D14C5190E0001DEFA /* RKOrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 250DF22914C5190E0001DEFA /* RKOrderedDictionary.m */; };
250DF25F14C680F90001DEFA /* RKObjectMappingProvider+Contexts.h in Headers */ = {isa = PBXBuildFile; fileRef = 250DF25E14C680F90001DEFA /* RKObjectMappingProvider+Contexts.h */; settings = {ATTRIBUTES = (Public, ); }; };
250DF26014C680F90001DEFA /* RKObjectMappingProvider+Contexts.h in Headers */ = {isa = PBXBuildFile; fileRef = 250DF25E14C680F90001DEFA /* RKObjectMappingProvider+Contexts.h */; settings = {ATTRIBUTES = (Public, ); }; };
25119FB6154A34B400C6BC58 /* parents_and_children.json in Resources */ = {isa = PBXBuildFile; fileRef = 25119FB5154A34B400C6BC58 /* parents_and_children.json */; };
25119FB7154A34B400C6BC58 /* parents_and_children.json in Resources */ = {isa = PBXBuildFile; fileRef = 25119FB5154A34B400C6BC58 /* parents_and_children.json */; };
2513504E14B8FE6B00A7E893 /* RKConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2513504D14B8FE6B00A7E893 /* RKConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
2513504F14B8FE6B00A7E893 /* RKConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2513504D14B8FE6B00A7E893 /* RKConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160D1A14564E810060A5C5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D1914564E810060A5C5 /* Foundation.framework */; };
25160D2814564E820060A5C5 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D2714564E820060A5C5 /* SenTestingKit.framework */; };
25160D2A14564E820060A5C5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D2914564E820060A5C5 /* UIKit.framework */; };
25160D2B14564E820060A5C5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D1914564E810060A5C5 /* Foundation.framework */; };
25160DD5145650490060A5C5 /* CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D46145650490060A5C5 /* CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DD6145650490060A5C5 /* NSManagedObject+ActiveRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D47145650490060A5C5 /* NSManagedObject+ActiveRecord.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DD7145650490060A5C5 /* NSManagedObject+ActiveRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D48145650490060A5C5 /* NSManagedObject+ActiveRecord.m */; };
25160DD9145650490060A5C5 /* RKManagedObjectLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4A145650490060A5C5 /* RKManagedObjectLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DDA145650490060A5C5 /* RKManagedObjectLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4B145650490060A5C5 /* RKManagedObjectLoader.m */; };
25160DDB145650490060A5C5 /* RKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4C145650490060A5C5 /* RKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DDC145650490060A5C5 /* RKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4D145650490060A5C5 /* RKManagedObjectMapping.m */; };
25160DDD145650490060A5C5 /* RKManagedObjectMappingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4E145650490060A5C5 /* RKManagedObjectMappingOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DDE145650490060A5C5 /* RKManagedObjectMappingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4F145650490060A5C5 /* RKManagedObjectMappingOperation.m */; };
25160DDF145650490060A5C5 /* RKManagedObjectSeeder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D50145650490060A5C5 /* RKManagedObjectSeeder.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE0145650490060A5C5 /* RKManagedObjectSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D51145650490060A5C5 /* RKManagedObjectSeeder.m */; };
25160DE1145650490060A5C5 /* RKManagedObjectStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D52145650490060A5C5 /* RKManagedObjectStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE2145650490060A5C5 /* RKManagedObjectStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D53145650490060A5C5 /* RKManagedObjectStore.m */; };
25160DE3145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D54145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE4145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D55145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.m */; };
25160DE5145650490060A5C5 /* RKObjectPropertyInspector+CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D56145650490060A5C5 /* RKObjectPropertyInspector+CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE6145650490060A5C5 /* RKObjectPropertyInspector+CoreData.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D57145650490060A5C5 /* RKObjectPropertyInspector+CoreData.m */; };
25160DE7145650490060A5C5 /* Network.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D59145650490060A5C5 /* Network.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE8145650490060A5C5 /* NSData+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D5A145650490060A5C5 /* NSData+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DE9145650490060A5C5 /* NSData+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D5B145650490060A5C5 /* NSData+RKAdditions.m */; };
25160DEA145650490060A5C5 /* NSDictionary+RKRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D5C145650490060A5C5 /* NSDictionary+RKRequestSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DEB145650490060A5C5 /* NSDictionary+RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D5D145650490060A5C5 /* NSDictionary+RKRequestSerialization.m */; };
25160DEE145650490060A5C5 /* RKClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D60145650490060A5C5 /* RKClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DEF145650490060A5C5 /* RKClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D61145650490060A5C5 /* RKClient.m */; };
25160DF0145650490060A5C5 /* RKNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D62145650490060A5C5 /* RKNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DF1145650490060A5C5 /* RKNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D63145650490060A5C5 /* RKNotifications.m */; };
25160DF2145650490060A5C5 /* RKOAuthClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D64145650490060A5C5 /* RKOAuthClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DF3145650490060A5C5 /* RKOAuthClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D65145650490060A5C5 /* RKOAuthClient.m */; };
25160DF4145650490060A5C5 /* RKParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D66145650490060A5C5 /* RKParams.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DF5145650490060A5C5 /* RKParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D67145650490060A5C5 /* RKParams.m */; };
25160DF6145650490060A5C5 /* RKParamsAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D68145650490060A5C5 /* RKParamsAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DF7145650490060A5C5 /* RKParamsAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D69145650490060A5C5 /* RKParamsAttachment.m */; };
25160DF8145650490060A5C5 /* RKReachabilityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6A145650490060A5C5 /* RKReachabilityObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DF9145650490060A5C5 /* RKReachabilityObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D6B145650490060A5C5 /* RKReachabilityObserver.m */; };
25160DFA145650490060A5C5 /* RKRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6C145650490060A5C5 /* RKRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DFB145650490060A5C5 /* RKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D6D145650490060A5C5 /* RKRequest.m */; };
25160DFC145650490060A5C5 /* RKRequest_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6E145650490060A5C5 /* RKRequest_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DFD145650490060A5C5 /* RKRequestCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6F145650490060A5C5 /* RKRequestCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160DFE145650490060A5C5 /* RKRequestCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D70145650490060A5C5 /* RKRequestCache.m */; };
25160DFF145650490060A5C5 /* RKRequestQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D71145650490060A5C5 /* RKRequestQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E00145650490060A5C5 /* RKRequestQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D72145650490060A5C5 /* RKRequestQueue.m */; };
25160E01145650490060A5C5 /* RKRequestSerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D73145650490060A5C5 /* RKRequestSerializable.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E02145650490060A5C5 /* RKRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D74145650490060A5C5 /* RKRequestSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E03145650490060A5C5 /* RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D75145650490060A5C5 /* RKRequestSerialization.m */; };
25160E04145650490060A5C5 /* RKResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D76145650490060A5C5 /* RKResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E05145650490060A5C5 /* RKResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D77145650490060A5C5 /* RKResponse.m */; };
25160E06145650490060A5C5 /* RKURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D78145650490060A5C5 /* RKURL.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E07145650490060A5C5 /* RKURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D79145650490060A5C5 /* RKURL.m */; };
25160E08145650490060A5C5 /* ObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7B145650490060A5C5 /* ObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E09145650490060A5C5 /* RKDynamicObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7C145650490060A5C5 /* RKDynamicObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E0A145650490060A5C5 /* RKDynamicObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D7D145650490060A5C5 /* RKDynamicObjectMapping.m */; };
25160E0B145650490060A5C5 /* RKErrorMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7E145650490060A5C5 /* RKErrorMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E0C145650490060A5C5 /* RKErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D7F145650490060A5C5 /* RKErrorMessage.m */; };
25160E0D145650490060A5C5 /* RKMappingOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D80145650490060A5C5 /* RKMappingOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E0E145650490060A5C5 /* RKMappingOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D81145650490060A5C5 /* RKMappingOperationQueue.m */; };
25160E0F145650490060A5C5 /* RKObjectAttributeMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D82145650490060A5C5 /* RKObjectAttributeMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E10145650490060A5C5 /* RKObjectAttributeMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D83145650490060A5C5 /* RKObjectAttributeMapping.m */; };
25160E11145650490060A5C5 /* RKObjectLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D84145650490060A5C5 /* RKObjectLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E12145650490060A5C5 /* RKObjectLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D85145650490060A5C5 /* RKObjectLoader.m */; };
25160E13145650490060A5C5 /* RKObjectLoader_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D86145650490060A5C5 /* RKObjectLoader_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E14145650490060A5C5 /* RKObjectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D87145650490060A5C5 /* RKObjectManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E15145650490060A5C5 /* RKObjectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D88145650490060A5C5 /* RKObjectManager.m */; };
25160E16145650490060A5C5 /* RKObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D89145650490060A5C5 /* RKObjectMapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E17145650490060A5C5 /* RKObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D8A145650490060A5C5 /* RKObjectMapper.m */; };
25160E18145650490060A5C5 /* RKObjectMapper_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8B145650490060A5C5 /* RKObjectMapper_Private.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E19145650490060A5C5 /* RKObjectMapperError.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8C145650490060A5C5 /* RKObjectMapperError.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E1A145650490060A5C5 /* RKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8D145650490060A5C5 /* RKObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E1B145650490060A5C5 /* RKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D8E145650490060A5C5 /* RKObjectMapping.m */; };
25160E1C145650490060A5C5 /* RKObjectMappingDefinition.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8F145650490060A5C5 /* RKObjectMappingDefinition.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E1D145650490060A5C5 /* RKObjectMappingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D90145650490060A5C5 /* RKObjectMappingOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E1E145650490060A5C5 /* RKObjectMappingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D91145650490060A5C5 /* RKObjectMappingOperation.m */; };
25160E1F145650490060A5C5 /* RKObjectMappingProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D92145650490060A5C5 /* RKObjectMappingProvider.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E20145650490060A5C5 /* RKObjectMappingProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D93145650490060A5C5 /* RKObjectMappingProvider.m */; };
25160E21145650490060A5C5 /* RKObjectMappingResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D94145650490060A5C5 /* RKObjectMappingResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E22145650490060A5C5 /* RKObjectMappingResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D95145650490060A5C5 /* RKObjectMappingResult.m */; };
25160E23145650490060A5C5 /* RKObjectPropertyInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D96145650490060A5C5 /* RKObjectPropertyInspector.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E24145650490060A5C5 /* RKObjectPropertyInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D97145650490060A5C5 /* RKObjectPropertyInspector.m */; };
25160E25145650490060A5C5 /* RKObjectRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D98145650490060A5C5 /* RKObjectRelationshipMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E26145650490060A5C5 /* RKObjectRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D99145650490060A5C5 /* RKObjectRelationshipMapping.m */; };
25160E27145650490060A5C5 /* RKObjectRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9A145650490060A5C5 /* RKObjectRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E28145650490060A5C5 /* RKObjectRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9B145650490060A5C5 /* RKObjectRouter.m */; };
25160E29145650490060A5C5 /* RKObjectSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2A145650490060A5C5 /* RKObjectSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectSerializer.m */; };
25160E2B145650490060A5C5 /* RKParserRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9E145650490060A5C5 /* RKParserRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2C145650490060A5C5 /* RKParserRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9F145650490060A5C5 /* RKParserRegistry.m */; };
25160E2D145650490060A5C5 /* RKRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA0145650490060A5C5 /* RKRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2E145650490060A5C5 /* RestKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA1145650490060A5C5 /* RestKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E31145650490060A5C5 /* lcl_config_components.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA5145650490060A5C5 /* lcl_config_components.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E32145650490060A5C5 /* lcl_config_extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA6145650490060A5C5 /* lcl_config_extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E33145650490060A5C5 /* lcl_config_logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA7145650490060A5C5 /* lcl_config_logger.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E34145650490060A5C5 /* NSDictionary+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA8145650490060A5C5 /* NSDictionary+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E35145650490060A5C5 /* NSDictionary+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DA9145650490060A5C5 /* NSDictionary+RKAdditions.m */; };
25160E36145650490060A5C5 /* NSString+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DAA145650490060A5C5 /* NSString+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E37145650490060A5C5 /* NSString+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DAB145650490060A5C5 /* NSString+RKAdditions.m */; };
25160E38145650490060A5C5 /* NSURL+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DAC145650490060A5C5 /* NSURL+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E39145650490060A5C5 /* NSURL+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DAD145650490060A5C5 /* NSURL+RKAdditions.m */; };
25160E3A145650490060A5C5 /* RKJSONParserJSONKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DB0145650490060A5C5 /* RKJSONParserJSONKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E3B145650490060A5C5 /* RKJSONParserJSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DB1145650490060A5C5 /* RKJSONParserJSONKit.m */; };
25160E44145650490060A5C5 /* RestKit-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 25160DBB145650490060A5C5 /* RestKit-Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; };
25160E45145650490060A5C5 /* RKAlert.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DBC145650490060A5C5 /* RKAlert.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E46145650490060A5C5 /* RKAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DBD145650490060A5C5 /* RKAlert.m */; };
25160E47145650490060A5C5 /* RKDotNetDateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DBE145650490060A5C5 /* RKDotNetDateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E48145650490060A5C5 /* RKDotNetDateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DBF145650490060A5C5 /* RKDotNetDateFormatter.m */; };
25160E49145650490060A5C5 /* RKFixCategoryBug.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC0145650490060A5C5 /* RKFixCategoryBug.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E4A145650490060A5C5 /* RKLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC1145650490060A5C5 /* RKLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E4B145650490060A5C5 /* RKLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC2145650490060A5C5 /* RKLog.m */; };
25160E4C145650490060A5C5 /* RKMIMETypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC3145650490060A5C5 /* RKMIMETypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E4D145650490060A5C5 /* RKMIMETypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC4145650490060A5C5 /* RKMIMETypes.m */; };
25160E4E145650490060A5C5 /* RKParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC5145650490060A5C5 /* RKParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E4F145650490060A5C5 /* RKPathMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC6145650490060A5C5 /* RKPathMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E50145650490060A5C5 /* RKPathMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC7145650490060A5C5 /* RKPathMatcher.m */; };
25160E51145650490060A5C5 /* RKSearchEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC8145650490060A5C5 /* RKSearchEngine.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E52145650490060A5C5 /* RKSearchEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC9145650490060A5C5 /* RKSearchEngine.m */; };
25160E53145650490060A5C5 /* Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DCA145650490060A5C5 /* Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E79145651060060A5C5 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160D2714564E820060A5C5 /* SenTestingKit.framework */; };
25160E7A145651060060A5C5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160E63145651060060A5C5 /* Cocoa.framework */; };
25160E7D145651060060A5C5 /* RestKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160E62145651060060A5C5 /* RestKit.framework */; };
25160ECA1456532C0060A5C5 /* GCOAuth.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E8F1456532C0060A5C5 /* GCOAuth.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ECB1456532C0060A5C5 /* GCOAuth.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E8F1456532C0060A5C5 /* GCOAuth.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ECC1456532C0060A5C5 /* GCOAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E901456532C0060A5C5 /* GCOAuth.m */; };
25160ECD1456532C0060A5C5 /* GCOAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E901456532C0060A5C5 /* GCOAuth.m */; };
25160ECE1456532C0060A5C5 /* NSData+Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E911456532C0060A5C5 /* NSData+Base64.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ECF1456532C0060A5C5 /* NSData+Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E911456532C0060A5C5 /* NSData+Base64.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ED01456532C0060A5C5 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E921456532C0060A5C5 /* NSData+Base64.m */; };
25160ED11456532C0060A5C5 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E921456532C0060A5C5 /* NSData+Base64.m */; };
25160ED31456532C0060A5C5 /* FileMD5Hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 25160E951456532C0060A5C5 /* FileMD5Hash.c */; };
25160ED41456532C0060A5C5 /* FileMD5Hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 25160E951456532C0060A5C5 /* FileMD5Hash.c */; };
25160ED51456532C0060A5C5 /* FileMD5Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E961456532C0060A5C5 /* FileMD5Hash.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ED61456532C0060A5C5 /* FileMD5Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E961456532C0060A5C5 /* FileMD5Hash.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160ED71456532C0060A5C5 /* FileMD5Hash_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 25160E971456532C0060A5C5 /* FileMD5Hash_Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; };
25160ED81456532C0060A5C5 /* FileMD5Hash_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 25160E971456532C0060A5C5 /* FileMD5Hash_Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; };
25160ED91456532C0060A5C5 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 25160E981456532C0060A5C5 /* LICENSE */; };
25160EDA1456532C0060A5C5 /* NOTICE in Resources */ = {isa = PBXBuildFile; fileRef = 25160E991456532C0060A5C5 /* NOTICE */; };
25160EDC1456532C0060A5C5 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 25160E9C1456532C0060A5C5 /* CHANGELOG.md */; };
25160EDD1456532C0060A5C5 /* JSONKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E9D1456532C0060A5C5 /* JSONKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EDE1456532C0060A5C5 /* JSONKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E9D1456532C0060A5C5 /* JSONKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EDF1456532C0060A5C5 /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E9E1456532C0060A5C5 /* JSONKit.m */; };
25160EE01456532C0060A5C5 /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160E9E1456532C0060A5C5 /* JSONKit.m */; };
25160EE21456532C0060A5C5 /* lcl.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA21456532C0060A5C5 /* lcl.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EE31456532C0060A5C5 /* lcl.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA21456532C0060A5C5 /* lcl.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EE41456532C0060A5C5 /* lcl.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EA31456532C0060A5C5 /* lcl.m */; };
25160EE51456532C0060A5C5 /* lcl.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EA31456532C0060A5C5 /* lcl.m */; };
25160EE61456532C0060A5C5 /* lcl_config_components.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA41456532C0060A5C5 /* lcl_config_components.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EE71456532C0060A5C5 /* lcl_config_components.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA41456532C0060A5C5 /* lcl_config_components.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EE81456532C0060A5C5 /* lcl_config_extensions.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA51456532C0060A5C5 /* lcl_config_extensions.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EE91456532C0060A5C5 /* lcl_config_extensions.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA51456532C0060A5C5 /* lcl_config_extensions.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EEA1456532C0060A5C5 /* lcl_config_logger.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA61456532C0060A5C5 /* lcl_config_logger.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EEB1456532C0060A5C5 /* lcl_config_logger.template.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EA61456532C0060A5C5 /* lcl_config_logger.template.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EF81456532C0060A5C5 /* LCLNSLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EB01456532C0060A5C5 /* LCLNSLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EF91456532C0060A5C5 /* LCLNSLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EB01456532C0060A5C5 /* LCLNSLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160EFA1456532C0060A5C5 /* LCLNSLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EB11456532C0060A5C5 /* LCLNSLog.m */; };
25160EFB1456532C0060A5C5 /* LCLNSLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EB11456532C0060A5C5 /* LCLNSLog.m */; };
25160F081456532C0060A5C5 /* SOCKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EBD1456532C0060A5C5 /* SOCKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F091456532C0060A5C5 /* SOCKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160EBD1456532C0060A5C5 /* SOCKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F0A1456532C0060A5C5 /* SOCKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EBE1456532C0060A5C5 /* SOCKit.m */; };
25160F0B1456532C0060A5C5 /* SOCKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160EBE1456532C0060A5C5 /* SOCKit.m */; };
25160F171456538B0060A5C5 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160F161456538B0060A5C5 /* libxml2.dylib */; };
25160F25145655AF0060A5C5 /* RestKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA1145650490060A5C5 /* RestKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F26145655BA0060A5C5 /* Network.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D59145650490060A5C5 /* Network.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F27145655BA0060A5C5 /* NSDictionary+RKRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D5C145650490060A5C5 /* NSDictionary+RKRequestSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F28145655BA0060A5C5 /* NSDictionary+RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D5D145650490060A5C5 /* NSDictionary+RKRequestSerialization.m */; };
25160F29145655BA0060A5C5 /* RKClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D60145650490060A5C5 /* RKClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F2A145655BA0060A5C5 /* RKClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D61145650490060A5C5 /* RKClient.m */; };
25160F2B145655BA0060A5C5 /* RKNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D62145650490060A5C5 /* RKNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F2C145655BA0060A5C5 /* RKNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D63145650490060A5C5 /* RKNotifications.m */; };
25160F2D145655BA0060A5C5 /* RKOAuthClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D64145650490060A5C5 /* RKOAuthClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F2E145655BA0060A5C5 /* RKOAuthClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D65145650490060A5C5 /* RKOAuthClient.m */; };
25160F2F145655BA0060A5C5 /* RKParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D66145650490060A5C5 /* RKParams.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F30145655BA0060A5C5 /* RKParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D67145650490060A5C5 /* RKParams.m */; };
25160F31145655BA0060A5C5 /* RKParamsAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D68145650490060A5C5 /* RKParamsAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F32145655BA0060A5C5 /* RKParamsAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D69145650490060A5C5 /* RKParamsAttachment.m */; };
25160F33145655BA0060A5C5 /* RKReachabilityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6A145650490060A5C5 /* RKReachabilityObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F34145655BA0060A5C5 /* RKReachabilityObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D6B145650490060A5C5 /* RKReachabilityObserver.m */; };
25160F35145655BA0060A5C5 /* RKRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6C145650490060A5C5 /* RKRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F36145655BA0060A5C5 /* RKRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D6D145650490060A5C5 /* RKRequest.m */; };
25160F37145655BA0060A5C5 /* RKRequest_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6E145650490060A5C5 /* RKRequest_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F38145655BA0060A5C5 /* RKRequestCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D6F145650490060A5C5 /* RKRequestCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F39145655BA0060A5C5 /* RKRequestCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D70145650490060A5C5 /* RKRequestCache.m */; };
25160F3A145655BA0060A5C5 /* RKRequestQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D71145650490060A5C5 /* RKRequestQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F3B145655BA0060A5C5 /* RKRequestQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D72145650490060A5C5 /* RKRequestQueue.m */; };
25160F3C145655BA0060A5C5 /* RKRequestSerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D73145650490060A5C5 /* RKRequestSerializable.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F3D145655BA0060A5C5 /* RKRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D74145650490060A5C5 /* RKRequestSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F3E145655BA0060A5C5 /* RKRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D75145650490060A5C5 /* RKRequestSerialization.m */; };
25160F3F145655BA0060A5C5 /* RKResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D76145650490060A5C5 /* RKResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F40145655BA0060A5C5 /* RKResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D77145650490060A5C5 /* RKResponse.m */; };
25160F41145655BA0060A5C5 /* RKURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D78145650490060A5C5 /* RKURL.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F42145655BA0060A5C5 /* RKURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D79145650490060A5C5 /* RKURL.m */; };
25160F43145655C60060A5C5 /* ObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7B145650490060A5C5 /* ObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F44145655C60060A5C5 /* RKDynamicObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7C145650490060A5C5 /* RKDynamicObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F45145655C60060A5C5 /* RKDynamicObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D7D145650490060A5C5 /* RKDynamicObjectMapping.m */; };
25160F46145655C60060A5C5 /* RKErrorMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D7E145650490060A5C5 /* RKErrorMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F47145655C60060A5C5 /* RKErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D7F145650490060A5C5 /* RKErrorMessage.m */; };
25160F48145655C60060A5C5 /* RKMappingOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D80145650490060A5C5 /* RKMappingOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F49145655C60060A5C5 /* RKMappingOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D81145650490060A5C5 /* RKMappingOperationQueue.m */; };
25160F4A145655C60060A5C5 /* RKObjectAttributeMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D82145650490060A5C5 /* RKObjectAttributeMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F4B145655C60060A5C5 /* RKObjectAttributeMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D83145650490060A5C5 /* RKObjectAttributeMapping.m */; };
25160F4C145655C60060A5C5 /* RKObjectLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D84145650490060A5C5 /* RKObjectLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F4D145655C60060A5C5 /* RKObjectLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D85145650490060A5C5 /* RKObjectLoader.m */; };
25160F4E145655C60060A5C5 /* RKObjectLoader_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D86145650490060A5C5 /* RKObjectLoader_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F4F145655C60060A5C5 /* RKObjectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D87145650490060A5C5 /* RKObjectManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F50145655C60060A5C5 /* RKObjectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D88145650490060A5C5 /* RKObjectManager.m */; };
25160F51145655C60060A5C5 /* RKObjectMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D89145650490060A5C5 /* RKObjectMapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F52145655C60060A5C5 /* RKObjectMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D8A145650490060A5C5 /* RKObjectMapper.m */; };
25160F53145655C60060A5C5 /* RKObjectMapper_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8B145650490060A5C5 /* RKObjectMapper_Private.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F54145655C60060A5C5 /* RKObjectMapperError.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8C145650490060A5C5 /* RKObjectMapperError.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F55145655C60060A5C5 /* RKObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8D145650490060A5C5 /* RKObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F56145655C60060A5C5 /* RKObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D8E145650490060A5C5 /* RKObjectMapping.m */; };
25160F57145655C60060A5C5 /* RKObjectMappingDefinition.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D8F145650490060A5C5 /* RKObjectMappingDefinition.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F58145655C60060A5C5 /* RKObjectMappingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D90145650490060A5C5 /* RKObjectMappingOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F59145655C60060A5C5 /* RKObjectMappingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D91145650490060A5C5 /* RKObjectMappingOperation.m */; };
25160F5A145655C60060A5C5 /* RKObjectMappingProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D92145650490060A5C5 /* RKObjectMappingProvider.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F5B145655C60060A5C5 /* RKObjectMappingProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D93145650490060A5C5 /* RKObjectMappingProvider.m */; };
25160F5C145655C60060A5C5 /* RKObjectMappingResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D94145650490060A5C5 /* RKObjectMappingResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F5D145655C60060A5C5 /* RKObjectMappingResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D95145650490060A5C5 /* RKObjectMappingResult.m */; };
25160F5E145655C60060A5C5 /* RKObjectPropertyInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D96145650490060A5C5 /* RKObjectPropertyInspector.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F5F145655C60060A5C5 /* RKObjectPropertyInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D97145650490060A5C5 /* RKObjectPropertyInspector.m */; };
25160F60145655C60060A5C5 /* RKObjectRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D98145650490060A5C5 /* RKObjectRelationshipMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F61145655C60060A5C5 /* RKObjectRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D99145650490060A5C5 /* RKObjectRelationshipMapping.m */; };
25160F62145655C60060A5C5 /* RKObjectRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9A145650490060A5C5 /* RKObjectRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F63145655C60060A5C5 /* RKObjectRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9B145650490060A5C5 /* RKObjectRouter.m */; };
25160F64145655C60060A5C5 /* RKObjectSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F65145655C60060A5C5 /* RKObjectSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectSerializer.m */; };
25160F66145655C60060A5C5 /* RKParserRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9E145650490060A5C5 /* RKParserRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F67145655C60060A5C5 /* RKParserRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9F145650490060A5C5 /* RKParserRegistry.m */; };
25160F68145655C60060A5C5 /* RKRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA0145650490060A5C5 /* RKRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F69145655D10060A5C5 /* CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D46145650490060A5C5 /* CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F6A145655D10060A5C5 /* NSManagedObject+ActiveRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D47145650490060A5C5 /* NSManagedObject+ActiveRecord.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F6B145655D10060A5C5 /* NSManagedObject+ActiveRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D48145650490060A5C5 /* NSManagedObject+ActiveRecord.m */; };
25160F6D145655D10060A5C5 /* RKManagedObjectLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4A145650490060A5C5 /* RKManagedObjectLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F6E145655D10060A5C5 /* RKManagedObjectLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4B145650490060A5C5 /* RKManagedObjectLoader.m */; };
25160F6F145655D10060A5C5 /* RKManagedObjectMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4C145650490060A5C5 /* RKManagedObjectMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F70145655D10060A5C5 /* RKManagedObjectMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4D145650490060A5C5 /* RKManagedObjectMapping.m */; };
25160F71145655D10060A5C5 /* RKManagedObjectMappingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D4E145650490060A5C5 /* RKManagedObjectMappingOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F72145655D10060A5C5 /* RKManagedObjectMappingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D4F145650490060A5C5 /* RKManagedObjectMappingOperation.m */; };
25160F73145655D10060A5C5 /* RKManagedObjectSeeder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D50145650490060A5C5 /* RKManagedObjectSeeder.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F74145655D10060A5C5 /* RKManagedObjectSeeder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D51145650490060A5C5 /* RKManagedObjectSeeder.m */; };
25160F75145655D10060A5C5 /* RKManagedObjectStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D52145650490060A5C5 /* RKManagedObjectStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F76145655D10060A5C5 /* RKManagedObjectStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D53145650490060A5C5 /* RKManagedObjectStore.m */; };
25160F77145655D10060A5C5 /* RKManagedObjectThreadSafeInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D54145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F78145655D10060A5C5 /* RKManagedObjectThreadSafeInvocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D55145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.m */; };
25160F79145655D10060A5C5 /* RKObjectPropertyInspector+CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D56145650490060A5C5 /* RKObjectPropertyInspector+CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F7A145655D10060A5C5 /* RKObjectPropertyInspector+CoreData.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D57145650490060A5C5 /* RKObjectPropertyInspector+CoreData.m */; };
25160F7C145657220060A5C5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160F7B145657220060A5C5 /* SystemConfiguration.framework */; };
25160F7E145657300060A5C5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160F7D1456572F0060A5C5 /* Cocoa.framework */; };
25160F7F145657650060A5C5 /* NSData+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D5A145650490060A5C5 /* NSData+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F80145657650060A5C5 /* NSData+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D5B145650490060A5C5 /* NSData+RKAdditions.m */; };
25160F85145657650060A5C5 /* lcl_config_components.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA5145650490060A5C5 /* lcl_config_components.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F86145657650060A5C5 /* lcl_config_extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA6145650490060A5C5 /* lcl_config_extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F87145657650060A5C5 /* lcl_config_logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA7145650490060A5C5 /* lcl_config_logger.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F88145657650060A5C5 /* NSDictionary+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA8145650490060A5C5 /* NSDictionary+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F89145657650060A5C5 /* NSDictionary+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DA9145650490060A5C5 /* NSDictionary+RKAdditions.m */; };
25160F8A145657650060A5C5 /* NSString+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DAA145650490060A5C5 /* NSString+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F8B145657650060A5C5 /* NSString+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DAB145650490060A5C5 /* NSString+RKAdditions.m */; };
25160F8C145657650060A5C5 /* NSURL+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DAC145650490060A5C5 /* NSURL+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F8D145657650060A5C5 /* NSURL+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DAD145650490060A5C5 /* NSURL+RKAdditions.m */; };
25160F8E1456576C0060A5C5 /* RKAlert.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DBC145650490060A5C5 /* RKAlert.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F8F1456576C0060A5C5 /* RKAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DBD145650490060A5C5 /* RKAlert.m */; };
25160F901456576C0060A5C5 /* RKDotNetDateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DBE145650490060A5C5 /* RKDotNetDateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F911456576C0060A5C5 /* RKDotNetDateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DBF145650490060A5C5 /* RKDotNetDateFormatter.m */; };
25160F921456576C0060A5C5 /* RKFixCategoryBug.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC0145650490060A5C5 /* RKFixCategoryBug.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F931456576C0060A5C5 /* RKLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC1145650490060A5C5 /* RKLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F941456576C0060A5C5 /* RKLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC2145650490060A5C5 /* RKLog.m */; };
25160F951456576C0060A5C5 /* RKMIMETypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC3145650490060A5C5 /* RKMIMETypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F961456576C0060A5C5 /* RKMIMETypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC4145650490060A5C5 /* RKMIMETypes.m */; };
25160F971456576C0060A5C5 /* RKParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC5145650490060A5C5 /* RKParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F981456576C0060A5C5 /* RKPathMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC6145650490060A5C5 /* RKPathMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F991456576C0060A5C5 /* RKPathMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC7145650490060A5C5 /* RKPathMatcher.m */; };
25160F9A1456576C0060A5C5 /* RKSearchEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DC8145650490060A5C5 /* RKSearchEngine.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F9B1456576C0060A5C5 /* RKSearchEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DC9145650490060A5C5 /* RKSearchEngine.m */; };
25160F9C1456576C0060A5C5 /* Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DCA145650490060A5C5 /* Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F9E1456577F0060A5C5 /* RKJSONParserJSONKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DB0145650490060A5C5 /* RKJSONParserJSONKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F9F1456577F0060A5C5 /* RKJSONParserJSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160DB1145650490060A5C5 /* RKJSONParserJSONKit.m */; };
25160FA1145658BC0060A5C5 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160FA0145658BC0060A5C5 /* libxml2.dylib */; };
251610581456F2330060A5C5 /* RKManagedObjectLoaderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC71456F2330060A5C5 /* RKManagedObjectLoaderTest.m */; };
251610591456F2330060A5C5 /* RKManagedObjectLoaderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC71456F2330060A5C5 /* RKManagedObjectLoaderTest.m */; };
2516105A1456F2330060A5C5 /* RKManagedObjectMappingOperationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC81456F2330060A5C5 /* RKManagedObjectMappingOperationTest.m */; };
2516105B1456F2330060A5C5 /* RKManagedObjectMappingOperationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC81456F2330060A5C5 /* RKManagedObjectMappingOperationTest.m */; };
2516105C1456F2330060A5C5 /* RKManagedObjectMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC91456F2330060A5C5 /* RKManagedObjectMappingTest.m */; };
2516105D1456F2330060A5C5 /* RKManagedObjectMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FC91456F2330060A5C5 /* RKManagedObjectMappingTest.m */; };
251610601456F2330060A5C5 /* RKManagedObjectStoreTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FCB1456F2330060A5C5 /* RKManagedObjectStoreTest.m */; };
251610611456F2330060A5C5 /* RKManagedObjectStoreTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FCB1456F2330060A5C5 /* RKManagedObjectStoreTest.m */; };
251610621456F2330060A5C5 /* RKManagedObjectThreadSafeInvocationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FCC1456F2330060A5C5 /* RKManagedObjectThreadSafeInvocationTest.m */; };
251610631456F2330060A5C5 /* RKManagedObjectThreadSafeInvocationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FCC1456F2330060A5C5 /* RKManagedObjectThreadSafeInvocationTest.m */; };
251610641456F2330060A5C5 /* blake in Resources */ = {isa = PBXBuildFile; fileRef = 25160FCF1456F2330060A5C5 /* blake */; };
251610651456F2330060A5C5 /* blake in Resources */ = {isa = PBXBuildFile; fileRef = 25160FCF1456F2330060A5C5 /* blake */; };
251610661456F2330060A5C5 /* ArrayOfNestedDictionaries.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD11456F2330060A5C5 /* ArrayOfNestedDictionaries.json */; };
251610671456F2330060A5C5 /* ArrayOfNestedDictionaries.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD11456F2330060A5C5 /* ArrayOfNestedDictionaries.json */; };
251610681456F2330060A5C5 /* ArrayOfResults.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD21456F2330060A5C5 /* ArrayOfResults.json */; };
251610691456F2330060A5C5 /* ArrayOfResults.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD21456F2330060A5C5 /* ArrayOfResults.json */; };
2516106A1456F2330060A5C5 /* ComplexNestedUser.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD31456F2330060A5C5 /* ComplexNestedUser.json */; };
2516106B1456F2330060A5C5 /* ComplexNestedUser.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD31456F2330060A5C5 /* ComplexNestedUser.json */; };
2516106C1456F2330060A5C5 /* ConnectingParents.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD41456F2330060A5C5 /* ConnectingParents.json */; };
2516106D1456F2330060A5C5 /* ConnectingParents.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD41456F2330060A5C5 /* ConnectingParents.json */; };
2516106E1456F2330060A5C5 /* boy.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD61456F2330060A5C5 /* boy.json */; };
2516106F1456F2330060A5C5 /* boy.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD61456F2330060A5C5 /* boy.json */; };
251610701456F2330060A5C5 /* friends.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD71456F2330060A5C5 /* friends.json */; };
251610711456F2330060A5C5 /* friends.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD71456F2330060A5C5 /* friends.json */; };
251610721456F2330060A5C5 /* girl.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD81456F2330060A5C5 /* girl.json */; };
251610731456F2330060A5C5 /* girl.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD81456F2330060A5C5 /* girl.json */; };
251610741456F2330060A5C5 /* mixed.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD91456F2330060A5C5 /* mixed.json */; };
251610751456F2330060A5C5 /* mixed.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FD91456F2330060A5C5 /* mixed.json */; };
251610761456F2330060A5C5 /* DynamicKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDA1456F2330060A5C5 /* DynamicKeys.json */; };
251610771456F2330060A5C5 /* DynamicKeys.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDA1456F2330060A5C5 /* DynamicKeys.json */; };
251610781456F2330060A5C5 /* DynamicKeysWithNestedRelationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDB1456F2330060A5C5 /* DynamicKeysWithNestedRelationship.json */; };
251610791456F2330060A5C5 /* DynamicKeysWithNestedRelationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDB1456F2330060A5C5 /* DynamicKeysWithNestedRelationship.json */; };
2516107A1456F2330060A5C5 /* DynamicKeysWithRelationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDC1456F2330060A5C5 /* DynamicKeysWithRelationship.json */; };
2516107B1456F2330060A5C5 /* DynamicKeysWithRelationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDC1456F2330060A5C5 /* DynamicKeysWithRelationship.json */; };
2516107C1456F2330060A5C5 /* error.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDD1456F2330060A5C5 /* error.json */; };
2516107D1456F2330060A5C5 /* error.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDD1456F2330060A5C5 /* error.json */; };
2516107E1456F2330060A5C5 /* errors.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDE1456F2330060A5C5 /* errors.json */; };
2516107F1456F2330060A5C5 /* errors.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDE1456F2330060A5C5 /* errors.json */; };
251610801456F2330060A5C5 /* Foursquare.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDF1456F2330060A5C5 /* Foursquare.json */; };
251610811456F2330060A5C5 /* Foursquare.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FDF1456F2330060A5C5 /* Foursquare.json */; };
251610821456F2330060A5C5 /* 1.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE11456F2330060A5C5 /* 1.json */; };
251610831456F2330060A5C5 /* 1.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE11456F2330060A5C5 /* 1.json */; };
251610841456F2330060A5C5 /* all.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE21456F2330060A5C5 /* all.json */; };
251610851456F2330060A5C5 /* all.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE21456F2330060A5C5 /* all.json */; };
251610861456F2330060A5C5 /* with_to_one_relationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE31456F2330060A5C5 /* with_to_one_relationship.json */; };
251610871456F2330060A5C5 /* with_to_one_relationship.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE31456F2330060A5C5 /* with_to_one_relationship.json */; };
251610881456F2330060A5C5 /* nested_user.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE41456F2330060A5C5 /* nested_user.json */; };
251610891456F2330060A5C5 /* nested_user.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE41456F2330060A5C5 /* nested_user.json */; };
2516108A1456F2330060A5C5 /* RailsUser.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE51456F2330060A5C5 /* RailsUser.json */; };
2516108B1456F2330060A5C5 /* RailsUser.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE51456F2330060A5C5 /* RailsUser.json */; };
2516108C1456F2330060A5C5 /* SameKeyDifferentTargetClasses.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE61456F2330060A5C5 /* SameKeyDifferentTargetClasses.json */; };
2516108D1456F2330060A5C5 /* SameKeyDifferentTargetClasses.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE61456F2330060A5C5 /* SameKeyDifferentTargetClasses.json */; };
2516108E1456F2330060A5C5 /* user.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE71456F2330060A5C5 /* user.json */; };
2516108F1456F2330060A5C5 /* user.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE71456F2330060A5C5 /* user.json */; };
251610901456F2330060A5C5 /* users.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE81456F2330060A5C5 /* users.json */; };
251610911456F2330060A5C5 /* users.json in Resources */ = {isa = PBXBuildFile; fileRef = 25160FE81456F2330060A5C5 /* users.json */; };
251610931456F2330060A5C5 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 25160FEA1456F2330060A5C5 /* .gitignore */; };
251610961456F2330060A5C5 /* attributes_without_text_content.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FED1456F2330060A5C5 /* attributes_without_text_content.xml */; };
251610971456F2330060A5C5 /* attributes_without_text_content.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FED1456F2330060A5C5 /* attributes_without_text_content.xml */; };
251610981456F2330060A5C5 /* container_attributes.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FEE1456F2330060A5C5 /* container_attributes.xml */; };
251610991456F2330060A5C5 /* container_attributes.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FEE1456F2330060A5C5 /* container_attributes.xml */; };
2516109A1456F2330060A5C5 /* national_weather_service.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FEF1456F2330060A5C5 /* national_weather_service.xml */; };
2516109B1456F2330060A5C5 /* national_weather_service.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FEF1456F2330060A5C5 /* national_weather_service.xml */; };
2516109C1456F2330060A5C5 /* orders.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF01456F2330060A5C5 /* orders.xml */; };
2516109D1456F2330060A5C5 /* orders.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF01456F2330060A5C5 /* orders.xml */; };
2516109E1456F2330060A5C5 /* tab_data.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF11456F2330060A5C5 /* tab_data.xml */; };
2516109F1456F2330060A5C5 /* tab_data.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF11456F2330060A5C5 /* tab_data.xml */; };
251610A01456F2330060A5C5 /* zend.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF21456F2330060A5C5 /* zend.xml */; };
251610A11456F2330060A5C5 /* zend.xml in Resources */ = {isa = PBXBuildFile; fileRef = 25160FF21456F2330060A5C5 /* zend.xml */; };
251610A21456F2330060A5C5 /* Data Model.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF41456F2330060A5C5 /* Data Model.xcdatamodel */; };
251610A31456F2330060A5C5 /* Data Model.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF41456F2330060A5C5 /* Data Model.xcdatamodel */; };
251610A41456F2330060A5C5 /* RKCat.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF61456F2330060A5C5 /* RKCat.m */; };
251610A51456F2330060A5C5 /* RKCat.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF61456F2330060A5C5 /* RKCat.m */; };
251610A61456F2330060A5C5 /* RKChild.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF81456F2330060A5C5 /* RKChild.m */; };
251610A71456F2330060A5C5 /* RKChild.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FF81456F2330060A5C5 /* RKChild.m */; };
251610A81456F2330060A5C5 /* RKDynamicMappingModels.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFA1456F2330060A5C5 /* RKDynamicMappingModels.m */; };
251610A91456F2330060A5C5 /* RKDynamicMappingModels.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFA1456F2330060A5C5 /* RKDynamicMappingModels.m */; };
251610AA1456F2330060A5C5 /* RKHouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFC1456F2330060A5C5 /* RKHouse.m */; };
251610AB1456F2330060A5C5 /* RKHouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFC1456F2330060A5C5 /* RKHouse.m */; };
251610AC1456F2330060A5C5 /* RKHuman.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFE1456F2330060A5C5 /* RKHuman.m */; };
251610AD1456F2330060A5C5 /* RKHuman.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160FFE1456F2330060A5C5 /* RKHuman.m */; };
251610AE1456F2330060A5C5 /* RKMappableAssociation.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610001456F2330060A5C5 /* RKMappableAssociation.m */; };
251610AF1456F2330060A5C5 /* RKMappableAssociation.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610001456F2330060A5C5 /* RKMappableAssociation.m */; };
251610B01456F2330060A5C5 /* RKMappableObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610021456F2330060A5C5 /* RKMappableObject.m */; };
251610B11456F2330060A5C5 /* RKMappableObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610021456F2330060A5C5 /* RKMappableObject.m */; };
251610B21456F2330060A5C5 /* RKObjectLoaderTestResultModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610041456F2330060A5C5 /* RKObjectLoaderTestResultModel.m */; };
251610B31456F2330060A5C5 /* RKObjectLoaderTestResultModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610041456F2330060A5C5 /* RKObjectLoaderTestResultModel.m */; };
251610B41456F2330060A5C5 /* RKObjectMapperTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610061456F2330060A5C5 /* RKObjectMapperTestModel.m */; };
251610B51456F2330060A5C5 /* RKObjectMapperTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610061456F2330060A5C5 /* RKObjectMapperTestModel.m */; };
251610B61456F2330060A5C5 /* RKParent.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610081456F2330060A5C5 /* RKParent.m */; };
251610B71456F2330060A5C5 /* RKParent.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610081456F2330060A5C5 /* RKParent.m */; };
251610B81456F2330060A5C5 /* RKResident.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516100A1456F2330060A5C5 /* RKResident.m */; };
251610B91456F2330060A5C5 /* RKResident.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516100A1456F2330060A5C5 /* RKResident.m */; };
251610BE1456F2330060A5C5 /* RKAuthenticationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610101456F2330060A5C5 /* RKAuthenticationTest.m */; };
251610BF1456F2330060A5C5 /* RKAuthenticationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610101456F2330060A5C5 /* RKAuthenticationTest.m */; };
251610C01456F2330060A5C5 /* RKClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610111456F2330060A5C5 /* RKClientTest.m */; };
251610C11456F2330060A5C5 /* RKClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610111456F2330060A5C5 /* RKClientTest.m */; };
251610C21456F2330060A5C5 /* RKOAuthClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610121456F2330060A5C5 /* RKOAuthClientTest.m */; };
251610C31456F2330060A5C5 /* RKOAuthClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610121456F2330060A5C5 /* RKOAuthClientTest.m */; };
251610C41456F2330060A5C5 /* RKParamsAttachmentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610131456F2330060A5C5 /* RKParamsAttachmentTest.m */; };
251610C51456F2330060A5C5 /* RKParamsAttachmentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610131456F2330060A5C5 /* RKParamsAttachmentTest.m */; };
251610C61456F2330060A5C5 /* RKParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610141456F2330060A5C5 /* RKParamsTest.m */; };
251610C71456F2330060A5C5 /* RKParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610141456F2330060A5C5 /* RKParamsTest.m */; };
251610CA1456F2330060A5C5 /* RKRequestQueueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610171456F2330060A5C5 /* RKRequestQueueTest.m */; };
251610CB1456F2330060A5C5 /* RKRequestQueueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610171456F2330060A5C5 /* RKRequestQueueTest.m */; };
251610CC1456F2330060A5C5 /* RKRequestTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610181456F2330060A5C5 /* RKRequestTest.m */; };
251610CD1456F2330060A5C5 /* RKRequestTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610181456F2330060A5C5 /* RKRequestTest.m */; };
251610CE1456F2330060A5C5 /* RKResponseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610191456F2330060A5C5 /* RKResponseTest.m */; };
251610CF1456F2330060A5C5 /* RKResponseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610191456F2330060A5C5 /* RKResponseTest.m */; };
251610D01456F2330060A5C5 /* RKURLTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101A1456F2330060A5C5 /* RKURLTest.m */; };
251610D11456F2330060A5C5 /* RKURLTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101A1456F2330060A5C5 /* RKURLTest.m */; };
251610D21456F2330060A5C5 /* RKDynamicObjectMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101C1456F2330060A5C5 /* RKDynamicObjectMappingTest.m */; };
251610D31456F2330060A5C5 /* RKDynamicObjectMappingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101C1456F2330060A5C5 /* RKDynamicObjectMappingTest.m */; };
251610D61456F2330060A5C5 /* RKObjectLoaderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101E1456F2330060A5C5 /* RKObjectLoaderTest.m */; };
251610D71456F2330060A5C5 /* RKObjectLoaderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101E1456F2330060A5C5 /* RKObjectLoaderTest.m */; };
251610D81456F2330060A5C5 /* RKObjectManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101F1456F2330060A5C5 /* RKObjectManagerTest.m */; };
251610D91456F2330060A5C5 /* RKObjectManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2516101F1456F2330060A5C5 /* RKObjectManagerTest.m */; };
251610DC1456F2330060A5C5 /* RKObjectMappingNextGenTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610211456F2330060A5C5 /* RKObjectMappingNextGenTest.m */; };
251610DD1456F2330060A5C5 /* RKObjectMappingNextGenTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610211456F2330060A5C5 /* RKObjectMappingNextGenTest.m */; };
251610DE1456F2330060A5C5 /* RKObjectMappingOperationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */; };
251610DF1456F2330060A5C5 /* RKObjectMappingOperationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */; };
251610E01456F2330060A5C5 /* RKObjectMappingProviderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610231456F2330060A5C5 /* RKObjectMappingProviderTest.m */; };
251610E11456F2330060A5C5 /* RKObjectMappingProviderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610231456F2330060A5C5 /* RKObjectMappingProviderTest.m */; };
251610E21456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */; };
251610E31456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */; };
251610E41456F2330060A5C5 /* RKObjectRouterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610251456F2330060A5C5 /* RKObjectRouterTest.m */; };
251610E51456F2330060A5C5 /* RKObjectRouterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610251456F2330060A5C5 /* RKObjectRouterTest.m */; };
251610E61456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectSerializerTest.m */; };
251610E71456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectSerializerTest.m */; };
251610E81456F2330060A5C5 /* RKParserRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610271456F2330060A5C5 /* RKParserRegistryTest.m */; };
251610E91456F2330060A5C5 /* RKParserRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610271456F2330060A5C5 /* RKParserRegistryTest.m */; };
251610F01456F2340060A5C5 /* RKTestEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610361456F2330060A5C5 /* RKTestEnvironment.m */; };
251610F11456F2340060A5C5 /* RKTestEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610361456F2330060A5C5 /* RKTestEnvironment.m */; };
251611031456F2340060A5C5 /* authentication.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2516104B1456F2330060A5C5 /* authentication.rb */; };
251611051456F2340060A5C5 /* etags.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2516104C1456F2330060A5C5 /* etags.rb */; };
251611071456F2340060A5C5 /* oauth2.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2516104D1456F2330060A5C5 /* oauth2.rb */; };
251611091456F2340060A5C5 /* timeout.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2516104E1456F2330060A5C5 /* timeout.rb */; };
2516110B1456F2340060A5C5 /* restkit.rb in Resources */ = {isa = PBXBuildFile; fileRef = 2516104F1456F2330060A5C5 /* restkit.rb */; };
2516110D1456F2340060A5C5 /* server.rb in Resources */ = {isa = PBXBuildFile; fileRef = 251610501456F2330060A5C5 /* server.rb */; };
2516110E1456F2340060A5C5 /* NSDictionary+RKRequestSerializationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610521456F2330060A5C5 /* NSDictionary+RKRequestSerializationTest.m */; };
2516110F1456F2340060A5C5 /* NSDictionary+RKRequestSerializationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610521456F2330060A5C5 /* NSDictionary+RKRequestSerializationTest.m */; };
251611101456F2340060A5C5 /* NSStringRestKitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610531456F2330060A5C5 /* NSStringRestKitTest.m */; };
251611111456F2340060A5C5 /* NSStringRestKitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610531456F2330060A5C5 /* NSStringRestKitTest.m */; };
251611121456F2340060A5C5 /* RKDotNetDateFormatterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610541456F2330060A5C5 /* RKDotNetDateFormatterTest.m */; };
251611131456F2340060A5C5 /* RKDotNetDateFormatterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610541456F2330060A5C5 /* RKDotNetDateFormatterTest.m */; };
251611141456F2340060A5C5 /* RKJSONParserJSONKitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610551456F2330060A5C5 /* RKJSONParserJSONKitTest.m */; };
251611151456F2340060A5C5 /* RKJSONParserJSONKitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610551456F2330060A5C5 /* RKJSONParserJSONKitTest.m */; };
251611161456F2340060A5C5 /* RKPathMatcherTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610561456F2330060A5C5 /* RKPathMatcherTest.m */; };
251611171456F2340060A5C5 /* RKPathMatcherTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610561456F2330060A5C5 /* RKPathMatcherTest.m */; };
251611181456F2340060A5C5 /* RKXMLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610571456F2330060A5C5 /* RKXMLParserTest.m */; };
251611191456F2340060A5C5 /* RKXMLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610571456F2330060A5C5 /* RKXMLParserTest.m */; };
251611291456F50F0060A5C5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 251611281456F50F0060A5C5 /* SystemConfiguration.framework */; };
2516112B1456F5170060A5C5 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516112A1456F5170060A5C5 /* CFNetwork.framework */; };
2516112C1456F51D0060A5C5 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 25160F161456538B0060A5C5 /* libxml2.dylib */; };
2516112E1456F5520060A5C5 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516112D1456F5520060A5C5 /* CoreData.framework */; };
251611301456F5590060A5C5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2516112F1456F5590060A5C5 /* Security.framework */; };
251611321456F56C0060A5C5 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 251611311456F56C0060A5C5 /* MobileCoreServices.framework */; };
252A202D153471380078F8AD /* NSArray+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 252A202B153471380078F8AD /* NSArray+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
252A202E153471380078F8AD /* NSArray+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 252A202C153471380078F8AD /* NSArray+RKAdditions.m */; };
252A2030153471470078F8AD /* NSArray+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 252A202C153471380078F8AD /* NSArray+RKAdditions.m */; };
252A20311534714D0078F8AD /* NSArray+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 252A202B153471380078F8AD /* NSArray+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
252A2034153477870078F8AD /* NSArray+RKAdditionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252A2033153477870078F8AD /* NSArray+RKAdditionsTest.m */; };
252A2035153477870078F8AD /* NSArray+RKAdditionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252A2033153477870078F8AD /* NSArray+RKAdditionsTest.m */; };
252EFAFA14D8EAEC004863C8 /* RKEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFAF914D8EAEC004863C8 /* RKEvent.m */; };
252EFAFB14D8EAEC004863C8 /* RKEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFAF914D8EAEC004863C8 /* RKEvent.m */; };
252EFB0814D98F4D004863C8 /* RKSearchableManagedObjectTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0614D98F4D004863C8 /* RKSearchableManagedObjectTest.m */; };
252EFB0914D98F4D004863C8 /* RKSearchableManagedObjectTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0614D98F4D004863C8 /* RKSearchableManagedObjectTest.m */; };
252EFB0A14D98F4D004863C8 /* RKSearchWordObserverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0714D98F4D004863C8 /* RKSearchWordObserverTest.m */; };
252EFB0B14D98F4D004863C8 /* RKSearchWordObserverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0714D98F4D004863C8 /* RKSearchWordObserverTest.m */; };
252EFB0D14D98F76004863C8 /* RKMutableBlockDictionaryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0C14D98F76004863C8 /* RKMutableBlockDictionaryTest.m */; };
252EFB0E14D98F76004863C8 /* RKMutableBlockDictionaryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB0C14D98F76004863C8 /* RKMutableBlockDictionaryTest.m */; };
252EFB1B14D9A7CB004863C8 /* NSBundle+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFB1914D9A7CB004863C8 /* NSBundle+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
252EFB1C14D9A7CB004863C8 /* NSBundle+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFB1914D9A7CB004863C8 /* NSBundle+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
252EFB1D14D9A7CB004863C8 /* NSBundle+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB1A14D9A7CB004863C8 /* NSBundle+RKAdditions.m */; };
252EFB1E14D9A7CB004863C8 /* NSBundle+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB1A14D9A7CB004863C8 /* NSBundle+RKAdditions.m */; };
252EFB2514D9B6F2004863C8 /* Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFB2414D9B6F2004863C8 /* Testing.h */; settings = {ATTRIBUTES = (Public, ); }; };
252EFB2614D9B6F2004863C8 /* Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFB2414D9B6F2004863C8 /* Testing.h */; settings = {ATTRIBUTES = (Public, ); }; };
252EFB2814DA0689004863C8 /* NakedEvents.json in Resources */ = {isa = PBXBuildFile; fileRef = 252EFB2714DA0689004863C8 /* NakedEvents.json */; };
252EFB2914DA0689004863C8 /* NakedEvents.json in Resources */ = {isa = PBXBuildFile; fileRef = 252EFB2714DA0689004863C8 /* NakedEvents.json */; };
253B495214E35D1A00B0483F /* RKTestFixture.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFB2014D9B35D004863C8 /* RKTestFixture.h */; settings = {ATTRIBUTES = (Public, ); }; };
253B495F14E35EC300B0483F /* RKTestFixture.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB2114D9B35D004863C8 /* RKTestFixture.m */; };
254A62B914AD544200939BEE /* RKObjectPaginator.h in Headers */ = {isa = PBXBuildFile; fileRef = 254A62B714AD544200939BEE /* RKObjectPaginator.h */; settings = {ATTRIBUTES = (Public, ); }; };
254A62BA14AD544200939BEE /* RKObjectPaginator.h in Headers */ = {isa = PBXBuildFile; fileRef = 254A62B714AD544200939BEE /* RKObjectPaginator.h */; settings = {ATTRIBUTES = (Public, ); }; };
254A62BB14AD544200939BEE /* RKObjectPaginator.m in Sources */ = {isa = PBXBuildFile; fileRef = 254A62B814AD544200939BEE /* RKObjectPaginator.m */; };
254A62BC14AD544200939BEE /* RKObjectPaginator.m in Sources */ = {isa = PBXBuildFile; fileRef = 254A62B814AD544200939BEE /* RKObjectPaginator.m */; };
254A62C014AD591C00939BEE /* RKObjectPaginatorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 254A62BF14AD591C00939BEE /* RKObjectPaginatorTest.m */; };
254A62C114AD591C00939BEE /* RKObjectPaginatorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 254A62BF14AD591C00939BEE /* RKObjectPaginatorTest.m */; };
25545959155F0527007D7625 /* RKBenchmark.h in Headers */ = {isa = PBXBuildFile; fileRef = 25545957155F0527007D7625 /* RKBenchmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
2554595A155F0527007D7625 /* RKBenchmark.h in Headers */ = {isa = PBXBuildFile; fileRef = 25545957155F0527007D7625 /* RKBenchmark.h */; settings = {ATTRIBUTES = (Public, ); }; };
2554595B155F0527007D7625 /* RKBenchmark.m in Sources */ = {isa = PBXBuildFile; fileRef = 25545958155F0527007D7625 /* RKBenchmark.m */; };
2554595C155F0527007D7625 /* RKBenchmark.m in Sources */ = {isa = PBXBuildFile; fileRef = 25545958155F0527007D7625 /* RKBenchmark.m */; };
2572538D155C543000CB05ED /* RKPortCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 2572538B155C543000CB05ED /* RKPortCheck.h */; settings = {ATTRIBUTES = (Public, ); }; };
2572538E155C543000CB05ED /* RKPortCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 2572538B155C543000CB05ED /* RKPortCheck.h */; settings = {ATTRIBUTES = (Public, ); }; };
2572538F155C543000CB05ED /* RKPortCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 2572538C155C543000CB05ED /* RKPortCheck.m */; };
25725390155C543000CB05ED /* RKPortCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 2572538C155C543000CB05ED /* RKPortCheck.m */; };
257ABAB015112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257ABAAE15112DD400CCAA76 /* NSManagedObjectContext+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
257ABAB115112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257ABAAE15112DD400CCAA76 /* NSManagedObjectContext+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
257ABAB215112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257ABAAF15112DD400CCAA76 /* NSManagedObjectContext+RKAdditions.m */; };
257ABAB315112DD500CCAA76 /* NSManagedObjectContext+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257ABAAF15112DD400CCAA76 /* NSManagedObjectContext+RKAdditions.m */; };
257ABAB61511371E00CCAA76 /* NSManagedObject+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257ABAB41511371C00CCAA76 /* NSManagedObject+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
257ABAB71511371E00CCAA76 /* NSManagedObject+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 257ABAB41511371C00CCAA76 /* NSManagedObject+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
257ABAB81511371E00CCAA76 /* NSManagedObject+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257ABAB51511371D00CCAA76 /* NSManagedObject+RKAdditions.m */; };
257ABAB91511371E00CCAA76 /* NSManagedObject+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 257ABAB51511371D00CCAA76 /* NSManagedObject+RKAdditions.m */; };
259C301715128079003066A2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25EC1B0014F8078100C3CF3F /* CoreFoundation.framework */; };
259C3022151280A1003066A2 /* blackArrow in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1ADE14F8022600C3CF3F /* blackArrow */; };
259C3023151280A1003066A2 /* in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1ADF14F8022600C3CF3F /* */; };
259C3024151280A1003066A2 /* blueArrow in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE014F8022600C3CF3F /* blueArrow */; };
259C3025151280A1003066A2 /* in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE114F8022600C3CF3F /* */; };
259C3026151280A1003066A2 /* grayArrow in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE214F8022600C3CF3F /* grayArrow */; };
259C3027151280A1003066A2 /* in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE314F8022600C3CF3F /* */; };
259C3028151280A1003066A2 /* whiteArrow in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE414F8022600C3CF3F /* whiteArrow */; };
259C3029151280A1003066A2 /* in Resources */ = {isa = PBXBuildFile; fileRef = 25EC1AE514F8022600C3CF3F /* */; };
259D983C154F6C90008C90F5 /* benchmark_parents_and_children.json in Resources */ = {isa = PBXBuildFile; fileRef = 259D983B154F6C90008C90F5 /* benchmark_parents_and_children.json */; };
259D983D154F6C90008C90F5 /* benchmark_parents_and_children.json in Resources */ = {isa = PBXBuildFile; fileRef = 259D983B154F6C90008C90F5 /* benchmark_parents_and_children.json */; };
259D98541550C69A008C90F5 /* RKEntityByAttributeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 259D98521550C69A008C90F5 /* RKEntityByAttributeCache.h */; };
259D98551550C69A008C90F5 /* RKEntityByAttributeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 259D98521550C69A008C90F5 /* RKEntityByAttributeCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
259D98561550C69A008C90F5 /* RKEntityByAttributeCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D98531550C69A008C90F5 /* RKEntityByAttributeCache.m */; };
259D98571550C69A008C90F5 /* RKEntityByAttributeCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D98531550C69A008C90F5 /* RKEntityByAttributeCache.m */; };
259D985A1550C6BE008C90F5 /* RKEntityByAttributeCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D98591550C6BE008C90F5 /* RKEntityByAttributeCacheTest.m */; };
259D985B1550C6BE008C90F5 /* RKEntityByAttributeCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D98591550C6BE008C90F5 /* RKEntityByAttributeCacheTest.m */; };
259D985E155218E5008C90F5 /* RKEntityCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 259D985C155218E4008C90F5 /* RKEntityCache.h */; };
259D985F155218E5008C90F5 /* RKEntityCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 259D985C155218E4008C90F5 /* RKEntityCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
259D9860155218E5008C90F5 /* RKEntityCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D985D155218E4008C90F5 /* RKEntityCache.m */; };
259D9861155218E5008C90F5 /* RKEntityCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D985D155218E4008C90F5 /* RKEntityCache.m */; };
259D986415521B20008C90F5 /* RKEntityCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D986315521B1F008C90F5 /* RKEntityCacheTest.m */; };
259D986515521B20008C90F5 /* RKEntityCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 259D986315521B1F008C90F5 /* RKEntityCacheTest.m */; };
25A2476E153E667E003240B6 /* RKCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A2476D153E667E003240B6 /* RKCacheTest.m */; };
25A2476F153E667E003240B6 /* RKCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A2476D153E667E003240B6 /* RKCacheTest.m */; };
25A34245147D8AAA0009758D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25A34244147D8AAA0009758D /* Security.framework */; };
25B408261491CDDC00F21111 /* RKDirectory.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B408241491CDDB00F21111 /* RKDirectory.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B408271491CDDC00F21111 /* RKDirectory.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B408241491CDDB00F21111 /* RKDirectory.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B408281491CDDC00F21111 /* RKDirectory.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B408251491CDDB00F21111 /* RKDirectory.m */; };
25B408291491CDDC00F21111 /* RKDirectory.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B408251491CDDB00F21111 /* RKDirectory.m */; };
25B6E91E14CF778D00B1E881 /* RKAbstractTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90314CF778D00B1E881 /* RKAbstractTableController.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E92014CF778D00B1E881 /* RKAbstractTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90414CF778D00B1E881 /* RKAbstractTableController.m */; };
25B6E92314CF778D00B1E881 /* RKAbstractTableController_Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90614CF778D00B1E881 /* RKAbstractTableController_Internals.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E92514CF778D00B1E881 /* RKControlTableItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90714CF778D00B1E881 /* RKControlTableItem.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E92714CF778D00B1E881 /* RKControlTableItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90814CF778D00B1E881 /* RKControlTableItem.m */; };
25B6E92914CF778D00B1E881 /* RKControlTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90914CF778D00B1E881 /* RKControlTableViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E92B14CF778D00B1E881 /* RKControlTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90A14CF778D00B1E881 /* RKControlTableViewCell.m */; };
25B6E92D14CF778D00B1E881 /* RKFetchedResultsTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90B14CF778D00B1E881 /* RKFetchedResultsTableController.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E92F14CF778D00B1E881 /* RKFetchedResultsTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90C14CF778D00B1E881 /* RKFetchedResultsTableController.m */; };
25B6E93114CF778D00B1E881 /* RKForm.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90D14CF778D00B1E881 /* RKForm.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E93314CF778D00B1E881 /* RKForm.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E90E14CF778D00B1E881 /* RKForm.m */; };
25B6E93514CF778D00B1E881 /* RKFormSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E90F14CF778D00B1E881 /* RKFormSection.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E93714CF778D00B1E881 /* RKFormSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91014CF778D00B1E881 /* RKFormSection.m */; };
25B6E93914CF778D00B1E881 /* RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91114CF778D00B1E881 /* RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E93B14CF778D00B1E881 /* RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91214CF778D00B1E881 /* RKTableController.m */; };
25B6E93D14CF778D00B1E881 /* RKTableItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91314CF778D00B1E881 /* RKTableItem.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E93F14CF778D00B1E881 /* RKTableItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91414CF778D00B1E881 /* RKTableItem.m */; };
25B6E94114CF778D00B1E881 /* RKTableSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91514CF778D00B1E881 /* RKTableSection.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E94314CF778D00B1E881 /* RKTableSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91614CF778D00B1E881 /* RKTableSection.m */; };
25B6E94514CF778D00B1E881 /* RKTableViewCellMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91714CF778D00B1E881 /* RKTableViewCellMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E94714CF778D00B1E881 /* RKTableViewCellMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91814CF778D00B1E881 /* RKTableViewCellMapping.m */; };
25B6E94914CF778D00B1E881 /* RKTableViewCellMappings.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91914CF778D00B1E881 /* RKTableViewCellMappings.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E94B14CF778D00B1E881 /* RKTableViewCellMappings.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91A14CF778D00B1E881 /* RKTableViewCellMappings.m */; };
25B6E94D14CF778D00B1E881 /* UI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91B14CF778D00B1E881 /* UI.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E94F14CF778D00B1E881 /* UIView+FindFirstResponder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E91C14CF778D00B1E881 /* UIView+FindFirstResponder.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E95114CF778D00B1E881 /* UIView+FindFirstResponder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E91D14CF778D00B1E881 /* UIView+FindFirstResponder.m */; };
25B6E95514CF795D00B1E881 /* RKErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95414CF795D00B1E881 /* RKErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E95614CF795D00B1E881 /* RKErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95414CF795D00B1E881 /* RKErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E95814CF7A1C00B1E881 /* RKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E95714CF7A1C00B1E881 /* RKErrors.m */; };
25B6E95914CF7A1C00B1E881 /* RKErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E95714CF7A1C00B1E881 /* RKErrors.m */; };
25B6E95C14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95A14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E95D14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E95A14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E95E14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E95B14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.m */; };
25B6E95F14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E95B14CF7E3C00B1E881 /* RKDynamicObjectMappingMatcher.m */; };
25B6E9A414CF829400B1E881 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 25B6E97B14CF829400B1E881 /* InfoPlist.strings */; };
25B6E9A514CF829400B1E881 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 25B6E97B14CF829400B1E881 /* InfoPlist.strings */; };
25B6E9A614CF829400B1E881 /* NSInvocation+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E97E14CF829400B1E881 /* NSInvocation+OCMAdditions.m */; };
25B6E9A714CF829400B1E881 /* NSInvocation+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E97E14CF829400B1E881 /* NSInvocation+OCMAdditions.m */; };
25B6E9A814CF829400B1E881 /* NSMethodSignature+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98014CF829400B1E881 /* NSMethodSignature+OCMAdditions.m */; };
25B6E9A914CF829400B1E881 /* NSMethodSignature+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98014CF829400B1E881 /* NSMethodSignature+OCMAdditions.m */; };
25B6E9AA14CF829400B1E881 /* NSNotificationCenter+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98114CF829400B1E881 /* NSNotificationCenter+OCMAdditions.m */; };
25B6E9AB14CF829400B1E881 /* NSNotificationCenter+OCMAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98114CF829400B1E881 /* NSNotificationCenter+OCMAdditions.m */; };
25B6E9AC14CF829400B1E881 /* OCClassMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98314CF829400B1E881 /* OCClassMockObject.m */; };
25B6E9AD14CF829400B1E881 /* OCClassMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98314CF829400B1E881 /* OCClassMockObject.m */; };
25B6E9AE14CF829400B1E881 /* OCMArg.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98414CF829400B1E881 /* OCMArg.m */; };
25B6E9AF14CF829400B1E881 /* OCMArg.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98414CF829400B1E881 /* OCMArg.m */; };
25B6E9B014CF829400B1E881 /* OCMBlockCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98614CF829400B1E881 /* OCMBlockCaller.m */; };
25B6E9B114CF829400B1E881 /* OCMBlockCaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98614CF829400B1E881 /* OCMBlockCaller.m */; };
25B6E9B214CF829400B1E881 /* OCMBoxedReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98814CF829400B1E881 /* OCMBoxedReturnValueProvider.m */; };
25B6E9B314CF829400B1E881 /* OCMBoxedReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98814CF829400B1E881 /* OCMBoxedReturnValueProvider.m */; };
25B6E9B414CF829400B1E881 /* OCMConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98914CF829400B1E881 /* OCMConstraint.m */; };
25B6E9B514CF829400B1E881 /* OCMConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98914CF829400B1E881 /* OCMConstraint.m */; };
25B6E9B614CF829400B1E881 /* OCMExceptionReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98B14CF829400B1E881 /* OCMExceptionReturnValueProvider.m */; };
25B6E9B714CF829400B1E881 /* OCMExceptionReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98B14CF829400B1E881 /* OCMExceptionReturnValueProvider.m */; };
25B6E9B814CF829400B1E881 /* OCMIndirectReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98D14CF829400B1E881 /* OCMIndirectReturnValueProvider.m */; };
25B6E9B914CF829400B1E881 /* OCMIndirectReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98D14CF829400B1E881 /* OCMIndirectReturnValueProvider.m */; };
25B6E9BA14CF829400B1E881 /* OCMNotificationPoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98F14CF829400B1E881 /* OCMNotificationPoster.m */; };
25B6E9BB14CF829400B1E881 /* OCMNotificationPoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E98F14CF829400B1E881 /* OCMNotificationPoster.m */; };
25B6E9BC14CF829400B1E881 /* OCMObserverRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99114CF829400B1E881 /* OCMObserverRecorder.m */; };
25B6E9BD14CF829400B1E881 /* OCMObserverRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99114CF829400B1E881 /* OCMObserverRecorder.m */; };
25B6E9BE14CF829400B1E881 /* OCMock-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 25B6E99214CF829400B1E881 /* OCMock-Info.plist */; };
25B6E9BF14CF829400B1E881 /* OCMock-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 25B6E99214CF829400B1E881 /* OCMock-Info.plist */; };
25B6E9C014CF829400B1E881 /* OCMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99414CF829400B1E881 /* OCMockObject.m */; };
25B6E9C114CF829400B1E881 /* OCMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99414CF829400B1E881 /* OCMockObject.m */; };
25B6E9C214CF829400B1E881 /* OCMockRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99514CF829400B1E881 /* OCMockRecorder.m */; };
25B6E9C314CF829400B1E881 /* OCMockRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99514CF829400B1E881 /* OCMockRecorder.m */; };
25B6E9C414CF829400B1E881 /* OCMPassByRefSetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99714CF829400B1E881 /* OCMPassByRefSetter.m */; };
25B6E9C514CF829400B1E881 /* OCMPassByRefSetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99714CF829400B1E881 /* OCMPassByRefSetter.m */; };
25B6E9C614CF829400B1E881 /* OCMRealObjectForwarder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99914CF829400B1E881 /* OCMRealObjectForwarder.m */; };
25B6E9C714CF829400B1E881 /* OCMRealObjectForwarder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99914CF829400B1E881 /* OCMRealObjectForwarder.m */; };
25B6E9C814CF829400B1E881 /* OCMReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99B14CF829400B1E881 /* OCMReturnValueProvider.m */; };
25B6E9C914CF829400B1E881 /* OCMReturnValueProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99B14CF829400B1E881 /* OCMReturnValueProvider.m */; };
25B6E9CA14CF829400B1E881 /* OCObserverMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99D14CF829400B1E881 /* OCObserverMockObject.m */; };
25B6E9CB14CF829400B1E881 /* OCObserverMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99D14CF829400B1E881 /* OCObserverMockObject.m */; };
25B6E9CC14CF829400B1E881 /* OCPartialMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99F14CF829400B1E881 /* OCPartialMockObject.m */; };
25B6E9CD14CF829400B1E881 /* OCPartialMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E99F14CF829400B1E881 /* OCPartialMockObject.m */; };
25B6E9CE14CF829400B1E881 /* OCPartialMockRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9A114CF829400B1E881 /* OCPartialMockRecorder.m */; };
25B6E9CF14CF829400B1E881 /* OCPartialMockRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9A114CF829400B1E881 /* OCPartialMockRecorder.m */; };
25B6E9D014CF829400B1E881 /* OCProtocolMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9A314CF829400B1E881 /* OCProtocolMockObject.m */; };
25B6E9D114CF829400B1E881 /* OCProtocolMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9A314CF829400B1E881 /* OCProtocolMockObject.m */; };
25B6E9DB14CF912500B1E881 /* RKSearchable.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9D614CF912500B1E881 /* RKSearchable.m */; };
25B6E9DC14CF912500B1E881 /* RKSearchable.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9D614CF912500B1E881 /* RKSearchable.m */; };
25B6E9DD14CF912500B1E881 /* RKTestAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9D814CF912500B1E881 /* RKTestAddress.m */; };
25B6E9DE14CF912500B1E881 /* RKTestAddress.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9D814CF912500B1E881 /* RKTestAddress.m */; };
25B6E9DF14CF912500B1E881 /* RKTestUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9DA14CF912500B1E881 /* RKTestUser.m */; };
25B6E9E014CF912500B1E881 /* RKTestUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9DA14CF912500B1E881 /* RKTestUser.m */; };
25B6E9E914CF940700B1E881 /* RKManagedObjectSearchEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E114CF940600B1E881 /* RKManagedObjectSearchEngine.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9EA14CF940700B1E881 /* RKManagedObjectSearchEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E114CF940600B1E881 /* RKManagedObjectSearchEngine.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9EB14CF940700B1E881 /* RKManagedObjectSearchEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E214CF940600B1E881 /* RKManagedObjectSearchEngine.m */; };
25B6E9EC14CF940700B1E881 /* RKManagedObjectSearchEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E214CF940600B1E881 /* RKManagedObjectSearchEngine.m */; };
25B6E9ED14CF940700B1E881 /* RKSearchableManagedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E314CF940600B1E881 /* RKSearchableManagedObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9EE14CF940700B1E881 /* RKSearchableManagedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E314CF940600B1E881 /* RKSearchableManagedObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9EF14CF940700B1E881 /* RKSearchableManagedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E414CF940600B1E881 /* RKSearchableManagedObject.m */; };
25B6E9F014CF940700B1E881 /* RKSearchableManagedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E414CF940600B1E881 /* RKSearchableManagedObject.m */; };
25B6E9F114CF940700B1E881 /* RKSearchWord.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E514CF940600B1E881 /* RKSearchWord.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9F214CF940700B1E881 /* RKSearchWord.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E514CF940600B1E881 /* RKSearchWord.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9F314CF940700B1E881 /* RKSearchWord.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E614CF940600B1E881 /* RKSearchWord.m */; };
25B6E9F414CF940700B1E881 /* RKSearchWord.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E614CF940600B1E881 /* RKSearchWord.m */; };
25B6E9F514CF940700B1E881 /* RKSearchWordObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E714CF940700B1E881 /* RKSearchWordObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9F614CF940700B1E881 /* RKSearchWordObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9E714CF940700B1E881 /* RKSearchWordObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9F714CF940700B1E881 /* RKSearchWordObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E814CF940700B1E881 /* RKSearchWordObserver.m */; };
25B6E9F814CF940700B1E881 /* RKSearchWordObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9E814CF940700B1E881 /* RKSearchWordObserver.m */; };
25B6E9FD14CF943E00B1E881 /* RKCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9F914CF943D00B1E881 /* RKCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9FE14CF943E00B1E881 /* RKCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9F914CF943D00B1E881 /* RKCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6E9FF14CF943E00B1E881 /* RKCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9FA14CF943E00B1E881 /* RKCache.m */; };
25B6EA0014CF943E00B1E881 /* RKCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9FA14CF943E00B1E881 /* RKCache.m */; };
25B6EA0114CF943E00B1E881 /* RKMutableBlockDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9FB14CF943E00B1E881 /* RKMutableBlockDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6EA0214CF943E00B1E881 /* RKMutableBlockDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 25B6E9FB14CF943E00B1E881 /* RKMutableBlockDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; };
25B6EA0314CF943E00B1E881 /* RKMutableBlockDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9FC14CF943E00B1E881 /* RKMutableBlockDictionary.m */; };
25B6EA0414CF943E00B1E881 /* RKMutableBlockDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B6E9FC14CF943E00B1E881 /* RKMutableBlockDictionary.m */; };
25B6EA0614CF946400B1E881 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B6EA0514CF946300B1E881 /* QuartzCore.framework */; };
25B6EA0814CF947E00B1E881 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25B6EA0714CF947D00B1E881 /* CoreGraphics.framework */; };
25C954A715542A47005C9E08 /* RKTestConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C954A415542A47005C9E08 /* RKTestConstants.m */; };
25C954A815542A47005C9E08 /* RKTestConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 25C954A415542A47005C9E08 /* RKTestConstants.m */; };
25CA7A8F14EC570200888FF8 /* RKObjectMappingDefinition.m in Sources */ = {isa = PBXBuildFile; fileRef = 25CA7A8E14EC570100888FF8 /* RKObjectMappingDefinition.m */; };
25CA7A9014EC570200888FF8 /* RKObjectMappingDefinition.m in Sources */ = {isa = PBXBuildFile; fileRef = 25CA7A8E14EC570100888FF8 /* RKObjectMappingDefinition.m */; };
25CA7A9114EC5C2D00888FF8 /* RKTestFixture.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFB2114D9B35D004863C8 /* RKTestFixture.m */; };
25CAAA9415254E7800CAE5D7 /* ArrayOfHumans.json in Resources */ = {isa = PBXBuildFile; fileRef = 25CAAA9315254E7800CAE5D7 /* ArrayOfHumans.json */; };
25CAAA9515254E7800CAE5D7 /* ArrayOfHumans.json in Resources */ = {isa = PBXBuildFile; fileRef = 25CAAA9315254E7800CAE5D7 /* ArrayOfHumans.json */; };
25DB7508151BD551009F01AF /* NSManagedObject+ActiveRecordTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25DB7507151BD551009F01AF /* NSManagedObject+ActiveRecordTest.m */; };
25DB7509151BD551009F01AF /* NSManagedObject+ActiveRecordTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25DB7507151BD551009F01AF /* NSManagedObject+ActiveRecordTest.m */; };
25E36E0215195CED00F9E448 /* RKFetchRequestMappingCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E36E0115195CED00F9E448 /* RKFetchRequestMappingCacheTest.m */; };
25E36E0315195CED00F9E448 /* RKFetchRequestMappingCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E36E0115195CED00F9E448 /* RKFetchRequestMappingCacheTest.m */; };
25E4DAB4156DA97F00A5C84B /* RKTableControllerTestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E4DAB2156DA97F00A5C84B /* RKTableControllerTestDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
25E4DAB5156DA97F00A5C84B /* RKTableControllerTestDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E4DAB2156DA97F00A5C84B /* RKTableControllerTestDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
25E4DAB6156DA97F00A5C84B /* RKTableControllerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E4DAB3156DA97F00A5C84B /* RKTableControllerTestDelegate.m */; };
25E4DAB7156DA97F00A5C84B /* RKTableControllerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E4DAB3156DA97F00A5C84B /* RKTableControllerTestDelegate.m */; };
25EC1A2C14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A2D14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1A2A14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A2E14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */; };
25EC1A2F14F6FDAD00C3CF3F /* RKObjectManager+RKTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1A2B14F6FDAC00C3CF3F /* RKObjectManager+RKTableController.m */; };
25EC1A3914F72B0900C3CF3F /* RKFetchRequestManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3814CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A3A14F72B0A00C3CF3F /* RKFetchRequestManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3814CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A3B14F72B1300C3CF3F /* RKFetchRequestManagedObjectCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7394DF3914CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.m */; };
25EC1A3C14F72B1400C3CF3F /* RKFetchRequestManagedObjectCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7394DF3914CF168C00CE7BCE /* RKFetchRequestManagedObjectCache.m */; };
25EC1A3D14F72B2800C3CF3F /* RKInMemoryManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3C14CF19F200CE7BCE /* RKInMemoryManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A3E14F72B2900C3CF3F /* RKInMemoryManagedObjectCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3C14CF19F200CE7BCE /* RKInMemoryManagedObjectCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A3F14F72B3100C3CF3F /* RKInMemoryManagedObjectCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7394DF3D14CF19F200CE7BCE /* RKInMemoryManagedObjectCache.m */; };
25EC1A4014F72B3300C3CF3F /* RKInMemoryManagedObjectCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 7394DF3D14CF19F200CE7BCE /* RKInMemoryManagedObjectCache.m */; };
25EC1A4114F72C7200C3CF3F /* RKObjectMappingProvider+CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DA8E1A14D1BA960054DD73 /* RKObjectMappingProvider+CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A4214F72C7300C3CF3F /* RKObjectMappingProvider+CoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DA8E1A14D1BA960054DD73 /* RKObjectMappingProvider+CoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A4314F72D0D00C3CF3F /* RKObjectMappingProvider+CoreData.m in Sources */ = {isa = PBXBuildFile; fileRef = 73DA8E1B14D1BA960054DD73 /* RKObjectMappingProvider+CoreData.m */; };
25EC1A4514F7393D00C3CF3F /* RKObjectMappingProviderContextEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 73DA8E2114D1C3870054DD73 /* RKObjectMappingProviderContextEntry.m */; };
25EC1A4614F7393E00C3CF3F /* RKObjectMappingProviderContextEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 73DA8E2114D1C3870054DD73 /* RKObjectMappingProviderContextEntry.m */; };
25EC1A4714F7394100C3CF3F /* RKObjectMappingProviderContextEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DA8E2014D1C3870054DD73 /* RKObjectMappingProviderContextEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A4814F7394200C3CF3F /* RKObjectMappingProviderContextEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 73DA8E2014D1C3870054DD73 /* RKObjectMappingProviderContextEntry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A6314F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3514CF157A00CE7BCE /* RKManagedObjectCaching.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1A6514F7402A00C3CF3F /* RKManagedObjectCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 7394DF3514CF157A00CE7BCE /* RKManagedObjectCaching.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1ABC14F8019F00C3CF3F /* RKRefreshGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1AB814F8019F00C3CF3F /* RKRefreshGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1ABD14F8019F00C3CF3F /* RKRefreshGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1AB814F8019F00C3CF3F /* RKRefreshGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1ABE14F8019F00C3CF3F /* RKRefreshGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1AB914F8019F00C3CF3F /* RKRefreshGestureRecognizer.m */; };
25EC1ABF14F8019F00C3CF3F /* RKRefreshGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1AB914F8019F00C3CF3F /* RKRefreshGestureRecognizer.m */; };
25EC1AC014F8019F00C3CF3F /* RKRefreshTriggerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1ABA14F8019F00C3CF3F /* RKRefreshTriggerView.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1AC114F8019F00C3CF3F /* RKRefreshTriggerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1ABA14F8019F00C3CF3F /* RKRefreshTriggerView.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1AC214F8019F00C3CF3F /* RKRefreshTriggerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1ABB14F8019F00C3CF3F /* RKRefreshTriggerView.m */; };
25EC1AC314F8019F00C3CF3F /* RKRefreshTriggerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1ABB14F8019F00C3CF3F /* RKRefreshTriggerView.m */; };
25EC1B3914F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1B3A14F84B5D00C3CF3F /* UIImage+RKAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25EC1B3714F84B5C00C3CF3F /* UIImage+RKAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
25EC1B3B14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */; };
25EC1B3C14F84B5D00C3CF3F /* UIImage+RKAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */; };
25FABED014E3796400E609E7 /* RKTestNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFAFD14D8EB30004863C8 /* RKTestNotificationObserver.m */; };
25FABED114E3796400E609E7 /* RKTestNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 252EFAFD14D8EB30004863C8 /* RKTestNotificationObserver.m */; };
25FABED214E3796B00E609E7 /* RKTestNotificationObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFAFC14D8EB30004863C8 /* RKTestNotificationObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25FABED314E3796C00E609E7 /* RKTestNotificationObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 252EFAFC14D8EB30004863C8 /* RKTestNotificationObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
25FABED614E37A2B00E609E7 /* RKTestResponseLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FABED414E37A2B00E609E7 /* RKTestResponseLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25FABED714E37A2B00E609E7 /* RKTestResponseLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FABED414E37A2B00E609E7 /* RKTestResponseLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
25FABED814E37A2B00E609E7 /* RKTestResponseLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FABED514E37A2B00E609E7 /* RKTestResponseLoader.m */; };
25FABED914E37A2B00E609E7 /* RKTestResponseLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FABED514E37A2B00E609E7 /* RKTestResponseLoader.m */; };
49A66B0C14CEFB0400A6F062 /* XMLReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A66B0914CEFB0400A6F062 /* XMLReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
49A66B0D14CEFB0400A6F062 /* XMLReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A66B0914CEFB0400A6F062 /* XMLReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
49A66B0E14CEFB0400A6F062 /* XMLReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 49A66B0A14CEFB0400A6F062 /* XMLReader.m */; };
49A66B0F14CEFB0400A6F062 /* XMLReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 49A66B0A14CEFB0400A6F062 /* XMLReader.m */; };
49A66B1214CF03CA00A6F062 /* RKXMLParserXMLReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A66B1014CF03CA00A6F062 /* RKXMLParserXMLReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
49A66B1314CF03CA00A6F062 /* RKXMLParserXMLReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A66B1014CF03CA00A6F062 /* RKXMLParserXMLReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
49A66B1414CF03CA00A6F062 /* RKXMLParserXMLReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 49A66B1114CF03CA00A6F062 /* RKXMLParserXMLReader.m */; };
49A66B1514CF03CA00A6F062 /* RKXMLParserXMLReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 49A66B1114CF03CA00A6F062 /* RKXMLParserXMLReader.m */; };
49D2759D14C9EF1E0090845D /* ISO8601DateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D2759914C9EF1E0090845D /* ISO8601DateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
49D2759E14C9EF1E0090845D /* ISO8601DateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D2759914C9EF1E0090845D /* ISO8601DateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
49D2759F14C9EF1E0090845D /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D2759A14C9EF1E0090845D /* ISO8601DateFormatter.m */; };
49D275A114C9EF1E0090845D /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D2759A14C9EF1E0090845D /* ISO8601DateFormatter.m */; };
49D275AD14C9F3020090845D /* RKISO8601DateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D275AB14C9F3020090845D /* RKISO8601DateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
49D275AE14C9F3020090845D /* RKISO8601DateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D275AB14C9F3020090845D /* RKISO8601DateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
49D275AF14C9F3020090845D /* RKISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D275AC14C9F3020090845D /* RKISO8601DateFormatter.m */; };
49D275B014C9F3020090845D /* RKISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 49D275AC14C9F3020090845D /* RKISO8601DateFormatter.m */; };
73D3907414CA1AE00093E3D6 /* parent.json in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907114CA19F90093E3D6 /* parent.json */; };
73D3907514CA1AE20093E3D6 /* parent.json in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907114CA19F90093E3D6 /* parent.json */; };
73D3907614CA1AE60093E3D6 /* child.json in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907314CA1A4A0093E3D6 /* child.json */; };
73D3907714CA1AE60093E3D6 /* child.json in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907314CA1A4A0093E3D6 /* child.json */; };
73D3907914CA1DD40093E3D6 /* channels.xml in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907814CA1D710093E3D6 /* channels.xml */; };
73D3907A14CA1DD50093E3D6 /* channels.xml in Resources */ = {isa = PBXBuildFile; fileRef = 73D3907814CA1D710093E3D6 /* channels.xml */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
25160D2C14564E820060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25160D0D14564E810060A5C5 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 25160D1514564E810060A5C5;
remoteInfo = RestKit;
};
25160E7B145651060060A5C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 25160D0D14564E810060A5C5 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 25160E61145651060060A5C5;
remoteInfo = RestKitFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
250CA67F147D8EEC0047D347 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 16;
files = (
250CA680147D8F050047D347 /* OCHamcrest.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2501405215366000004E0466 /* RKObjectiveCppTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RKObjectiveCppTest.mm; sourceTree = "
25055B8014EEF32A00B9C4DD /* RKMappingTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKMappingTest.h; path = Testing/RKMappingTest.h; sourceTree = "
25055B8114EEF32A00B9C4DD /* RKMappingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKMappingTest.m; path = Testing/RKMappingTest.m; sourceTree = "
25055B8214EEF32A00B9C4DD /* RKTestFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKTestFactory.h; path = Testing/RKTestFactory.h; sourceTree = "
25055B8314EEF32A00B9C4DD /* RKTestFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKTestFactory.m; path = Testing/RKTestFactory.m; sourceTree = "
25055B8D14EEF40000B9C4DD /* RKMappingTestExpectation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKMappingTestExpectation.h; path = Testing/RKMappingTestExpectation.h; sourceTree = "
25055B8E14EEF40000B9C4DD /* RKMappingTestExpectation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKMappingTestExpectation.m; path = Testing/RKMappingTestExpectation.m; sourceTree = "
25079C6D151B93DB00266AE7 /* NSEntityDescription+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+RKAdditions.h"; sourceTree = "
25079C6E151B93DB00266AE7 /* NSEntityDescription+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+RKAdditions.m"; sourceTree = "
25079C75151B952200266AE7 /* NSEntityDescription+RKAdditionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+RKAdditionsTest.m"; sourceTree = "
250CA67B147D8E800047D347 /* OCHamcrest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OCHamcrest.framework; sourceTree = "
250CA67C147D8E800047D347 /* OCHamcrestIOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OCHamcrestIOS.framework; sourceTree = "
250DF22814C5190E0001DEFA /* RKOrderedDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKOrderedDictionary.h; sourceTree = "
250DF22914C5190E0001DEFA /* RKOrderedDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKOrderedDictionary.m; sourceTree = "
250DF25E14C680F90001DEFA /* RKObjectMappingProvider+Contexts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RKObjectMappingProvider+Contexts.h"; sourceTree = "
25119FB5154A34B400C6BC58 /* parents_and_children.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = parents_and_children.json; sourceTree = "
2513504D14B8FE6B00A7E893 /* RKConfigurationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKConfigurationDelegate.h; sourceTree = "
25160D1614564E810060A5C5 /* libRestKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRestKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
25160D1914564E810060A5C5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
25160D2614564E820060A5C5 /* RestKitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RestKitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
25160D2714564E820060A5C5 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
25160D2914564E820060A5C5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
25160D46145650490060A5C5 /* CoreData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreData.h; sourceTree = "
25160D47145650490060A5C5 /* NSManagedObject+ActiveRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+ActiveRecord.h"; sourceTree = "
25160D48145650490060A5C5 /* NSManagedObject+ActiveRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+ActiveRecord.m"; sourceTree = "
25160D4A145650490060A5C5 /* RKManagedObjectLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectLoader.h; sourceTree = "
25160D4B145650490060A5C5 /* RKManagedObjectLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectLoader.m; sourceTree = "
25160D4C145650490060A5C5 /* RKManagedObjectMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectMapping.h; sourceTree = "
25160D4D145650490060A5C5 /* RKManagedObjectMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectMapping.m; sourceTree = "
25160D4E145650490060A5C5 /* RKManagedObjectMappingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectMappingOperation.h; sourceTree = "
25160D4F145650490060A5C5 /* RKManagedObjectMappingOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectMappingOperation.m; sourceTree = "
25160D50145650490060A5C5 /* RKManagedObjectSeeder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectSeeder.h; sourceTree = "
25160D51145650490060A5C5 /* RKManagedObjectSeeder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectSeeder.m; sourceTree = "
25160D52145650490060A5C5 /* RKManagedObjectStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectStore.h; sourceTree = "
25160D53145650490060A5C5 /* RKManagedObjectStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectStore.m; sourceTree = "
25160D54145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKManagedObjectThreadSafeInvocation.h; sourceTree = "
25160D55145650490060A5C5 /* RKManagedObjectThreadSafeInvocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectThreadSafeInvocation.m; sourceTree = "
25160D56145650490060A5C5 /* RKObjectPropertyInspector+CoreData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RKObjectPropertyInspector+CoreData.h"; sourceTree = "
25160D57145650490060A5C5 /* RKObjectPropertyInspector+CoreData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RKObjectPropertyInspector+CoreData.m"; sourceTree = "
25160D59145650490060A5C5 /* Network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Network.h; sourceTree = "
25160D5A145650490060A5C5 /* NSData+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSData+RKAdditions.h"; path = "../Network/NSData+RKAdditions.h"; sourceTree = "
25160D5B145650490060A5C5 /* NSData+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+RKAdditions.m"; path = "../Network/NSData+RKAdditions.m"; sourceTree = "
25160D5C145650490060A5C5 /* NSDictionary+RKRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+RKRequestSerialization.h"; sourceTree = "
25160D5D145650490060A5C5 /* NSDictionary+RKRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RKRequestSerialization.m"; sourceTree = "
25160D60145650490060A5C5 /* RKClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKClient.h; sourceTree = "
25160D61145650490060A5C5 /* RKClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKClient.m; sourceTree = "
25160D62145650490060A5C5 /* RKNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKNotifications.h; sourceTree = "
25160D63145650490060A5C5 /* RKNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKNotifications.m; sourceTree = "
25160D64145650490060A5C5 /* RKOAuthClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKOAuthClient.h; sourceTree = "
25160D65145650490060A5C5 /* RKOAuthClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKOAuthClient.m; sourceTree = "
25160D66145650490060A5C5 /* RKParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParams.h; sourceTree = "
25160D67145650490060A5C5 /* RKParams.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParams.m; sourceTree = "
25160D68145650490060A5C5 /* RKParamsAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParamsAttachment.h; sourceTree = "
25160D69145650490060A5C5 /* RKParamsAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsAttachment.m; sourceTree = "
25160D6A145650490060A5C5 /* RKReachabilityObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKReachabilityObserver.h; sourceTree = "
25160D6B145650490060A5C5 /* RKReachabilityObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKReachabilityObserver.m; sourceTree = "
25160D6C145650490060A5C5 /* RKRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequest.h; sourceTree = "
25160D6D145650490060A5C5 /* RKRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequest.m; sourceTree = "
25160D6E145650490060A5C5 /* RKRequest_Internals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequest_Internals.h; sourceTree = "
25160D6F145650490060A5C5 /* RKRequestCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestCache.h; sourceTree = "
25160D70145650490060A5C5 /* RKRequestCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestCache.m; sourceTree = "
25160D71145650490060A5C5 /* RKRequestQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestQueue.h; sourceTree = "
25160D72145650490060A5C5 /* RKRequestQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestQueue.m; sourceTree = "
25160D73145650490060A5C5 /* RKRequestSerializable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestSerializable.h; sourceTree = "
25160D74145650490060A5C5 /* RKRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRequestSerialization.h; sourceTree = "
25160D75145650490060A5C5 /* RKRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestSerialization.m; sourceTree = "
25160D76145650490060A5C5 /* RKResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKResponse.h; sourceTree = "
25160D77145650490060A5C5 /* RKResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKResponse.m; sourceTree = "
25160D78145650490060A5C5 /* RKURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKURL.h; sourceTree = "
25160D79145650490060A5C5 /* RKURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKURL.m; sourceTree = "
25160D7B145650490060A5C5 /* ObjectMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectMapping.h; sourceTree = "
25160D7C145650490060A5C5 /* RKDynamicObjectMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKDynamicObjectMapping.h; sourceTree = "
25160D7D145650490060A5C5 /* RKDynamicObjectMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDynamicObjectMapping.m; sourceTree = "
25160D7E145650490060A5C5 /* RKErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKErrorMessage.h; sourceTree = "
25160D7F145650490060A5C5 /* RKErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKErrorMessage.m; sourceTree = "
25160D80145650490060A5C5 /* RKMappingOperationQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappingOperationQueue.h; sourceTree = "
25160D81145650490060A5C5 /* RKMappingOperationQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappingOperationQueue.m; sourceTree = "
25160D82145650490060A5C5 /* RKObjectAttributeMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectAttributeMapping.h; sourceTree = "
25160D83145650490060A5C5 /* RKObjectAttributeMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectAttributeMapping.m; sourceTree = "
25160D84145650490060A5C5 /* RKObjectLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectLoader.h; sourceTree = "
25160D85145650490060A5C5 /* RKObjectLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectLoader.m; sourceTree = "
25160D86145650490060A5C5 /* RKObjectLoader_Internals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectLoader_Internals.h; sourceTree = "
25160D87145650490060A5C5 /* RKObjectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectManager.h; sourceTree = "
25160D88145650490060A5C5 /* RKObjectManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectManager.m; sourceTree = "
25160D89145650490060A5C5 /* RKObjectMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMapper.h; sourceTree = "
25160D8A145650490060A5C5 /* RKObjectMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMapper.m; sourceTree = "
25160D8B145650490060A5C5 /* RKObjectMapper_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMapper_Private.h; sourceTree = "
25160D8C145650490060A5C5 /* RKObjectMapperError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMapperError.h; sourceTree = "
25160D8D145650490060A5C5 /* RKObjectMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMapping.h; sourceTree = "
25160D8E145650490060A5C5 /* RKObjectMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMapping.m; sourceTree = "
25160D8F145650490060A5C5 /* RKObjectMappingDefinition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMappingDefinition.h; sourceTree = "
25160D90145650490060A5C5 /* RKObjectMappingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMappingOperation.h; sourceTree = "
25160D91145650490060A5C5 /* RKObjectMappingOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingOperation.m; sourceTree = "
25160D92145650490060A5C5 /* RKObjectMappingProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMappingProvider.h; sourceTree = "
25160D93145650490060A5C5 /* RKObjectMappingProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingProvider.m; sourceTree = "
25160D94145650490060A5C5 /* RKObjectMappingResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMappingResult.h; sourceTree = "
25160D95145650490060A5C5 /* RKObjectMappingResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingResult.m; sourceTree = "
25160D96145650490060A5C5 /* RKObjectPropertyInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectPropertyInspector.h; sourceTree = "
25160D97145650490060A5C5 /* RKObjectPropertyInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectPropertyInspector.m; sourceTree = "
25160D98145650490060A5C5 /* RKObjectRelationshipMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectRelationshipMapping.h; sourceTree = "
25160D99145650490060A5C5 /* RKObjectRelationshipMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectRelationshipMapping.m; sourceTree = "
25160D9A145650490060A5C5 /* RKObjectRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectRouter.h; sourceTree = "
25160D9B145650490060A5C5 /* RKObjectRouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectRouter.m; sourceTree = "
25160D9C145650490060A5C5 /* RKObjectSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectSerializer.h; sourceTree = "
25160D9D145650490060A5C5 /* RKObjectSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectSerializer.m; sourceTree = "
25160D9E145650490060A5C5 /* RKParserRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParserRegistry.h; sourceTree = "
25160D9F145650490060A5C5 /* RKParserRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParserRegistry.m; sourceTree = "
25160DA0145650490060A5C5 /* RKRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRouter.h; sourceTree = "
25160DA1145650490060A5C5 /* RestKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestKit.h; sourceTree = "
25160DA5145650490060A5C5 /* lcl_config_components.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_components.h; sourceTree = "
25160DA6145650490060A5C5 /* lcl_config_extensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_extensions.h; sourceTree = "
25160DA7145650490060A5C5 /* lcl_config_logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_logger.h; sourceTree = "
25160DA8145650490060A5C5 /* NSDictionary+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+RKAdditions.h"; sourceTree = "
25160DA9145650490060A5C5 /* NSDictionary+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RKAdditions.m"; sourceTree = "
25160DAA145650490060A5C5 /* NSString+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RKAdditions.h"; sourceTree = "
25160DAB145650490060A5C5 /* NSString+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RKAdditions.m"; sourceTree = "
25160DAC145650490060A5C5 /* NSURL+RKAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+RKAdditions.h"; sourceTree = "
25160DAD145650490060A5C5 /* NSURL+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+RKAdditions.m"; sourceTree = "
25160DB0145650490060A5C5 /* RKJSONParserJSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKJSONParserJSONKit.h; sourceTree = "
25160DB1145650490060A5C5 /* RKJSONParserJSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKJSONParserJSONKit.m; sourceTree = "
25160DBB145650490060A5C5 /* RestKit-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RestKit-Prefix.pch"; sourceTree = "
25160DBC145650490060A5C5 /* RKAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKAlert.h; sourceTree = "
25160DBD145650490060A5C5 /* RKAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKAlert.m; sourceTree = "
25160DBE145650490060A5C5 /* RKDotNetDateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKDotNetDateFormatter.h; sourceTree = "
25160DBF145650490060A5C5 /* RKDotNetDateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDotNetDateFormatter.m; sourceTree = "
25160DC0145650490060A5C5 /* RKFixCategoryBug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKFixCategoryBug.h; sourceTree = "
25160DC1145650490060A5C5 /* RKLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKLog.h; sourceTree = "
25160DC2145650490060A5C5 /* RKLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKLog.m; sourceTree = "
25160DC3145650490060A5C5 /* RKMIMETypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMIMETypes.h; sourceTree = "
25160DC4145650490060A5C5 /* RKMIMETypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMIMETypes.m; sourceTree = "
25160DC5145650490060A5C5 /* RKParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParser.h; sourceTree = "
25160DC6145650490060A5C5 /* RKPathMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKPathMatcher.h; sourceTree = "
25160DC7145650490060A5C5 /* RKPathMatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKPathMatcher.m; sourceTree = "
25160DC8145650490060A5C5 /* RKSearchEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKSearchEngine.h; sourceTree = "
25160DC9145650490060A5C5 /* RKSearchEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKSearchEngine.m; sourceTree = "
25160DCA145650490060A5C5 /* Support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Support.h; sourceTree = "
25160E62145651060060A5C5 /* RestKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RestKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
25160E63145651060060A5C5 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
25160E66145651060060A5C5 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
25160E67145651060060A5C5 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
25160E68145651060060A5C5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
25160E78145651060060A5C5 /* RestKitFrameworkTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RestKitFrameworkTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
25160E8F1456532C0060A5C5 /* GCOAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCOAuth.h; sourceTree = "
25160E901456532C0060A5C5 /* GCOAuth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCOAuth.m; sourceTree = "
25160E911456532C0060A5C5 /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = "
25160E921456532C0060A5C5 /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = "
25160E931456532C0060A5C5 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "
25160E951456532C0060A5C5 /* FileMD5Hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = FileMD5Hash.c; sourceTree = "
25160E961456532C0060A5C5 /* FileMD5Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMD5Hash.h; sourceTree = "
25160E971456532C0060A5C5 /* FileMD5Hash_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMD5Hash_Prefix.pch; sourceTree = "
25160E981456532C0060A5C5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "
25160E991456532C0060A5C5 /* NOTICE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NOTICE; sourceTree = "
25160E9A1456532C0060A5C5 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "
25160E9C1456532C0060A5C5 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGELOG.md; sourceTree = "
25160E9D1456532C0060A5C5 /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = "
25160E9E1456532C0060A5C5 /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = "
25160E9F1456532C0060A5C5 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "
25160EA21456532C0060A5C5 /* lcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl.h; sourceTree = "
25160EA31456532C0060A5C5 /* lcl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = lcl.m; sourceTree = "
25160EA41456532C0060A5C5 /* lcl_config_components.template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_components.template.h; sourceTree = "
25160EA51456532C0060A5C5 /* lcl_config_extensions.template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_extensions.template.h; sourceTree = "
25160EA61456532C0060A5C5 /* lcl_config_logger.template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_logger.template.h; sourceTree = "
25160EA71456532C0060A5C5 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "
25160EAF1456532C0060A5C5 /* lcl_config_logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_logger.h; sourceTree = "
25160EB01456532C0060A5C5 /* LCLNSLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LCLNSLog.h; sourceTree = "
25160EB11456532C0060A5C5 /* LCLNSLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LCLNSLog.m; sourceTree = "
25160EBD1456532C0060A5C5 /* SOCKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOCKit.h; sourceTree = "
25160EBE1456532C0060A5C5 /* SOCKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOCKit.m; sourceTree = "
25160F161456538B0060A5C5 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
25160F7B145657220060A5C5 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; };
25160F7D1456572F0060A5C5 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
25160FA0145658BC0060A5C5 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = SDKs/MacOSX10.7.sdk/usr/lib/libxml2.dylib; sourceTree = DEVELOPER_DIR; };
25160FC71456F2330060A5C5 /* RKManagedObjectLoaderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectLoaderTest.m; sourceTree = "
25160FC81456F2330060A5C5 /* RKManagedObjectMappingOperationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectMappingOperationTest.m; sourceTree = "
25160FC91456F2330060A5C5 /* RKManagedObjectMappingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectMappingTest.m; sourceTree = "
25160FCB1456F2330060A5C5 /* RKManagedObjectStoreTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectStoreTest.m; sourceTree = "
25160FCC1456F2330060A5C5 /* RKManagedObjectThreadSafeInvocationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectThreadSafeInvocationTest.m; sourceTree = "
25160FCF1456F2330060A5C5 /* blake */ = {isa = PBXFileReference; lastKnownFileType = image ; path = blake ; sourceTree = "
25160FD11456F2330060A5C5 /* ArrayOfNestedDictionaries.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ArrayOfNestedDictionaries.json; sourceTree = "
25160FD21456F2330060A5C5 /* ArrayOfResults.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ArrayOfResults.json; sourceTree = "
25160FD31456F2330060A5C5 /* ComplexNestedUser.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ComplexNestedUser.json; sourceTree = "
25160FD41456F2330060A5C5 /* ConnectingParents.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ConnectingParents.json; sourceTree = "
25160FD61456F2330060A5C5 /* boy.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = boy.json; sourceTree = "
25160FD71456F2330060A5C5 /* friends.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = friends.json; sourceTree = "
25160FD81456F2330060A5C5 /* girl.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = girl.json; sourceTree = "
25160FD91456F2330060A5C5 /* mixed.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = mixed.json; sourceTree = "
25160FDA1456F2330060A5C5 /* DynamicKeys.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = DynamicKeys.json; sourceTree = "
25160FDB1456F2330060A5C5 /* DynamicKeysWithNestedRelationship.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = DynamicKeysWithNestedRelationship.json; sourceTree = "
25160FDC1456F2330060A5C5 /* DynamicKeysWithRelationship.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = DynamicKeysWithRelationship.json; sourceTree = "
25160FDD1456F2330060A5C5 /* error.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = error.json; sourceTree = "
25160FDE1456F2330060A5C5 /* errors.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = errors.json; sourceTree = "
25160FDF1456F2330060A5C5 /* Foursquare.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Foursquare.json; sourceTree = "
25160FE11456F2330060A5C5 /* 1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = 1.json; sourceTree = "
25160FE21456F2330060A5C5 /* all.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = all.json; sourceTree = "
25160FE31456F2330060A5C5 /* with_to_one_relationship.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = with_to_one_relationship.json; sourceTree = "
25160FE41456F2330060A5C5 /* nested_user.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = nested_user.json; sourceTree = "
25160FE51456F2330060A5C5 /* RailsUser.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = RailsUser.json; sourceTree = "
25160FE61456F2330060A5C5 /* SameKeyDifferentTargetClasses.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = SameKeyDifferentTargetClasses.json; sourceTree = "
25160FE71456F2330060A5C5 /* user.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = user.json; sourceTree = "
25160FE81456F2330060A5C5 /* users.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = users.json; sourceTree = "
25160FEA1456F2330060A5C5 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = "
25160FED1456F2330060A5C5 /* attributes_without_text_content.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = attributes_without_text_content.xml; sourceTree = "
25160FEE1456F2330060A5C5 /* container_attributes.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = container_attributes.xml; sourceTree = "
25160FEF1456F2330060A5C5 /* national_weather_service.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = national_weather_service.xml; sourceTree = "
25160FF01456F2330060A5C5 /* orders.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = orders.xml; sourceTree = "
25160FF11456F2330060A5C5 /* tab_data.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = tab_data.xml; sourceTree = "
25160FF21456F2330060A5C5 /* zend.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = zend.xml; sourceTree = "
25160FF41456F2330060A5C5 /* Data Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Data Model.xcdatamodel"; sourceTree = "
25160FF51456F2330060A5C5 /* RKCat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKCat.h; sourceTree = "
25160FF61456F2330060A5C5 /* RKCat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKCat.m; sourceTree = "
25160FF71456F2330060A5C5 /* RKChild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKChild.h; sourceTree = "
25160FF81456F2330060A5C5 /* RKChild.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKChild.m; sourceTree = "
25160FF91456F2330060A5C5 /* RKDynamicMappingModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKDynamicMappingModels.h; sourceTree = "
25160FFA1456F2330060A5C5 /* RKDynamicMappingModels.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDynamicMappingModels.m; sourceTree = "
25160FFB1456F2330060A5C5 /* RKHouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKHouse.h; sourceTree = "
25160FFC1456F2330060A5C5 /* RKHouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKHouse.m; sourceTree = "
25160FFD1456F2330060A5C5 /* RKHuman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKHuman.h; sourceTree = "
25160FFE1456F2330060A5C5 /* RKHuman.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKHuman.m; sourceTree = "
25160FFF1456F2330060A5C5 /* RKMappableAssociation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappableAssociation.h; sourceTree = "
251610001456F2330060A5C5 /* RKMappableAssociation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableAssociation.m; sourceTree = "
251610011456F2330060A5C5 /* RKMappableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKMappableObject.h; sourceTree = "
251610021456F2330060A5C5 /* RKMappableObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKMappableObject.m; sourceTree = "
251610031456F2330060A5C5 /* RKObjectLoaderTestResultModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectLoaderTestResultModel.h; sourceTree = "
251610041456F2330060A5C5 /* RKObjectLoaderTestResultModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectLoaderTestResultModel.m; sourceTree = "
251610051456F2330060A5C5 /* RKObjectMapperTestModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectMapperTestModel.h; sourceTree = "
251610061456F2330060A5C5 /* RKObjectMapperTestModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMapperTestModel.m; sourceTree = "
251610071456F2330060A5C5 /* RKParent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParent.h; sourceTree = "
251610081456F2330060A5C5 /* RKParent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParent.m; sourceTree = "
251610091456F2330060A5C5 /* RKResident.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKResident.h; sourceTree = "
2516100A1456F2330060A5C5 /* RKResident.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKResident.m; sourceTree = "
251610101456F2330060A5C5 /* RKAuthenticationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKAuthenticationTest.m; sourceTree = "
251610111456F2330060A5C5 /* RKClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKClientTest.m; sourceTree = "
251610121456F2330060A5C5 /* RKOAuthClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKOAuthClientTest.m; sourceTree = "
251610131456F2330060A5C5 /* RKParamsAttachmentTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsAttachmentTest.m; sourceTree = "
251610141456F2330060A5C5 /* RKParamsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParamsTest.m; sourceTree = "
251610171456F2330060A5C5 /* RKRequestQueueTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestQueueTest.m; sourceTree = "
251610181456F2330060A5C5 /* RKRequestTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestTest.m; sourceTree = "
251610191456F2330060A5C5 /* RKResponseTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKResponseTest.m; sourceTree = "
2516101A1456F2330060A5C5 /* RKURLTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKURLTest.m; sourceTree = "
2516101C1456F2330060A5C5 /* RKDynamicObjectMappingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDynamicObjectMappingTest.m; sourceTree = "
2516101E1456F2330060A5C5 /* RKObjectLoaderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectLoaderTest.m; sourceTree = "
2516101F1456F2330060A5C5 /* RKObjectManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectManagerTest.m; sourceTree = "
251610211456F2330060A5C5 /* RKObjectMappingNextGenTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingNextGenTest.m; sourceTree = "
251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingOperationTest.m; sourceTree = "
251610231456F2330060A5C5 /* RKObjectMappingProviderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingProviderTest.m; sourceTree = "
251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingResultTest.m; sourceTree = "
251610251456F2330060A5C5 /* RKObjectRouterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectRouterTest.m; sourceTree = "
251610261456F2330060A5C5 /* RKObjectSerializerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectSerializerTest.m; sourceTree = "
251610271456F2330060A5C5 /* RKParserRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParserRegistryTest.m; sourceTree = "
251610351456F2330060A5C5 /* RKTestEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTestEnvironment.h; sourceTree = "
251610361456F2330060A5C5 /* RKTestEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTestEnvironment.m; sourceTree = "
2516104B1456F2330060A5C5 /* authentication.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = authentication.rb; sourceTree = "
2516104C1456F2330060A5C5 /* etags.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = etags.rb; sourceTree = "
2516104D1456F2330060A5C5 /* oauth2.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = oauth2.rb; sourceTree = "
2516104E1456F2330060A5C5 /* timeout.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = timeout.rb; sourceTree = "
2516104F1456F2330060A5C5 /* restkit.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = restkit.rb; sourceTree = "
251610501456F2330060A5C5 /* server.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = server.rb; sourceTree = "
251610521456F2330060A5C5 /* NSDictionary+RKRequestSerializationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RKRequestSerializationTest.m"; sourceTree = "
251610531456F2330060A5C5 /* NSStringRestKitTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringRestKitTest.m; sourceTree = "
251610541456F2330060A5C5 /* RKDotNetDateFormatterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKDotNetDateFormatterTest.m; sourceTree = "