diff --git a/Code/CoreData/RKManagedObjectStore.m b/Code/CoreData/RKManagedObjectStore.m index 3bdccefd..568ffa28 100644 --- a/Code/CoreData/RKManagedObjectStore.m +++ b/Code/CoreData/RKManagedObjectStore.m @@ -309,7 +309,10 @@ static NSString* const RKManagedObjectStoreThreadDictionaryEntityCacheKey = @"RK NSAssert(primaryKeyAttribute, @"Cannot find existing managed object instance without a primary key attribute"); NSAssert(primaryKeyValue, @"Cannot find existing managed object by primary key without a value"); NSManagedObject* object = nil; - + + // NOTE: We coerce the primary key into a string (if possible) for convenience. Generally + // primary keys are expressed either as a number of a string, so this lets us support either case interchangeably + id lookupValue = [primaryKeyValue respondsToSelector:@selector(stringValue)] ? [primaryKeyValue stringValue] : primaryKeyValue; NSArray* objects = nil; NSString* entityName = entity.name; NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary]; @@ -327,10 +330,13 @@ static NSString* const RKManagedObjectStoreThreadDictionaryEntityCacheKey = @"RK objects = [NSManagedObject executeFetchRequest:fetchRequest]; RKLogInfo(@"Caching all %d %@ objects to thread local storage", [objects count], entity.name); NSMutableDictionary* dictionary = [NSMutableDictionary dictionary]; + BOOL coerceToString = [[[objects lastObject] valueForKey:primaryKeyAttribute] respondsToSelector:@selector(stringValue)]; for (id theObject in objects) { - id primaryKeyValue = [theObject valueForKey:primaryKeyAttribute]; + id attributeValue = [theObject valueForKey:primaryKeyAttribute]; + // Coerce to a string if possible + attributeValue = coerceToString ? [attributeValue stringValue] : attributeValue; if (primaryKeyValue) { - [dictionary setObject:theObject forKey:primaryKeyValue]; + [dictionary setObject:theObject forKey:attributeValue]; } } @@ -339,7 +345,7 @@ static NSString* const RKManagedObjectStoreThreadDictionaryEntityCacheKey = @"RK NSMutableDictionary* dictionary = [entityCache objectForKey:entityName]; NSAssert1(dictionary, @"Thread local cache of %@ objects should not be nil", entityName); - object = [dictionary objectForKey:primaryKeyValue]; + object = [dictionary objectForKey:lookupValue]; if (object == nil) { object = [[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext] autorelease]; diff --git a/RestKit.xcodeproj/project.pbxproj b/RestKit.xcodeproj/project.pbxproj index 3a78d9cd..082ceac9 100644 --- a/RestKit.xcodeproj/project.pbxproj +++ b/RestKit.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ 250C296C13411E60000A3551 /* RKRequestQueueSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 250C296B13411E60000A3551 /* RKRequestQueueSpec.m */; }; 250C29FD134185D2000A3551 /* RKNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 250C29FB134185CE000A3551 /* RKNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; }; 250C29FE134185D2000A3551 /* RKNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 250C29FC134185D0000A3551 /* RKNetwork.m */; }; + 250CAF5813BF9F2D00A1330E /* RKManagedObjectStoreSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 250CAF5713BF9F2D00A1330E /* RKManagedObjectStoreSpec.m */; }; 250D5BF013A0698100471F0E /* lcl.h in Headers */ = {isa = PBXBuildFile; fileRef = 250D5BDB13A0698100471F0E /* lcl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 250D5BF113A0698100471F0E /* lcl.m in Sources */ = {isa = PBXBuildFile; fileRef = 250D5BDC13A0698100471F0E /* lcl.m */; }; 250D5BFA13A0698100471F0E /* LCLNSLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 250D5BE913A0698100471F0E /* LCLNSLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -392,6 +393,7 @@ 250C296B13411E60000A3551 /* RKRequestQueueSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRequestQueueSpec.m; sourceTree = ""; }; 250C29FB134185CE000A3551 /* RKNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKNetwork.h; sourceTree = ""; }; 250C29FC134185D0000A3551 /* RKNetwork.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKNetwork.m; sourceTree = ""; }; + 250CAF5713BF9F2D00A1330E /* RKManagedObjectStoreSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKManagedObjectStoreSpec.m; sourceTree = ""; }; 250D5BDB13A0698100471F0E /* lcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl.h; sourceTree = ""; }; 250D5BDC13A0698100471F0E /* lcl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = lcl.m; sourceTree = ""; }; 250D5BDD13A0698100471F0E /* lcl_config_components.template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_components.template.h; sourceTree = ""; }; @@ -1334,6 +1336,7 @@ 25901D7B137B695F0002ECEB /* RKManagedObjectFactorySpec.m */, 257FB68613958786003A628E /* RKManagedObjectMappingSpec.m */, 257FB70C1395DEB5003A628E /* RKManagedObjectMappingOperationSpec.m */, + 250CAF5713BF9F2D00A1330E /* RKManagedObjectStoreSpec.m */, ); path = CoreData; sourceTree = ""; @@ -2120,6 +2123,7 @@ 2515E7BD13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m in Sources */, 25ACF1AD13BB9D490067B380 /* RKURLSpec.m in Sources */, 2559209713BD1B8700E9C29C /* RKParamsSpec.m in Sources */, + 250CAF5813BF9F2D00A1330E /* RKManagedObjectStoreSpec.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme b/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme index 9f913e09..e20d4052 100644 --- a/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme +++ b/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme @@ -87,13 +87,13 @@ + value = "RKManagedObjectStoreSpec" + isEnabled = "NO"> + isEnabled = "NO">