mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-24 04:46:01 +08:00
Document RKDynamicMappingMatcher and clean up API
This commit is contained in:
@@ -33,7 +33,7 @@ typedef RKObjectMapping *(^RKDynamicMappingDelegateBlock)(id);
|
||||
///------------------------------------
|
||||
|
||||
/**
|
||||
A block to invoke to determine the appropriate concrete object mapping to apply to the mappable data.
|
||||
Sets a block to be invoked to determine the appropriate concrete object mapping with which to map an object representation.
|
||||
|
||||
@param block The block object to invoke to select the object mapping with which to map the given object representation.
|
||||
*/
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setObjectMapping:(RKObjectMapping *)objectMapping whenValueOfKeyPath:(NSString *)keyPath isEqualTo:(id)value
|
||||
- (void)setObjectMapping:(RKObjectMapping *)objectMapping whenValueOfKeyPath:(NSString *)keyPath isEqualTo:(id)expectedValue
|
||||
{
|
||||
RKLogDebug(@"Adding dynamic object mapping for key '%@' with value '%@' to destination class: %@", keyPath, value, NSStringFromClass(objectMapping.objectClass));
|
||||
RKDynamicMappingMatcher *matcher = [[RKDynamicMappingMatcher alloc] initWithKey:keyPath value:value objectMapping:objectMapping];
|
||||
RKLogDebug(@"Adding dynamic object mapping for key '%@' with value '%@' to destination class: %@", keyPath, expectedValue, NSStringFromClass(objectMapping.objectClass));
|
||||
RKDynamicMappingMatcher *matcher = [[RKDynamicMappingMatcher alloc] initWithKeyPath:keyPath expectedValue:expectedValue objectMapping:objectMapping];
|
||||
[_matchers addObject:matcher];
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@
|
||||
|
||||
// Consult the declarative matchers first
|
||||
for (RKDynamicMappingMatcher *matcher in _matchers) {
|
||||
if ([matcher isMatchForData:data]) {
|
||||
RKLogTrace(@"Found declarative match for data: %@.", [matcher matchDescription]);
|
||||
if ([matcher matches:data]) {
|
||||
RKLogTrace(@"Found declarative match for matcher: %@.", matcher);
|
||||
return matcher.objectMapping;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,59 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RKObjectMapping.h"
|
||||
|
||||
|
||||
/**
|
||||
The `RKDynamicMappingMatcher` class provides an interface for encapsulating the selection of an object mapping based on the runtime value of a property at a given key path. A matcher object is initialized with a key path, an expected value to be read from the key path, and an object mapping that is to be applied if the match evaluates to `YES`. When evaluating the match, the matcher invokes `valueForKeyPath:` on the object being matched and compares the value returned with the `expectedValue` via the `RKValueIsEqualToValue` function.
|
||||
|
||||
@see `RKValueIsEqualToValue()`
|
||||
*/
|
||||
// TODO: better name? RKKeyPathMappingMatcher | RKMappingMatcher | RKKeyPathMatcher | RKMatcher | RKValueMatcher | RKPropertyMatcher
|
||||
@interface RKDynamicMappingMatcher : NSObject
|
||||
|
||||
@property (nonatomic, strong, readonly) RKObjectMapping *objectMapping;
|
||||
@property (nonatomic, copy, readonly) NSString *primaryKeyAttribute;
|
||||
///-----------------------------
|
||||
/// @name Initializing a Matcher
|
||||
///-----------------------------
|
||||
|
||||
- (id)initWithKey:(NSString *)key value:(id)value objectMapping:(RKObjectMapping *)objectMapping;
|
||||
- (id)initWithKey:(NSString *)key value:(id)value primaryKeyAttribute:(NSString *)primaryKeyAttribute;
|
||||
- (id)initWithPrimaryKeyAttribute:(NSString *)primaryKeyAttribute evaluationBlock:(BOOL (^)(id data))block;
|
||||
- (BOOL)isMatchForData:(id)data;
|
||||
- (NSString *)matchDescription;
|
||||
/**
|
||||
Initializes the receiver with a given key path, expected value, and an object mapping that applies in the event of a positive match.
|
||||
|
||||
@param keyPath The key path to obtain the comparison value from the object being matched via `valueForKeyPath:`.
|
||||
@param expectedValue The value that is expected to be read from `keyPath` if there is a match.
|
||||
@param objectMapping The object mapping object that applies if the comparison value is equal to the expected value.
|
||||
@return The receiver, initialized with the given key path, expected value, and object mapping.
|
||||
*/
|
||||
- (id)initWithKeyPath:(NSString *)keyPath expectedValue:(id)expectedValue objectMapping:(RKObjectMapping *)objectMapping;
|
||||
|
||||
///-----------------------------
|
||||
/// @name Initializing a Matcher
|
||||
///-----------------------------
|
||||
|
||||
/**
|
||||
The key path to obtain the comparison value from the object being matched via `valueForKeyPath:`.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly) NSString *keyPath;
|
||||
|
||||
/**
|
||||
The value that is expected to be read from `keyPath` if there is a match.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) id expectedValue;
|
||||
|
||||
/**
|
||||
The object mapping object that applies if the comparison value read from `keyPath` is equal to the `expectedValue`.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) RKObjectMapping *objectMapping;
|
||||
|
||||
///-------------------------
|
||||
/// @name Evaluating a Match
|
||||
///-------------------------
|
||||
|
||||
/**
|
||||
Returns a Boolean value that indicates if the given object matches the expectations of the receiver.
|
||||
|
||||
The match is evaluated by invoking `valueForKeyPath:` on the give object with the value of the `keyPath` property and comparing the returned value with the `expectedValue` using the `RKValueIsEqualToValue` function.
|
||||
|
||||
@param object The object to be evaluated.
|
||||
@return `YES` if the object matches the expectations of the receiver, else `NO`.
|
||||
*/
|
||||
- (BOOL)matches:(id)object;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,70 +8,39 @@
|
||||
|
||||
#import "RKDynamicMappingMatcher.h"
|
||||
|
||||
|
||||
// Implemented in RKMappingOperation
|
||||
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
BOOL RKValueIsEqualToValue(id sourceValue, id destinationValue);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface RKDynamicMappingMatcher ()
|
||||
@property (nonatomic, copy) NSString *keyPath;
|
||||
@property (nonatomic, strong) id value;
|
||||
@property (nonatomic, copy) BOOL (^isMatchForDataBlock)(id data);
|
||||
@property (nonatomic, strong, readwrite) id expectedValue;
|
||||
@property (nonatomic, strong, readwrite) RKObjectMapping *objectMapping;
|
||||
@property (nonatomic, copy, readwrite) NSString *primaryKeyAttribute;
|
||||
@end
|
||||
|
||||
@implementation RKDynamicMappingMatcher
|
||||
|
||||
- (id)initWithKey:(NSString *)key value:(id)value objectMapping:(RKObjectMapping *)objectMapping
|
||||
- (id)initWithKeyPath:(NSString *)keyPath expectedValue:(id)expectedValue objectMapping:(RKObjectMapping *)objectMapping
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.keyPath = key;
|
||||
self.value = value;
|
||||
self.keyPath = keyPath;
|
||||
self.expectedValue = expectedValue;
|
||||
self.objectMapping = objectMapping;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithKey:(NSString *)key value:(id)value primaryKeyAttribute:(NSString *)primaryKeyAttribute
|
||||
- (BOOL)matches:(id)object
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.keyPath = key;
|
||||
self.value = value;
|
||||
self.primaryKeyAttribute = primaryKeyAttribute;
|
||||
}
|
||||
|
||||
return self;
|
||||
return RKValueIsEqualToValue([object valueForKeyPath:self.keyPath], self.expectedValue);
|
||||
}
|
||||
|
||||
- (id)initWithPrimaryKeyAttribute:(NSString *)primaryKeyAttribute evaluationBlock:(BOOL (^)(id data))block
|
||||
- (NSString *)description
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.primaryKeyAttribute = primaryKeyAttribute;
|
||||
self.isMatchForDataBlock = block;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isMatchForData:(id)data
|
||||
{
|
||||
if (self.isMatchForDataBlock) {
|
||||
return self.isMatchForDataBlock(data);
|
||||
}
|
||||
return RKObjectIsValueEqualToValue([data valueForKeyPath:_keyPath], _value);
|
||||
}
|
||||
|
||||
- (NSString *)matchDescription
|
||||
{
|
||||
if (self.isMatchForDataBlock) {
|
||||
return @"No description available. Using block to perform match.";
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@ == %@", _keyPath, _value];
|
||||
return [NSString stringWithFormat:@"<%@: %p when `%@` == '%@' objectMapping: %@>", NSStringFromClass([self class]), self, self.keyPath, self.expectedValue, self.objectMapping];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
#define RKLogComponent lcl_cRestKitObjectMapping
|
||||
|
||||
// Temporary home for object equivalancy tests
|
||||
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue);
|
||||
BOOL RKObjectIsValueEqualToValue(id sourceValue, id destinationValue) {
|
||||
BOOL RKValueIsEqualToValue(id sourceValue, id destinationValue);
|
||||
BOOL RKValueIsEqualToValue(id sourceValue, id destinationValue) {
|
||||
NSCAssert(sourceValue, @"Expected sourceValue not to be nil");
|
||||
NSCAssert(destinationValue, @"Expected destinationValue not to be nil");
|
||||
|
||||
@@ -213,7 +213,7 @@ extern NSString * const RKObjectMappingNestingAttributeKeyName;
|
||||
|
||||
- (BOOL)isValue:(id)sourceValue equalToValue:(id)destinationValue
|
||||
{
|
||||
return RKObjectIsValueEqualToValue(sourceValue, destinationValue);
|
||||
return RKValueIsEqualToValue(sourceValue, destinationValue);
|
||||
}
|
||||
|
||||
- (BOOL)validateValue:(id *)value atKeyPath:(NSString *)keyPath
|
||||
|
||||
Reference in New Issue
Block a user