mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-24 04:46:01 +08:00
Continued cleanup related to managed object context work
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
/**
|
||||
The Core Data entity description used for this object mapping
|
||||
*/
|
||||
@property (nonatomic, readonly) NSEntityDescription *entity;
|
||||
@property (nonatomic, retain, readonly) NSEntityDescription *entity;
|
||||
|
||||
/**
|
||||
The name of the attribute on the destination entity that acts as the primary key for instances
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
|
||||
@interface RKEntityMapping ()
|
||||
@property (nonatomic, retain, readwrite) NSEntityDescription *entity;
|
||||
@property (nonatomic, retain) NSMutableArray *mutableConnections;
|
||||
@end
|
||||
|
||||
@@ -67,8 +68,8 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
NSAssert(objectClass, @"The managedObjectClass for an object mapped entity cannot be nil.");
|
||||
self = [self init];
|
||||
if (self) {
|
||||
_objectClass = [objectClass retain];
|
||||
_entity = [entity retain];
|
||||
self.objectClass = objectClass;
|
||||
self.entity = entity;
|
||||
|
||||
[self addObserver:self forKeyPath:@"entity" options:NSKeyValueObservingOptionInitial context:nil];
|
||||
[self addObserver:self forKeyPath:@"primaryKeyAttribute" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
|
||||
@@ -159,71 +160,6 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
return [desc defaultValue];
|
||||
}
|
||||
|
||||
// TODO: Gut this method from superclass...
|
||||
- (id)mappableObjectForData:(id)mappableData
|
||||
{
|
||||
NSAssert(false, @"DISABLED!!!");
|
||||
NSAssert(mappableData, @"Mappable data cannot be nil");
|
||||
return 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];
|
||||
|
||||
@@ -96,14 +96,11 @@
|
||||
|
||||
RKManagedObjectMappingOperationDataSource *dataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:self.managedObjectContext
|
||||
cache:self.managedObjectStore.cacheStrategy];
|
||||
dataSource.operationQueue = [[NSOperationQueue new] autorelease];
|
||||
[dataSource.operationQueue setSuspended:YES];
|
||||
[dataSource.operationQueue setMaxConcurrentOperationCount:1];
|
||||
dataSource.tracksInsertedObjects = YES; // We need to be able to obtain permanent object ID's
|
||||
self.mappingOperationDataSource = dataSource;
|
||||
|
||||
// // Merge changes from the primary MOC back into our MOC
|
||||
// [[NSNotificationCenter defaultCenter] addObserver:self
|
||||
// selector:@selector(handlePrimaryManagedObjectContextDidSaveNotification:)
|
||||
// name:NSManagedObjectContextDidSaveNotification
|
||||
// object:self.managedObjectStore.primaryManagedObjectContext];
|
||||
self.mappingOperationDataSource = dataSource;
|
||||
} else if ([keyPath isEqualToString:@"targetObject"]) {
|
||||
if ([self.targetObject isKindOfClass:[NSManagedObject class]]) {
|
||||
self.targetObjectID = [(NSManagedObject *)self.targetObject objectID];
|
||||
@@ -113,16 +110,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
//- (void)handlePrimaryManagedObjectContextDidSaveNotification:(NSNotification *)notification
|
||||
//{
|
||||
// [self.managedObjectContext performBlock:^{
|
||||
// [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
|
||||
// }];
|
||||
//}
|
||||
|
||||
#pragma mark - RKObjectMapperDelegate methods
|
||||
|
||||
// TODO: Figure out how to eliminate this...
|
||||
// TODO: Figure out how to eliminate the dependence on the delegate
|
||||
|
||||
- (void)mapperDidFinishMapping:(RKObjectMapper *)mapper
|
||||
{
|
||||
if ([self.mappingOperationDataSource isKindOfClass:[RKManagedObjectMappingOperationDataSource class]]) {
|
||||
// Allow any enqueued connection operations to execute once mapping is complete
|
||||
NSOperationQueue *operationQueue = [(RKManagedObjectMappingOperationDataSource *)self.mappingOperationDataSource operationQueue];
|
||||
[operationQueue setSuspended:NO];
|
||||
[operationQueue waitUntilAllOperationsAreFinished];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mapper:(RKObjectMapper *)objectMapper didMapFromObject:(id)sourceObject toObject:(id)destinationObject atKeyPath:(NSString *)keyPath usingMapping:(RKObjectMapping *)objectMapping
|
||||
{
|
||||
if ([destinationObject isKindOfClass:[NSManagedObject class]]) {
|
||||
@@ -137,7 +138,11 @@
|
||||
{
|
||||
if ([NSThread isMainThread] == NO && _targetObjectID) {
|
||||
NSAssert(self.managedObjectContext, @"Expected managedObjectContext not to be nil.");
|
||||
return [self.managedObjectContext objectWithID:self.targetObjectID];
|
||||
__block NSManagedObject *localTargetObject;
|
||||
[self.managedObjectContext performBlockAndWait:^{
|
||||
localTargetObject = [self.managedObjectContext objectWithID:self.targetObjectID];
|
||||
}];
|
||||
return localTargetObject;
|
||||
}
|
||||
|
||||
return [super targetObject];
|
||||
@@ -153,22 +158,6 @@
|
||||
return mappingResult;
|
||||
}
|
||||
|
||||
//- (BOOL)prepareURLRequest
|
||||
//{
|
||||
// // 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]]) {
|
||||
// self.deleteObjectOnFailure = [(NSManagedObject *)self.targetObject isNew];
|
||||
// [self.objectStore save:nil];
|
||||
// self.targetObjectID = [[(NSManagedObject *)self.targetObject objectID] retain];
|
||||
// }
|
||||
//
|
||||
// return [super prepareURLRequest];
|
||||
//}
|
||||
|
||||
- (NSArray *)cachedObjects
|
||||
{
|
||||
NSFetchRequest *fetchRequest = [self.mappingProvider fetchRequestForResourcePath:self.resourcePath];
|
||||
@@ -230,7 +219,6 @@
|
||||
|
||||
[self.managedObjectContext performBlockAndWait:^{
|
||||
success = [self.managedObjectContext save:&error];
|
||||
NSLog(@"Saved MOC success = %d. Error: %@", success, error);
|
||||
}];
|
||||
if (! success) {
|
||||
RKLogError(@"Failed to save managed object context after mapping completed: %@", [error localizedDescription]);
|
||||
@@ -251,12 +239,9 @@
|
||||
NSDictionary *dictionary = [result asDictionary];
|
||||
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateOfObjectLoadWithResultDictionary:)];
|
||||
if (self.managedObjectContext.parentContext) {
|
||||
NSLog(@"Saving parent context...");
|
||||
[self.managedObjectContext.parentContext performBlockAndWait:^{
|
||||
NSError *error = nil;
|
||||
if (! [self.managedObjectContext.parentContext save:&error]) {
|
||||
NSLog(@"Failed to save parent context. Error: %@", error);
|
||||
|
||||
if ([[error domain] isEqualToString:@"NSCocoaErrorDomain"]) {
|
||||
NSDictionary *userInfo = [error userInfo];
|
||||
NSArray *errors = [userInfo valueForKey:@"NSDetailedErrors"];
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
@synthesize managedObjectCache = _managedObjectCache;
|
||||
@synthesize operationQueue = _operationQueue;
|
||||
@synthesize tracksInsertedObjects = _tracksInsertedObjects;
|
||||
@synthesize insertedObjects = _insertedObjects;
|
||||
@synthesize mutableInsertedObjects = _mutableInsertedObjects;
|
||||
|
||||
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext cache:(id<RKManagedObjectCaching>)managedObjectCache
|
||||
{
|
||||
@@ -150,10 +150,10 @@
|
||||
|
||||
- (void)commitChangesForMappingOperation:(RKMappingOperation *)mappingOperation
|
||||
{
|
||||
if ([mappingOperation.objectMapping isKindOfClass:[RKEntityMapping class]]) {
|
||||
if ([mappingOperation.mapping isKindOfClass:[RKEntityMapping class]]) {
|
||||
[self emitDeadlockWarningIfNecessary];
|
||||
|
||||
for (RKConnectionMapping *connectionMapping in [(RKEntityMapping *)mappingOperation.objectMapping connections]) {
|
||||
for (RKConnectionMapping *connectionMapping in [(RKEntityMapping *)mappingOperation.mapping connections]) {
|
||||
RKRelationshipConnectionOperation *operation = [[RKRelationshipConnectionOperation alloc] initWithManagedObject:mappingOperation.destinationObject
|
||||
connectionMapping:connectionMapping
|
||||
managedObjectCache:self.managedObjectCache];
|
||||
|
||||
@@ -65,16 +65,6 @@ typedef RKObjectMapping *(^RKDynamicMappingDelegateBlock)(id);
|
||||
*/
|
||||
+ (RKDynamicMapping *)dynamicMapping;
|
||||
|
||||
#if NS_BLOCKS_AVAILABLE
|
||||
|
||||
/**
|
||||
Return a new auto-released dynamic object mapping after yielding it to the block for configuration
|
||||
*/
|
||||
+ (RKDynamicMapping *)dynamicMappingUsingBlock:(void(^)(RKDynamicMapping *dynamicMapping))block;
|
||||
+ (RKDynamicMapping *)dynamicMappingWithBlock:(void(^)(RKDynamicMapping *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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// RKObjectMappingOperation.h
|
||||
// RKMappingOperation.h
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 4/30/11.
|
||||
@@ -21,7 +21,7 @@
|
||||
#import "RKObjectMapping.h"
|
||||
#import "RKAttributeMapping.h"
|
||||
|
||||
@class RKMappingOperation;
|
||||
@class RKMappingOperation, RKDynamicMapping;
|
||||
@protocol RKMappingOperationDataSource;
|
||||
|
||||
/**
|
||||
@@ -76,16 +76,30 @@
|
||||
- (void)mappingOperation:(RKMappingOperation *)operation didNotSetUnchangedValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKAttributeMapping *)mapping;
|
||||
|
||||
/**
|
||||
Tells the delegate that the object mapping operation has failed due to an error.
|
||||
Tells the delegate that the 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)mappingOperation:(RKMappingOperation *)operation didFailWithError:(NSError *)error;
|
||||
|
||||
/**
|
||||
Tells the delegate that the mapping operation has selected a concrete object mapping with which to map the source object.
|
||||
|
||||
Only sent if the receiver was initialized with an instance of RKDynamicMapping as the mapping.
|
||||
|
||||
@param operation The mapping operation.
|
||||
@param objectMapping The concrete object mapping with which to perform the mapping.
|
||||
@param dynamicMapping The dynamic source mapping from which the object mapping was determined.
|
||||
|
||||
@since 0.11.0
|
||||
*/
|
||||
- (void)mappingOperation:(RKMappingOperation *)operation didSelectObjectMapping:(RKObjectMapping *)objectMapping forDynamicMapping:(RKDynamicMapping *)dynamicMapping;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
Instances of RKObjectMappingOperation perform transformation between object
|
||||
Instances of RKMappingOperation 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
|
||||
@@ -97,41 +111,33 @@
|
||||
/**
|
||||
A dictionary of mappable elements containing simple values or nested object structures.
|
||||
*/
|
||||
@property (nonatomic, readonly) id sourceObject;
|
||||
@property (nonatomic, retain, 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;
|
||||
@property (nonatomic, retain, 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
|
||||
The mapping defining how values contained in the source object should be transformed to the destination object via key-value coding.
|
||||
|
||||
Will either be an instance of RKObjectMapping or RKDynamicMapping.
|
||||
*/
|
||||
@property (nonatomic, readonly) RKObjectMapping *objectMapping;
|
||||
@property (nonatomic, retain, readonly) RKMapping *mapping;
|
||||
|
||||
/**
|
||||
The delegate to inform of interesting events during the mapping operation
|
||||
*/
|
||||
@property (nonatomic, assign) id<RKMappingOperationDelegate> delegate;
|
||||
|
||||
/**
|
||||
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) NSOperationQueue *queue;
|
||||
|
||||
/**
|
||||
The data source is responsible for providing the mapping operation with an appropriate target object for
|
||||
mapping when the destination is nil.
|
||||
|
||||
@see RKMappingOperationDataSource
|
||||
*/
|
||||
@property (nonatomic, retain) id<RKMappingOperationDataSource> dataSource;
|
||||
@property (nonatomic, assign) id<RKMappingOperationDataSource> dataSource;
|
||||
|
||||
/**
|
||||
Creates and returns a new mapping operation configured to transform the object representation
|
||||
@@ -142,11 +148,11 @@
|
||||
@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 RKDynamicMapping defining how the
|
||||
@param objectOrDynamicMapping An instance of RKObjectMapping or RKDynamicMapping 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:(RKMapping *)mapping;
|
||||
+ (id)mappingOperationFromObject:(id)sourceObject toObject:(id)destinationObject withMapping:(RKMapping *)objectOrDynamicMapping;
|
||||
|
||||
/**
|
||||
Initializes the receiver with a source and destination objects and an object mapping
|
||||
@@ -155,11 +161,11 @@
|
||||
@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 RKDynamicMapping defining how the
|
||||
@param objectOrDynamicMapping An instance of RKObjectMapping or RKDynamicMapping 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:(RKMapping *)mapping;
|
||||
- (id)initWithSourceObject:(id)sourceObject destinationObject:(id)destinationObject mapping:(RKMapping *)objectOrDynamicMapping;
|
||||
|
||||
/**
|
||||
Process all mappable values from the mappable dictionary and assign them to the target object
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// RKObjectMappingOperation.m
|
||||
// RKMappingOperation.m
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 4/30/11.
|
||||
@@ -64,48 +64,40 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
|
||||
}
|
||||
|
||||
@interface RKMappingOperation ()
|
||||
@property (nonatomic, retain, readwrite) RKMapping *mapping;
|
||||
@property (nonatomic, retain, readwrite) id sourceObject;
|
||||
@property (nonatomic, retain, readwrite) id destinationObject;
|
||||
@property (nonatomic, retain) NSDictionary *nestedAttributeSubstitution;
|
||||
@property (nonatomic, retain) NSError *validationError;
|
||||
@property (nonatomic, retain) RKObjectMapping *objectMapping; // The concrete mapping
|
||||
@end
|
||||
|
||||
@implementation RKMappingOperation
|
||||
|
||||
@synthesize sourceObject = _sourceObject;
|
||||
@synthesize destinationObject = _destinationObject;
|
||||
@synthesize objectMapping = _objectMapping;
|
||||
@synthesize mapping = _mapping;
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize queue = _queue;
|
||||
@synthesize nestedAttributeSubstitution = _nestedAttributeSubstitution;
|
||||
@synthesize validationError = _validationError;
|
||||
|
||||
+ (id)mappingOperationFromObject:(id)sourceObject toObject:(id)destinationObject withMapping:(RKMapping *)objectMapping
|
||||
+ (id)mappingOperationFromObject:(id)sourceObject toObject:(id)destinationObject withMapping:(RKMapping *)objectOrDynamicMapping
|
||||
{
|
||||
// Check for availability of ManagedObjectMappingOperation. Better approach for handling?
|
||||
Class targetClass = NSClassFromString(@"RKManagedObjectMappingOperation");
|
||||
if (targetClass == nil) targetClass = [RKMappingOperation class];
|
||||
|
||||
return [[[targetClass alloc] initWithSourceObject:sourceObject destinationObject:destinationObject mapping:objectMapping] autorelease];
|
||||
return [[[self alloc] initWithSourceObject:sourceObject destinationObject:destinationObject mapping:objectOrDynamicMapping] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithSourceObject:(id)sourceObject destinationObject:(id)destinationObject mapping:(RKMapping *)objectMapping
|
||||
- (id)initWithSourceObject:(id)sourceObject destinationObject:(id)destinationObject mapping:(RKMapping *)objectOrDynamicMapping
|
||||
{
|
||||
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");
|
||||
NSAssert(objectOrDynamicMapping != nil, @"Cannot perform a mapping operation without a mapping");
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_sourceObject = [sourceObject retain];
|
||||
_destinationObject = [destinationObject retain];
|
||||
self.sourceObject = sourceObject;
|
||||
self.destinationObject = destinationObject;
|
||||
self.dataSource = [[RKObjectMappingOperationDataSource new] autorelease];
|
||||
|
||||
if ([objectMapping isKindOfClass:[RKDynamicMapping class]]) {
|
||||
_objectMapping = [[(RKDynamicMapping *)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");
|
||||
self.mapping = objectOrDynamicMapping;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -115,10 +107,8 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
|
||||
{
|
||||
[_sourceObject release];
|
||||
[_destinationObject release];
|
||||
[_objectMapping release];
|
||||
[_mapping release];
|
||||
[_nestedAttributeSubstitution release];
|
||||
[_queue release];
|
||||
self.dataSource = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -454,8 +444,8 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
|
||||
|
||||
RKLogTrace(@"Performing nested object mapping using mapping %@ for data: %@", relationshipMapping, anObject);
|
||||
RKMappingOperation *subOperation = [RKMappingOperation mappingOperationFromObject:anObject toObject:anotherObject withMapping:relationshipMapping.mapping];
|
||||
subOperation.dataSource = self.dataSource;
|
||||
subOperation.delegate = self.delegate;
|
||||
subOperation.queue = self.queue;
|
||||
if (NO == [subOperation performMapping:&error]) {
|
||||
RKLogWarning(@"WARNING: Failed mapping nested object: %@", [error localizedDescription]);
|
||||
}
|
||||
@@ -659,6 +649,19 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
|
||||
{
|
||||
RKLogDebug(@"Starting mapping operation...");
|
||||
RKLogTrace(@"Performing mapping operation: %@", self);
|
||||
|
||||
// Determine the concrete mapping if we were initialized with a dynamic mapping
|
||||
if ([self.mapping isKindOfClass:[RKDynamicMapping class]]) {
|
||||
self.objectMapping = [(RKDynamicMapping *)self.mapping objectMappingForDictionary:self.sourceObject];
|
||||
RKLogDebug(@"RKObjectMappingOperation was initialized with a dynamic mapping. Determined concrete mapping = %@", self.objectMapping);
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(mappingOperation:didSelectObjectMapping:forDynamicMapping:)]) {
|
||||
[self.delegate mappingOperation:self didSelectObjectMapping:self.objectMapping forDynamicMapping:(RKDynamicMapping *)self.mapping];
|
||||
}
|
||||
} else if ([self.mapping isKindOfClass:[RKObjectMapping class]]) {
|
||||
self.objectMapping = (RKObjectMapping *)self.mapping;
|
||||
}
|
||||
NSAssert(self.objectMapping, @"Cannot perform a mapping operation with an object mapping");
|
||||
|
||||
[self applyNestedMappings];
|
||||
BOOL mappedAttributes = [self applyAttributeMappings];
|
||||
|
||||
@@ -234,9 +234,8 @@
|
||||
NSError *error = nil;
|
||||
|
||||
RKMappingOperation *mappingOperation = [RKMappingOperation mappingOperationFromObject:mappableObject
|
||||
toObject:destinationObject
|
||||
withMapping:mapping];
|
||||
mappingOperation.queue = self.operationQueue;
|
||||
toObject:destinationObject
|
||||
withMapping:mapping];
|
||||
mappingOperation.dataSource = self.mappingOperationDataSource;
|
||||
if ([self.delegate respondsToSelector:@selector(mapper:willPerformMappingOperation:)]) {
|
||||
[self.delegate mapper:self willPerformMappingOperation:mappingOperation];
|
||||
|
||||
@@ -43,10 +43,7 @@ relationship. Relationships are processed using an object mapping as well.
|
||||
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 : RKMapping <NSCopying> {
|
||||
Class _objectClass;
|
||||
NSMutableArray *_mappings;
|
||||
}
|
||||
@interface RKObjectMapping : RKMapping <NSCopying>
|
||||
|
||||
/**
|
||||
The target class this object mapping is defining rules for
|
||||
@@ -482,14 +479,6 @@ relationship. Relationships are processed using an object mapping as well.
|
||||
*/
|
||||
- (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
|
||||
|
||||
@@ -499,14 +488,6 @@ relationship. Relationships are processed using an object mapping as well.
|
||||
*/
|
||||
- (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;
|
||||
|
||||
/**
|
||||
Returns YES if the receiever and the other mapping target the same object class
|
||||
and contain an equivalent set of attribute and relationship mappings.
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
// Constants
|
||||
NSString * const RKObjectMappingNestingAttributeKeyName = @"<RK_NESTING_ATTRIBUTE>";
|
||||
|
||||
@interface RKObjectMapping () {
|
||||
NSMutableArray *_mappings;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation RKObjectMapping
|
||||
|
||||
@synthesize objectClass = _objectClass;
|
||||
@@ -377,11 +382,6 @@ NSString * const RKObjectMappingNestingAttributeKeyName = @"<RK_NESTING_ATTRIBUT
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id)mappableObjectForData:(id)mappableData
|
||||
{
|
||||
return [[self.objectClass new] autorelease];
|
||||
}
|
||||
|
||||
- (Class)classForProperty:(NSString *)propertyName
|
||||
{
|
||||
return [[RKPropertyInspector sharedInspector] typeForProperty:propertyName ofClass:self.objectClass];
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#import "RKMappingOperation.h"
|
||||
#import "RKMappingTestExpectation.h"
|
||||
|
||||
@protocol RKMappingOperationDataSource;
|
||||
|
||||
/**
|
||||
An RKMappingTest object provides support for unit testing
|
||||
a RestKit object mapping operation by evaluation expectations
|
||||
@@ -153,6 +155,13 @@
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) RKObjectMapping *mapping;
|
||||
|
||||
/**
|
||||
A data source for the mapping operation.
|
||||
|
||||
Defaults to an instance of RKObjectMappingOperationDataSource.
|
||||
*/
|
||||
@property (nonatomic, strong) id<RKMappingOperationDataSource> mappingOperationDataSource;
|
||||
|
||||
/**
|
||||
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
|
||||
@@ -171,10 +180,10 @@
|
||||
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.
|
||||
by invoking `[self.mappingOperationDataSource objectForMappableContent:self.sourceObject mapping:self.mapping]`
|
||||
to obtain a new object from the data source and then assign the object as the value for the destinationObject property.
|
||||
|
||||
@see [RKObjectMapping mappableObjectForData:]
|
||||
@see RKMappingOperationDataSource
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) id destinationObject;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
//
|
||||
|
||||
#import "RKMappingTest.h"
|
||||
#import "RKEntityMapping.h"
|
||||
#import "RKObjectMappingOperationDataSource.h"
|
||||
|
||||
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
|
||||
@@ -44,8 +46,8 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
|
||||
@implementation RKMappingTestEvent
|
||||
|
||||
@synthesize value;
|
||||
@synthesize mapping;
|
||||
@synthesize value = _value;
|
||||
@synthesize mapping = _mapping;
|
||||
|
||||
+ (RKMappingTestEvent *)eventWithMapping:(RKAttributeMapping *)mapping value:(id)value
|
||||
{
|
||||
@@ -101,6 +103,7 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
@synthesize events = _events;
|
||||
@synthesize verifiesOnExpect = _verifiesOnExpect;
|
||||
@synthesize performedMapping = _performedMapping;
|
||||
@synthesize mappingOperationDataSource = _mappingOperationDataSource;
|
||||
|
||||
+ (RKMappingTest *)testForMapping:(RKObjectMapping *)mapping object:(id)sourceObject
|
||||
{
|
||||
@@ -119,13 +122,14 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_sourceObject = sourceObject;
|
||||
_destinationObject = destinationObject;
|
||||
_mapping = mapping;
|
||||
_expectations = [NSMutableArray new];
|
||||
_events = [NSMutableArray new];
|
||||
_verifiesOnExpect = NO;
|
||||
_performedMapping = NO;
|
||||
self.sourceObject = sourceObject;
|
||||
self.destinationObject = destinationObject;
|
||||
self.mapping = mapping;
|
||||
self.expectations = [NSMutableArray new];
|
||||
self.events = [NSMutableArray new];
|
||||
self.verifiesOnExpect = NO;
|
||||
self.performedMapping = NO;
|
||||
self.mappingOperationDataSource = [RKObjectMappingOperationDataSource new];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -224,9 +228,10 @@ BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
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];
|
||||
self.destinationObject = [self.mappingOperationDataSource objectForMappableContent:self.sourceObject mapping:self.mapping];
|
||||
}
|
||||
RKMappingOperation *mappingOperation = [RKMappingOperation mappingOperationFromObject:sourceObject toObject:self.destinationObject withMapping:self.mapping];
|
||||
mappingOperation.dataSource = self.mappingOperationDataSource;
|
||||
NSError *error = nil;
|
||||
mappingOperation.delegate = self;
|
||||
BOOL success = [mappingOperation performMapping:&error];
|
||||
|
||||
@@ -461,6 +461,31 @@ static NSString *lastUpdatedDateDictionaryKey = @"lastUpdatedDateDictionaryKey";
|
||||
|
||||
#pragma mark - UITableViewDataSource methods
|
||||
|
||||
- (UITableViewCell *)cellFromCellMapping:(RKTableViewCellMapping *)cellMapping
|
||||
{
|
||||
RKLogTrace(@"About to dequeue reusable cell using self.reuseIdentifier=%@", cellMapping.reuseIdentifier);
|
||||
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellMapping.reuseIdentifier];
|
||||
if (cell) {
|
||||
RKLogTrace(@"Dequeued existing cell object for reuse identifier '%@': %@", cellMapping.reuseIdentifier, cell);
|
||||
} else {
|
||||
cell = [[[cellMapping.objectClass alloc] initWithStyle:cellMapping.style
|
||||
reuseIdentifier:cellMapping.reuseIdentifier] autorelease];
|
||||
RKLogTrace(@"Failed to dequeue existing cell object for reuse identifier '%@', instantiated new cell: %@", cellMapping.reuseIdentifier, cell);
|
||||
}
|
||||
|
||||
if (cellMapping.managesCellAttributes) {
|
||||
cell.accessoryType = cellMapping.accessoryType;
|
||||
cell.selectionStyle = cellMapping.selectionStyle;
|
||||
}
|
||||
|
||||
// Fire the prepare callbacks
|
||||
for (void (^block)(UITableViewCell *) in cellMapping.prepareCellBlocks) {
|
||||
block(cell);
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSAssert(theTableView == self.tableView, @"tableView:cellForRowAtIndexPath: invoked with inappropriate tableView: %@", theTableView);
|
||||
@@ -471,7 +496,7 @@ static NSString *lastUpdatedDateDictionaryKey = @"lastUpdatedDateDictionaryKey";
|
||||
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];
|
||||
UITableViewCell *cell = [self cellFromCellMapping:cellMapping];
|
||||
NSAssert(cell, @"Cell mapping failed to dequeue or allocate a tableViewCell for object: %@", mappableObject);
|
||||
|
||||
// Map the object state into the cell
|
||||
@@ -1390,17 +1415,17 @@ static NSString *lastUpdatedDateDictionaryKey = @"lastUpdatedDateDictionaryKey";
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)loadTableWithObjectLoader:(RKObjectLoader *)theObjectLoader
|
||||
- (void)loadTableWithObjectLoader:(RKObjectLoader *)objectLoader
|
||||
{
|
||||
NSAssert(theObjectLoader, @"Cannot perform a network load without an object loader");
|
||||
if (! [self.objectLoader isEqual:theObjectLoader]) {
|
||||
NSAssert(objectLoader, @"Cannot perform a network load without an object loader");
|
||||
if (! [self.objectLoader isEqual:objectLoader]) {
|
||||
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;
|
||||
objectLoader.delegate = self;
|
||||
self.objectLoader = objectLoader;
|
||||
}
|
||||
if ([self.delegate respondsToSelector:@selector(tableController:willLoadTableWithObjectLoader:)]) {
|
||||
[self.delegate tableController:self willLoadTableWithObjectLoader:self.objectLoader];
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import <CoreData/CoreData.h>
|
||||
#import "RKAbstractTableController.h"
|
||||
|
||||
typedef UIView *(^RKFetchedResultsTableViewViewForHeaderInSectionBlock)(NSUInteger sectionIndex, NSString *sectionTitle);
|
||||
@@ -36,27 +37,31 @@ typedef UIView *(^RKFetchedResultsTableViewViewForHeaderInSectionBlock)(NSUInteg
|
||||
/**
|
||||
Instances of RKFetchedResultsTableController provide an interface for driving a UITableView
|
||||
*/
|
||||
@interface RKFetchedResultsTableController : RKAbstractTableController <NSFetchedResultsControllerDelegate> {
|
||||
@private
|
||||
NSArray *_arraySortedFetchedObjects;
|
||||
BOOL _isEmptyBeforeAnimation;
|
||||
}
|
||||
@interface RKFetchedResultsTableController : RKAbstractTableController <NSFetchedResultsControllerDelegate>
|
||||
|
||||
// Delegate
|
||||
@property (nonatomic, assign) id<RKFetchedResultsTableControllerDelegate> delegate;
|
||||
@property (nonatomic, retain, readonly) NSFetchedResultsController *fetchedResultsController;
|
||||
|
||||
// Fetched Results Controller
|
||||
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
|
||||
@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, retain, readonly) NSFetchedResultsController *fetchedResultsController;
|
||||
|
||||
// Configuring Headers and Sections
|
||||
@property (nonatomic, assign) CGFloat heightForHeaderInSection;
|
||||
@property (nonatomic, copy) RKFetchedResultsTableViewViewForHeaderInSectionBlock onViewForHeaderInSection;
|
||||
@property (nonatomic, assign) BOOL showsSectionIndexTitles;
|
||||
|
||||
// Sorting
|
||||
@property (nonatomic, assign) SEL sortSelector;
|
||||
@property (nonatomic, copy) NSComparator sortComparator;
|
||||
|
||||
- (void)setObjectMappingForClass:(Class)objectClass;
|
||||
- (void)setObjectMappingForClass:(Class)objectClass; // TODO: Kill this API... mapping descriptors will cover use case.
|
||||
- (void)loadTable;
|
||||
- (void)loadTableFromNetwork;
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
#define RKLogComponent lcl_cRestKitUI
|
||||
|
||||
@interface RKFetchedResultsTableController ()
|
||||
|
||||
@property (nonatomic, assign) BOOL isEmptyBeforeAnimation;
|
||||
@property (nonatomic, retain, readwrite) NSFetchedResultsController *fetchedResultsController;
|
||||
@property (nonatomic, retain) NSArray *arraySortedFetchedObjects;
|
||||
|
||||
- (BOOL)performFetch:(NSError **)error;
|
||||
- (void)updateSortedArray;
|
||||
@@ -52,6 +55,8 @@
|
||||
@synthesize sortSelector = _sortSelector;
|
||||
@synthesize sortComparator = _sortComparator;
|
||||
@synthesize fetchRequest = _fetchRequest;
|
||||
@synthesize arraySortedFetchedObjects = _arraySortedFetchedObjects;
|
||||
@synthesize isEmptyBeforeAnimation = _isEmptyBeforeAnimation;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
@@ -81,9 +86,10 @@
|
||||
|
||||
- (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];
|
||||
NSAssert(self.fetchedResultsController, @"Cannot perform a fetch: self.fetchedResultsController is nil.");
|
||||
|
||||
[NSFetchedResultsController deleteCacheWithName:self.fetchedResultsController.cacheName];
|
||||
BOOL success = [self.fetchedResultsController performFetch:error];
|
||||
if (!success) {
|
||||
RKLogError(@"performFetch failed with error: %@", [*error localizedDescription]);
|
||||
return NO;
|
||||
@@ -109,17 +115,16 @@
|
||||
|
||||
- (void)updateSortedArray
|
||||
{
|
||||
[_arraySortedFetchedObjects release];
|
||||
_arraySortedFetchedObjects = nil;
|
||||
self.arraySortedFetchedObjects = nil;
|
||||
|
||||
if (_sortSelector || _sortComparator) {
|
||||
if (_sortSelector) {
|
||||
_arraySortedFetchedObjects = [[_fetchedResultsController.fetchedObjects sortedArrayUsingSelector:_sortSelector] retain];
|
||||
} else if (_sortComparator) {
|
||||
_arraySortedFetchedObjects = [[_fetchedResultsController.fetchedObjects sortedArrayUsingComparator:_sortComparator] retain];
|
||||
if (self.sortSelector || self.sortComparator) {
|
||||
if (self.sortSelector) {
|
||||
self.arraySortedFetchedObjects = [self.fetchedResultsController.fetchedObjects sortedArrayUsingSelector:self.sortSelector];
|
||||
} else if (self.sortComparator) {
|
||||
self.arraySortedFetchedObjects = [self.fetchedResultsController.fetchedObjects sortedArrayUsingComparator:self.sortComparator];
|
||||
}
|
||||
|
||||
NSAssert(_arraySortedFetchedObjects.count == _fetchedResultsController.fetchedObjects.count,
|
||||
NSAssert(self.arraySortedFetchedObjects.count == self.fetchedResultsController.fetchedObjects.count,
|
||||
@"sortSelector or sortComparator sort resulted in fewer objects than expected");
|
||||
}
|
||||
}
|
||||
@@ -159,7 +164,7 @@
|
||||
- (BOOL)isFooterRow:(NSUInteger)row
|
||||
{
|
||||
NSUInteger sectionIndex = ([self sectionCount] - 1);
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:sectionIndex];
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:sectionIndex];
|
||||
NSUInteger nonFooterRowCount = [sectionInfo numberOfObjects];
|
||||
if (sectionIndex == 0) {
|
||||
nonFooterRowCount += (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0;
|
||||
@@ -249,30 +254,30 @@
|
||||
|
||||
- (NSFetchRequest *)fetchRequest
|
||||
{
|
||||
return _fetchRequest ? _fetchRequest : _fetchedResultsController.fetchRequest;
|
||||
return _fetchRequest ? _fetchRequest : self.fetchedResultsController.fetchRequest;
|
||||
}
|
||||
|
||||
- (void)loadTable
|
||||
{
|
||||
NSFetchRequest *fetchRequest = nil;
|
||||
if (_resourcePath) {
|
||||
if (self.resourcePath) {
|
||||
fetchRequest = [self.objectManager.mappingProvider fetchRequestForResourcePath:self.resourcePath];
|
||||
} else {
|
||||
fetchRequest = _fetchRequest;
|
||||
fetchRequest = self.fetchRequest;
|
||||
}
|
||||
NSAssert(fetchRequest != nil, @"Attempted to load RKFetchedResultsTableController with nil fetchRequest for resourcePath %@, fetchRequest %@", _resourcePath, _fetchRequest);
|
||||
|
||||
if (_predicate) {
|
||||
[fetchRequest setPredicate:_predicate];
|
||||
if (self.predicate) {
|
||||
[fetchRequest setPredicate:self.predicate];
|
||||
}
|
||||
if (_sortDescriptors) {
|
||||
[fetchRequest setSortDescriptors:_sortDescriptors];
|
||||
if (self.sortDescriptors) {
|
||||
[fetchRequest setSortDescriptors:self.sortDescriptors];
|
||||
}
|
||||
|
||||
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
|
||||
managedObjectContext:[NSManagedObjectContext contextForCurrentThread]
|
||||
sectionNameKeyPath:_sectionNameKeyPath
|
||||
cacheName:_cacheName];
|
||||
managedObjectContext:self.managedObjectContext
|
||||
sectionNameKeyPath:self.sectionNameKeyPath
|
||||
cacheName:self.cacheName];
|
||||
[self.fetchedResultsController release];
|
||||
self.fetchedResultsController.delegate = self;
|
||||
|
||||
@@ -299,17 +304,17 @@
|
||||
|
||||
- (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;
|
||||
NSAssert(self.sectionNameKeyPath == nil, @"Attempted to sort fetchedObjects across multiple sections");
|
||||
NSAssert(self.sortComparator == nil, @"Attempted to sort fetchedObjects with a sortSelector when a sortComparator already exists");
|
||||
self.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);
|
||||
NSAssert(self.sectionNameKeyPath == nil, @"Attempted to sort fetchedObjects across multiple sections");
|
||||
NSAssert(self.sortSelector == nil, @"Attempted to sort fetchedObjects with a sortComparator when a sortSelector already exists");
|
||||
if (self.sortComparator) {
|
||||
Block_release(self.sortComparator);
|
||||
_sortComparator = nil;
|
||||
}
|
||||
_sortComparator = Block_copy(sortComparator);
|
||||
@@ -317,8 +322,8 @@
|
||||
|
||||
- (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");
|
||||
NSAssert(self.sortSelector == nil, @"Attempted to create a sectioned fetchedResultsController when a sortSelector is present");
|
||||
NSAssert(self.sortComparator == nil, @"Attempted to create a sectioned fetchedResultsController when a sortComparator is present");
|
||||
[sectionNameKeyPath retain];
|
||||
[_sectionNameKeyPath release];
|
||||
_sectionNameKeyPath = sectionNameKeyPath;
|
||||
@@ -344,12 +349,12 @@
|
||||
|
||||
- (NSUInteger)sectionCount
|
||||
{
|
||||
return [[_fetchedResultsController sections] count];
|
||||
return [[self.fetchedResultsController sections] count];
|
||||
}
|
||||
|
||||
- (NSUInteger)rowCount
|
||||
{
|
||||
NSUInteger fetchedItemCount = [[_fetchedResultsController fetchedObjects] count];
|
||||
NSUInteger fetchedItemCount = [[self.fetchedResultsController fetchedObjects] count];
|
||||
NSUInteger nonFetchedItemCount = 0;
|
||||
if (fetchedItemCount == 0) {
|
||||
nonFetchedItemCount += self.emptyItem ? 1 : 0;
|
||||
@@ -365,7 +370,7 @@
|
||||
- (NSIndexPath *)indexPathForObject:(id)object
|
||||
{
|
||||
if ([object isKindOfClass:[NSManagedObject class]]) {
|
||||
return [self indexPathForFetchedResultsIndexPath:[_fetchedResultsController indexPathForObject:object]];
|
||||
return [self indexPathForFetchedResultsIndexPath:[self.fetchedResultsController indexPathForObject:object]];
|
||||
} else if ([object isKindOfClass:[RKTableItem class]]) {
|
||||
if ([object isEqual:self.emptyItem]) {
|
||||
return ([self isEmpty]) ? [self emptyItemIndexPath] : nil;
|
||||
@@ -376,7 +381,7 @@
|
||||
return [NSIndexPath indexPathForRow:row inSection:[self headerSectionIndex]];
|
||||
} else if ([self.footerItems containsObject:object]) {
|
||||
NSUInteger footerSectionIndex = [self sectionCount] - 1;
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:footerSectionIndex];
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:footerSectionIndex];
|
||||
NSUInteger numberOfFetchedResults = sectionInfo.numberOfObjects;
|
||||
NSUInteger objectIndex = [self.footerItems indexOfObject:object];
|
||||
NSUInteger row = numberOfFetchedResults + objectIndex;
|
||||
@@ -405,15 +410,15 @@
|
||||
- (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];
|
||||
RKLogTrace(@"numberOfSectionsInTableView: %d (%@)", [[self.fetchedResultsController sections] count], [[self.fetchedResultsController sections] valueForKey:@"name"]);
|
||||
return [[self.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 <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
|
||||
NSUInteger numberOfRows = [sectionInfo numberOfObjects];
|
||||
|
||||
if ([self isHeaderSection:section]) {
|
||||
@@ -450,7 +455,7 @@
|
||||
- (NSInteger)tableView:(UITableView *)theTableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
|
||||
{
|
||||
if (theTableView.style == UITableViewStylePlain && self.showsSectionIndexTitles) {
|
||||
return [_fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
|
||||
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -470,13 +475,16 @@
|
||||
[[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);
|
||||
}
|
||||
NSManagedObjectContext *managedObjectContext = managedObject.managedObjectContext;
|
||||
[managedObjectContext performBlock:^{
|
||||
[managedObjectContext deleteObject:managedObject];
|
||||
|
||||
NSError *error = nil;
|
||||
[managedObjectContext save:&error];
|
||||
if (error) {
|
||||
RKLogError(@"Failed to save managedObjectContext after a delete with error: %@", error);
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,7 +512,7 @@
|
||||
- (CGFloat)tableView:(UITableView *)theTableView heightForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
NSAssert(theTableView == self.tableView, @"heightForHeaderInSection: invoked with inappropriate tableView: %@", theTableView);
|
||||
return _heightForHeaderInSection;
|
||||
return self.heightForHeaderInSection;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)theTableView heightForFooterInSection:(NSInteger)sectionIndex
|
||||
@@ -516,10 +524,10 @@
|
||||
- (UIView *)tableView:(UITableView *)theTableView viewForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
NSAssert(theTableView == self.tableView, @"viewForHeaderInSection: invoked with inappropriate tableView: %@", theTableView);
|
||||
if (_onViewForHeaderInSection) {
|
||||
if (self.onViewForHeaderInSection) {
|
||||
NSString *sectionTitle = [self tableView:self.tableView titleForHeaderInSection:section];
|
||||
if (sectionTitle) {
|
||||
return _onViewForHeaderInSection(section, sectionTitle);
|
||||
return self.onViewForHeaderInSection(section, sectionTitle);
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
@@ -541,7 +549,7 @@
|
||||
NSUInteger row = ([self isEmpty] && self.emptyItem) ? (indexPath.row - 1) : indexPath.row;
|
||||
return [self.headerItems objectAtIndex:row];
|
||||
} else if ([self isFooterIndexPath:indexPath]) {
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:indexPath.section];
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:indexPath.section];
|
||||
NSUInteger footerRow = (indexPath.row - sectionInfo.numberOfObjects);
|
||||
if (indexPath.section == 0) {
|
||||
footerRow -= (![self isEmpty] || self.showsHeaderRowsWhenEmpty) ? [self.headerItems count] : 0;
|
||||
@@ -549,14 +557,14 @@
|
||||
}
|
||||
return [self.footerItems objectAtIndex:footerRow];
|
||||
|
||||
} else if (_sortSelector || _sortComparator) {
|
||||
return [_arraySortedFetchedObjects objectAtIndex:[self fetchedResultsIndexPathForIndexPath:indexPath].row];
|
||||
} else if (self.sortSelector || self.sortComparator) {
|
||||
return [self.arraySortedFetchedObjects objectAtIndex:[self fetchedResultsIndexPathForIndexPath:indexPath].row];
|
||||
}
|
||||
|
||||
NSIndexPath *fetchedResultsIndexPath = [self fetchedResultsIndexPathForIndexPath:indexPath];
|
||||
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:fetchedResultsIndexPath.section];
|
||||
if (fetchedResultsIndexPath.row < [sectionInfo numberOfObjects]) {
|
||||
return [_fetchedResultsController objectAtIndexPath:fetchedResultsIndexPath];
|
||||
return [self.fetchedResultsController objectAtIndexPath:fetchedResultsIndexPath];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
@@ -588,10 +596,10 @@
|
||||
{
|
||||
RKLogTrace(@"Beginning updates for fetchedResultsController (%@). Current section count = %d (resource path: %@)", controller, [[controller sections] count], _resourcePath);
|
||||
|
||||
if (_sortSelector) return;
|
||||
if (self.sortSelector) return;
|
||||
|
||||
[self.tableView beginUpdates];
|
||||
_isEmptyBeforeAnimation = [self isEmpty];
|
||||
self.isEmptyBeforeAnimation = [self isEmpty];
|
||||
}
|
||||
|
||||
- (void)controller:(NSFetchedResultsController *)controller
|
||||
@@ -682,7 +690,7 @@
|
||||
|
||||
[self updateSortedArray];
|
||||
|
||||
if (_sortSelector) {
|
||||
if (self.sortSelector) {
|
||||
[self.tableView reloadData];
|
||||
} else {
|
||||
[self.tableView endUpdates];
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import "RKFormSection.h"
|
||||
#import "NSArray+RKAdditions.h"
|
||||
#import "RKMappingOperation.h"
|
||||
#import "RKMappingOperationDataSource.h"
|
||||
|
||||
// Define logging component
|
||||
#undef RKLogComponent
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
The block will be invoked each time a cell is either initialized or dequeued for reuse.
|
||||
*/
|
||||
- (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block;
|
||||
@property (nonatomic, readonly) NSArray *prepareCellBlocks;
|
||||
|
||||
/** @name Configuring Control Actions */
|
||||
// TODO: Docs!!!
|
||||
|
||||
@@ -83,7 +83,7 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
@end
|
||||
|
||||
@interface RKTableViewCellMapping ()
|
||||
@property (nonatomic, retain) NSMutableArray *prepareCellBlocks;
|
||||
@property (nonatomic, retain) NSMutableArray *mutablePrepareCellBlocks;
|
||||
@end
|
||||
|
||||
@implementation RKTableViewCellMapping
|
||||
@@ -103,7 +103,7 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
@synthesize rowHeight = _rowHeight;
|
||||
@synthesize deselectsRowOnSelection = _deselectsRowOnSelection;
|
||||
@synthesize managesCellAttributes = _managesCellAttributes;
|
||||
@synthesize prepareCellBlocks = _prepareCellBlocks;
|
||||
@synthesize mutablePrepareCellBlocks = _mutablePrepareCellBlocks;
|
||||
|
||||
+ (id)cellMapping
|
||||
{
|
||||
@@ -142,7 +142,7 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
_selectionStyle = UITableViewCellSelectionStyleBlue;
|
||||
self.rowHeight = 44;
|
||||
self.deselectsRowOnSelection = YES;
|
||||
_prepareCellBlocks = [NSMutableArray new];
|
||||
self.mutablePrepareCellBlocks = [NSMutableArray array];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -158,7 +158,7 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
- (void)dealloc
|
||||
{
|
||||
[_reuseIdentifier release];
|
||||
[_prepareCellBlocks release];
|
||||
[_mutablePrepareCellBlocks release];
|
||||
Block_release(_onSelectCell);
|
||||
Block_release(_onSelectCellForObjectAtIndexPath);
|
||||
Block_release(_onCellWillAppearForObjectAtIndexPath);
|
||||
@@ -170,11 +170,6 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSMutableArray *)prepareCellBlocks
|
||||
{
|
||||
return _prepareCellBlocks;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
RKTableViewCellMapping *copy = [super copyWithZone:zone];
|
||||
@@ -192,8 +187,8 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
copy.targetIndexPathForMove = self.targetIndexPathForMove;
|
||||
copy.rowHeight = self.rowHeight;
|
||||
|
||||
@synchronized(_prepareCellBlocks) {
|
||||
for (void (^block)(UITableViewCell *) in _prepareCellBlocks) {
|
||||
@synchronized(_mutablePrepareCellBlocks) {
|
||||
for (void (^block)(UITableViewCell *) in _mutablePrepareCellBlocks) {
|
||||
void (^blockCopy)(UITableViewCell *cell) = [block copy];
|
||||
[copy addPrepareCellBlock:blockCopy];
|
||||
[blockCopy release];
|
||||
@@ -203,33 +198,6 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
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) {
|
||||
RKLogTrace(@"Dequeued existing cell object for reuse identifier '%@': %@", self.reuseIdentifier, cell);
|
||||
} else {
|
||||
cell = [[[self.objectClass alloc] initWithStyle:self.style
|
||||
reuseIdentifier:self.reuseIdentifier] autorelease];
|
||||
RKLogTrace(@"Failed to dequeue existing cell object for reuse identifier '%@', instantiated new cell: %@", self.reuseIdentifier, cell);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -278,10 +246,15 @@ typedef void(^RKControlBlockActionBlock)(id sender);
|
||||
- (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block
|
||||
{
|
||||
void (^blockCopy)(UITableViewCell *cell) = [block copy];
|
||||
[_prepareCellBlocks addObject:blockCopy];
|
||||
[self.mutablePrepareCellBlocks addObject:blockCopy];
|
||||
[blockCopy release];
|
||||
}
|
||||
|
||||
- (NSArray *)prepareCellBlocks
|
||||
{
|
||||
return [NSArray arrayWithArray:self.mutablePrepareCellBlocks];
|
||||
}
|
||||
|
||||
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath
|
||||
{
|
||||
[self addPrepareCellBlock:^(UITableViewCell *cell) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#import "RKTestEnvironment.h"
|
||||
#import "RKFetchedResultsTableController.h"
|
||||
#import "RKManagedObjectStore.h"
|
||||
#import "RKManagedObjectMapping.h"
|
||||
#import "RKEntityMapping.h"
|
||||
#import "RKHuman.h"
|
||||
#import "RKEvent.h"
|
||||
#import "RKAbstractTableController_Internals.h"
|
||||
@@ -39,6 +39,7 @@
|
||||
@end
|
||||
|
||||
@interface RKFetchedResultsTableControllerTest : RKTestCase
|
||||
@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext;
|
||||
@end
|
||||
|
||||
@implementation RKFetchedResultsTableControllerTest
|
||||
@@ -57,8 +58,8 @@
|
||||
|
||||
- (void)bootstrapStoreAndCache
|
||||
{
|
||||
RKManagedObjectStore *store = [RKTestFactory managedObjectStore];
|
||||
RKManagedObjectMapping *humanMapping = [RKManagedObjectMapping mappingForEntityWithName:@"RKHuman" inManagedObjectStore:store];
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
RKEntityMapping *humanMapping = [RKEntityMapping mappingForEntityWithName:@"RKHuman" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
|
||||
[humanMapping mapKeyPath:@"id" toAttribute:@"railsID"];
|
||||
[humanMapping mapAttributes:@"name", nil];
|
||||
humanMapping.primaryKeyAttribute = @"railsID";
|
||||
@@ -72,13 +73,13 @@
|
||||
other.railsID = [NSNumber numberWithInt:5678];
|
||||
other.name = @"other";
|
||||
NSError *error = nil;
|
||||
[store save:&error];
|
||||
[managedObjectStore save:&error];
|
||||
assertThat(error, is(nilValue()));
|
||||
assertThatInt([RKHuman count:nil], is(equalToInt(2)));
|
||||
|
||||
RKObjectManager *objectManager = [RKTestFactory objectManager];
|
||||
[objectManager.mappingProvider setMapping:humanMapping forKeyPath:@"human"];
|
||||
objectManager.managedObjectStore = store;
|
||||
objectManager.managedObjectStore = managedObjectStore;
|
||||
|
||||
[objectManager.mappingProvider setObjectMapping:humanMapping forResourcePathPattern:@"/JSON/humans/all\\.json" withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {
|
||||
return [RKHuman requestAllSortedBy:@"name" ascending:YES];
|
||||
@@ -89,10 +90,15 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSManagedObjectContext *)managedObjectContext
|
||||
{
|
||||
return [[RKObjectManager sharedManager].managedObjectStore mainQueueManagedObjectContext];
|
||||
}
|
||||
|
||||
- (void)bootstrapNakedObjectStoreAndCache
|
||||
{
|
||||
RKManagedObjectStore *store = [RKTestFactory managedObjectStore];
|
||||
RKManagedObjectMapping *eventMapping = [RKManagedObjectMapping mappingForClass:[RKEvent class] inManagedObjectStore:store];
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
RKEntityMapping *eventMapping = [RKEntityMapping mappingForEntityWithName:@"RKEvent" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
|
||||
[eventMapping mapKeyPath:@"event_id" toAttribute:@"eventID"];
|
||||
[eventMapping mapKeyPath:@"type" toAttribute:@"eventType"];
|
||||
[eventMapping mapAttributes:@"location", @"summary", nil];
|
||||
@@ -106,13 +112,13 @@
|
||||
nakedEvent.location = @"Performance Hall";
|
||||
nakedEvent.summary = @"Shindig";
|
||||
NSError *error = nil;
|
||||
[store save:&error];
|
||||
[managedObjectStore save:&error];
|
||||
assertThat(error, is(nilValue()));
|
||||
assertThatInt([RKEvent count:nil], is(equalToInt(1)));
|
||||
|
||||
RKObjectManager *objectManager = [RKTestFactory objectManager];
|
||||
[objectManager.mappingProvider addObjectMapping:eventMapping];
|
||||
objectManager.managedObjectStore = store;
|
||||
objectManager.managedObjectStore = managedObjectStore;
|
||||
|
||||
id mockMappingProvider = [OCMockObject partialMockForObject:objectManager.mappingProvider];
|
||||
[[[mockMappingProvider stub] andReturn:[RKEvent requestAllSortedBy:@"eventType" ascending:YES]] fetchRequestForResourcePath:@"/JSON/NakedEvents.json"];
|
||||
@@ -120,8 +126,8 @@
|
||||
|
||||
- (void)bootstrapEmptyStoreAndCache
|
||||
{
|
||||
RKManagedObjectStore *store = [RKTestFactory managedObjectStore];
|
||||
RKManagedObjectMapping *humanMapping = [RKManagedObjectMapping mappingForEntityWithName:@"RKHuman" inManagedObjectStore:store];
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
RKEntityMapping *humanMapping = [RKEntityMapping mappingForEntityWithName:@"RKHuman" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
|
||||
[humanMapping mapKeyPath:@"id" toAttribute:@"railsID"];
|
||||
[humanMapping mapAttributes:@"name", nil];
|
||||
humanMapping.primaryKeyAttribute = @"railsID";
|
||||
@@ -131,7 +137,7 @@
|
||||
|
||||
RKObjectManager *objectManager = [RKTestFactory objectManager];
|
||||
[objectManager.mappingProvider setMapping:humanMapping forKeyPath:@"human"];
|
||||
objectManager.managedObjectStore = store;
|
||||
objectManager.managedObjectStore = managedObjectStore;
|
||||
|
||||
id mockMappingProvider = [OCMockObject partialMockForObject:objectManager.mappingProvider];
|
||||
[[[mockMappingProvider stub] andReturn:[RKHuman requestAllSortedBy:@"name" ascending:YES]] fetchRequestForResourcePath:@"/JSON/humans/all.json"];
|
||||
@@ -154,6 +160,7 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -168,6 +175,7 @@
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.resourcePath = @"/JSON/NakedEvents.json";
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
[tableController setObjectMappingForClass:[RKEvent class]];
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -194,6 +202,7 @@
|
||||
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
|
||||
ascending:YES]];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.predicate = predicate;
|
||||
tableController.sortDescriptors = sortDescriptors;
|
||||
@@ -211,6 +220,7 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
tableController.cacheName = @"allHumansCache";
|
||||
@@ -231,6 +241,7 @@
|
||||
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
|
||||
ascending:YES]];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.predicate = predicate;
|
||||
tableController.sortDescriptors = sortDescriptors;
|
||||
@@ -252,9 +263,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -268,9 +279,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController loadTable];
|
||||
@@ -282,9 +293,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
assertThatInt([tableController rowCount], is(equalToInt(2)));
|
||||
@@ -298,6 +309,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -317,6 +329,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Empty";
|
||||
@@ -336,6 +349,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Empty";
|
||||
@@ -355,6 +369,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -378,6 +393,7 @@
|
||||
[self bootstrapEmptyStoreAndCache];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -401,6 +417,7 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -442,9 +459,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController loadTable];
|
||||
@@ -457,9 +474,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -471,9 +488,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController loadTable];
|
||||
@@ -486,9 +503,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -509,9 +526,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -532,6 +549,7 @@
|
||||
method:RKRequestMethodDELETE]];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController = [RKFetchedResultsTableController tableControllerForTableViewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.canEditRows = YES;
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
@@ -569,9 +587,9 @@
|
||||
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.canEditRows = YES;
|
||||
[tableController loadTable];
|
||||
@@ -607,9 +625,9 @@
|
||||
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
|
||||
@@ -640,6 +658,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.canEditRows = YES;
|
||||
[tableController loadTable];
|
||||
@@ -666,9 +685,9 @@
|
||||
[self bootstrapStoreAndCache];
|
||||
UITableView *tableView = [UITableView new];
|
||||
RKFetchedResultsTableControllerSpecViewController *viewController = [RKFetchedResultsTableControllerSpecViewController new];
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
RKFetchedResultsTableController *tableController = [[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.canMoveRows = YES;
|
||||
[tableController loadTable];
|
||||
@@ -700,6 +719,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
assertThatBool([tableController isHeaderSection:0], is(equalToBool(YES)));
|
||||
@@ -715,6 +735,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -736,6 +757,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -757,6 +779,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
@@ -779,6 +802,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -800,6 +824,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
assertThatBool([tableController isEmptySection:0], is(equalToBool(YES)));
|
||||
@@ -815,6 +840,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController loadTable];
|
||||
assertThatBool([tableController isEmptyRow:0], is(equalToBool(YES)));
|
||||
@@ -830,6 +856,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -854,6 +881,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -878,6 +906,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Empty";
|
||||
@@ -902,6 +931,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -924,6 +954,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -945,6 +976,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
@@ -968,6 +1000,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Empty";
|
||||
@@ -990,6 +1023,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1018,6 +1052,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
@@ -1048,6 +1083,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1083,6 +1119,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.sectionNameKeyPath = @"name";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
@@ -1118,6 +1155,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1145,6 +1183,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
RKTableItem *headerRow = [RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1175,6 +1214,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
RKTableItem *footerRow = [RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -1205,6 +1245,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1229,6 +1270,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Footer";
|
||||
@@ -1253,6 +1295,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1289,6 +1332,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
|
||||
RKTableItem *headerRow = [RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
@@ -1337,6 +1381,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1373,6 +1418,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
|
||||
tableItem.text = @"Header";
|
||||
@@ -1415,6 +1461,7 @@
|
||||
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
|
||||
|
||||
tableController.imageForEmpty = image;
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/empty/array";
|
||||
tableController.autoRefreshFromNetwork = YES;
|
||||
[tableController.cache invalidateAll];
|
||||
@@ -1436,6 +1483,7 @@
|
||||
RKFetchedResultsTableController *tableController =
|
||||
[[RKFetchedResultsTableController alloc] initWithTableView:tableView
|
||||
viewController:viewController];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/NakedEvents.json";
|
||||
[tableController setObjectMappingForClass:[RKEvent class]];
|
||||
|
||||
@@ -1457,6 +1505,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.cacheName = @"allHumansCache";
|
||||
|
||||
@@ -1480,6 +1529,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.cacheName = @"allHumansCache";
|
||||
|
||||
@@ -1500,6 +1550,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.cacheName = @"allHumansCache";
|
||||
|
||||
@@ -1520,6 +1571,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
tableController.cacheName = @"allHumansCache";
|
||||
|
||||
@@ -1542,6 +1594,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
|
||||
RKTableItem *headerItem = [RKTableItem tableItemWithText:@"Header"];
|
||||
@@ -1580,6 +1633,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
|
||||
RKTableItem *headerItem = [RKTableItem tableItemWithText:@"Header"];
|
||||
@@ -1617,6 +1671,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
|
||||
RKTableItem *headerItem = [RKTableItem tableItemWithText:@"Header"];
|
||||
@@ -1654,6 +1709,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/all.json";
|
||||
|
||||
RKTableItem *emptyItem = [RKTableItem tableItemWithText:@"Empty!"];
|
||||
@@ -1696,6 +1752,7 @@
|
||||
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
|
||||
[cellMapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
|
||||
[tableController mapObjectsWithClass:[RKHuman class] toTableCellsWithMapping:cellMapping];
|
||||
tableController.managedObjectContext = self.managedObjectContext;
|
||||
tableController.resourcePath = @"/JSON/humans/empty.json";
|
||||
tableController.showsFooterRowsWhenEmpty = NO;
|
||||
tableController.showsHeaderRowsWhenEmpty = NO;
|
||||
|
||||
@@ -177,9 +177,9 @@
|
||||
RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new];
|
||||
RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:objectStore.primaryManagedObjectContext
|
||||
cache:managedObjectCache];
|
||||
mappingOperationDataSource.operationQueue = [[NSOperationQueue new] autorelease];
|
||||
RKMappingOperation *operation = [[RKMappingOperation alloc] initWithSourceObject:mappableData destinationObject:human mapping:humanMapping];
|
||||
operation.dataSource = mappingOperationDataSource;
|
||||
operation.queue = [[NSOperationQueue new] autorelease];
|
||||
NSError *error = nil;
|
||||
[operation performMapping:&error];
|
||||
|
||||
@@ -751,9 +751,9 @@
|
||||
RKFetchRequestManagedObjectCache *managedObjectCache = [RKFetchRequestManagedObjectCache new];
|
||||
RKManagedObjectMappingOperationDataSource *mappingOperationDataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:objectStore.primaryManagedObjectContext
|
||||
cache:managedObjectCache];
|
||||
mappingOperationDataSource.operationQueue = [[NSOperationQueue new] autorelease];
|
||||
RKMappingOperation* operation = [[RKMappingOperation alloc] initWithSourceObject:mappableData destinationObject:human mapping:humanMapping];
|
||||
operation.dataSource = mappingOperationDataSource;
|
||||
operation.queue = [[NSOperationQueue new] autorelease];
|
||||
NSError* error = nil;
|
||||
[operation performMapping:&error];
|
||||
|
||||
|
||||
@@ -111,9 +111,9 @@
|
||||
assertThat(human.railsID, is(equalToInt(1)));
|
||||
}
|
||||
|
||||
- (void)testShouldDeleteACoreDataBackedTargetObjectOnError
|
||||
- (void)testShouldNotPersistTemporaryEntityToPersistentStoreOnError
|
||||
{
|
||||
RKHuman *temporaryHuman = [[RKHuman alloc] initWithEntity:[NSEntityDescription entityForName:@"RKHuman" inManagedObjectContext:_objectManager.managedObjectStore.primaryManagedObjectContext] insertIntoManagedObjectContext:_objectManager.managedObjectStore.primaryManagedObjectContext];
|
||||
RKHuman *temporaryHuman = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:_objectManager.managedObjectStore.primaryManagedObjectContext];
|
||||
temporaryHuman.name = @"My Name";
|
||||
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
|
||||
[mapping mapAttributes:@"name", nil];
|
||||
@@ -128,7 +128,7 @@
|
||||
[objectLoader send];
|
||||
[loader waitForResponse];
|
||||
|
||||
assertThatBool([temporaryHuman hasBeenDeleted], is(equalToBool(YES)));
|
||||
assertThatBool([temporaryHuman isNew], is(equalToBool(YES)));
|
||||
}
|
||||
|
||||
- (void)testShouldNotDeleteACoreDataBackedTargetObjectOnErrorIfItWasAlreadySaved
|
||||
|
||||
Reference in New Issue
Block a user