mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-13 09:30:46 +08:00
* Replaces primary key with `RKEntityIdentifier` * Add support for use of compound keys for object identification * Refactor `RKConnectionMapping` to `RKConnectionDescription` and add support for connecting with multiple attributes * Clarify naming of representation key methods to better match naming conventions * Add type transformation support for object identification * Greatly expand test coverage for object identification * Drop the `NSEntityDescription` category * Simplify the `RKManagedObjectCaching` protocol * Add compound key support to the Fetch Request and In Memory Cache implementations * Replace Kiwi with Specta for tests where contexts are helpful for organization * Rename `defaultValueForMissingAttribute` to `defaultValueForAttribute`
79 lines
2.9 KiB
Objective-C
79 lines
2.9 KiB
Objective-C
//
|
|
// RKFetchRequestMappingCache.m
|
|
// RestKit
|
|
//
|
|
// Created by Jeff Arena on 1/24/12.
|
|
// Copyright (c) 2009-2012 RestKit. All rights reserved.
|
|
//
|
|
|
|
#import "RKFetchRequestManagedObjectCache.h"
|
|
#import "RKLog.h"
|
|
#import "RKPropertyInspector.h"
|
|
#import "RKPropertyInspector+CoreData.h"
|
|
|
|
// Set Logging Component
|
|
#undef RKLogComponent
|
|
#define RKLogComponent RKlcl_cRestKitCoreData
|
|
|
|
static NSString *RKPredicateCacheKeyForAttributes(NSArray *attributeNames)
|
|
{
|
|
return [[attributeNames sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] componentsJoinedByString:@":"];
|
|
}
|
|
|
|
// NOTE: We build a dynamic format string here because `NSCompoundPredicate` does not support use of substiution variables
|
|
static NSPredicate *RKPredicateWithSubsitutionVariablesForAttributes(NSArray *attributeNames)
|
|
{
|
|
NSMutableArray *formatFragments = [NSMutableArray arrayWithCapacity:[attributeNames count]];
|
|
for (NSString *attributeName in attributeNames) {
|
|
NSString *formatFragment = [NSString stringWithFormat:@"%@ = $%@", attributeName, attributeName];
|
|
[formatFragments addObject:formatFragment];
|
|
}
|
|
|
|
return [NSPredicate predicateWithFormat:[formatFragments componentsJoinedByString:@" AND "]];
|
|
}
|
|
|
|
@interface RKFetchRequestManagedObjectCache ()
|
|
@property (nonatomic, strong) NSCache *predicateCache;
|
|
@end
|
|
|
|
@implementation RKFetchRequestManagedObjectCache
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
self.predicateCache = [NSCache new];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSArray *)managedObjectsWithEntity:(NSEntityDescription *)entity
|
|
attributeValues:(NSDictionary *)attributeValues
|
|
inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
|
|
{
|
|
|
|
NSAssert(entity, @"Cannot find existing managed object without a target class");
|
|
NSAssert(attributeValues, @"Cannot retrieve cached objects without attribute values to identify them with.");
|
|
NSAssert(managedObjectContext, @"Cannot find existing managed object with a nil context");
|
|
|
|
NSString *predicateCacheKey = RKPredicateCacheKeyForAttributes([attributeValues allKeys]);
|
|
NSPredicate *substitutionPredicate = [self.predicateCache objectForKey:predicateCacheKey];
|
|
if (! substitutionPredicate) {
|
|
substitutionPredicate = RKPredicateWithSubsitutionVariablesForAttributes([attributeValues allKeys]);
|
|
[self.predicateCache setObject:substitutionPredicate forKey:predicateCacheKey];
|
|
}
|
|
|
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[entity name]];
|
|
fetchRequest.predicate = [substitutionPredicate predicateWithSubstitutionVariables:attributeValues];
|
|
NSError *error = nil;
|
|
NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
|
|
if (! objects) {
|
|
RKLogError(@"Failed to execute fetch request due to error: %@", error);
|
|
}
|
|
RKLogDebug(@"Found objects '%@' using fetchRequest '%@'", objects, fetchRequest);
|
|
|
|
return objects;
|
|
}
|
|
|
|
@end
|