From 7cc4a28a799ee795702b2c3f1f1f875f60d0ced5 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:11:30 -0400 Subject: [PATCH 01/29] Adds key path mapping support --- Classes/NSManagedObject+ActiveRecord.m | 12 ++++++++++++ Classes/NSManagedObject+Mappings.h | 10 +++++++++- Classes/NSManagedObject+Mappings.m | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index f5b3b40..14bf620 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -232,6 +232,18 @@ + (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSM #endif } } + + for (NSString *attribute in [attributes allKeys]) { + NSString *keypath = [self keyPathForRemoteKey:attribute]; + + if (keypath) { + id value = [properties valueForKeyPath:keypath]; + NSString *localKey = [self keyForRemoteKey:attribute inContext:context]; + if (!value || !localKey) + continue; + transformed[localKey] = value; + } + } return transformed; } diff --git a/Classes/NSManagedObject+Mappings.h b/Classes/NSManagedObject+Mappings.h index 7ac1641..4e3e4a6 100644 --- a/Classes/NSManagedObject+Mappings.h +++ b/Classes/NSManagedObject+Mappings.h @@ -31,12 +31,20 @@ */ + (NSDictionary *)mappings; +/** + A keypath used for accessing some property value. + + @param remoteKey A remote (server) attribute name. + @return A keypath. + */ ++ (NSString *)keyPathForRemoteKey:(NSString *)key; + /** Returns a Core Data attribute name for a remote attribute name. Returns values defined in @c +mappings or, by default, converts snake case to camel case (e.g., @c @@"first_name" becomes @c @@"firstName"). @see +[NSManagedObject mappings] - @param key A remote (server) attribute name. + @param remoteKey A remote (server) attribute name. @param context A local managed object context. @return A local (Core Data) attribute name. diff --git a/Classes/NSManagedObject+Mappings.m b/Classes/NSManagedObject+Mappings.m index 52adc45..4745833 100644 --- a/Classes/NSManagedObject+Mappings.m +++ b/Classes/NSManagedObject+Mappings.m @@ -109,6 +109,10 @@ + (NSDictionary *)mappings { return nil; } ++ (NSString *)keyPathForRemoteKey:(NSString *)key { + return nil; +} + + (id)primaryKey { @throw [NSException exceptionWithName:NSStringWithFormat(@"Primary key undefined in %@", self.class) reason:NSStringWithFormat(@"You need to override %@ +primaryKey if you want to support automatic creation with only object ID", From 6d1f00c1fea1a90d2c9ff08f7c49b834e6715c6f Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:12:52 -0400 Subject: [PATCH 02/29] Adds additional attributes to Person entity from sample project --- Example/SampleProject.xcodeproj/project.pbxproj | 12 ++++++------ .../Models/Categories/Person+Mappings.m | 10 ++++++++++ Example/SampleProject/Models/Person.h | 7 ++++--- Example/SampleProject/Models/Person.m | 8 +++++--- .../SampleProject.xcdatamodel/contents | 13 +++++++------ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Example/SampleProject.xcodeproj/project.pbxproj b/Example/SampleProject.xcodeproj/project.pbxproj index e8ed60a..1138f10 100644 --- a/Example/SampleProject.xcodeproj/project.pbxproj +++ b/Example/SampleProject.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = 496F953C174CCCBA00220FD1 /* OBRPerson.m */; }; - 6433E5B9184D89EC008EF278 /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5B8184D89EC008EF278 /* Person.m */; }; + 4F5744B5194ABB0C0099A49E /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F5744B4194ABB0C0099A49E /* Person.m */; }; 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */; }; 6433E5C5184E83D6008EF278 /* Car.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C4184E83D6008EF278 /* Car.m */; }; 892C1E91165D54160077F2CB /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 892C1E90165D54160077F2CB /* Default-568h@2x.png */; }; @@ -49,8 +49,8 @@ 0EE71E2B92554B48A0914E08 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 496F953B174CCCBA00220FD1 /* OBRPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBRPerson.h; sourceTree = ""; }; 496F953C174CCCBA00220FD1 /* OBRPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBRPerson.m; sourceTree = ""; }; - 6433E5B7184D89EC008EF278 /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; - 6433E5B8184D89EC008EF278 /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; + 4F5744B3194ABB0C0099A49E /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; + 4F5744B4194ABB0C0099A49E /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsuranceCompany.h; sourceTree = ""; }; 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InsuranceCompany.m; sourceTree = ""; }; 6433E5C3184E83D6008EF278 /* Car.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Car.h; sourceTree = ""; }; @@ -119,8 +119,6 @@ 6433E5C4184E83D6008EF278 /* Car.m */, 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */, 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */, - 6433E5B7184D89EC008EF278 /* Person.h */, - 6433E5B8184D89EC008EF278 /* Person.m */, 496F953B174CCCBA00220FD1 /* OBRPerson.h */, 496F953C174CCCBA00220FD1 /* OBRPerson.m */, 897AD0C51758D99A006869BA /* Person+Mappings.h */, @@ -129,6 +127,8 @@ 897AD0C91758D9A6006869BA /* Car+Mappings.m */, FA91A5E71875B9FD00BE74DD /* InsuranceCompany+Mappings.h */, FA91A5E81875B9FD00BE74DD /* InsuranceCompany+Mappings.m */, + 4F5744B3194ABB0C0099A49E /* Person.h */, + 4F5744B4194ABB0C0099A49E /* Person.m */, ); path = Models; sourceTree = ""; @@ -382,9 +382,9 @@ files = ( 6433E5C5184E83D6008EF278 /* Car.m in Sources */, 89F1EEB615A4C73B00AE4FB4 /* main.m in Sources */, + 4F5744B5194ABB0C0099A49E /* Person.m in Sources */, 89F1EEBA15A4C73B00AE4FB4 /* AppDelegate.m in Sources */, FA91A5E91875B9FE00BE74DD /* InsuranceCompany+Mappings.m in Sources */, - 6433E5B9184D89EC008EF278 /* Person.m in Sources */, 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */, 89F1EEBD15A4C73B00AE4FB4 /* SampleProject.xcdatamodeld in Sources */, 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */, diff --git a/Example/SampleProject/Models/Categories/Person+Mappings.m b/Example/SampleProject/Models/Categories/Person+Mappings.m index f257012..dc3c826 100644 --- a/Example/SampleProject/Models/Categories/Person+Mappings.m +++ b/Example/SampleProject/Models/Categories/Person+Mappings.m @@ -24,4 +24,14 @@ + (NSDictionary *)mappings { }; } ++ (NSString *)keyPathForRemoteKey:(NSString *)key { + if ([key isEqualToString:@"role"]) { + return @"profile.role"; + } + if ([key isEqualToString:@"lifeSavings"]) { + return @"profile.life_savings"; + } + return nil; +} + @end diff --git a/Example/SampleProject/Models/Person.h b/Example/SampleProject/Models/Person.h index 9d942c3..4130ab8 100644 --- a/Example/SampleProject/Models/Person.h +++ b/Example/SampleProject/Models/Person.h @@ -2,7 +2,7 @@ // Person.h // SampleProject // -// Created by Delisa Mason on 12/27/13. +// Created by Ignacio Romero Z. on 6/13/14. // // @@ -19,11 +19,12 @@ @property (nonatomic, retain) NSNumber * isMember; @property (nonatomic, retain) NSString * lastName; @property (nonatomic, retain) NSNumber * remoteID; -@property (nonatomic, retain) NSNumber * savings; +@property (nonatomic, retain) NSNumber * lifeSavings; +@property (nonatomic, retain) NSString * role; @property (nonatomic, retain) NSSet *cars; @property (nonatomic, retain) NSSet *employees; -@property (nonatomic, retain) Person *manager; @property (nonatomic, retain) InsuranceCompany *insuranceCompany; +@property (nonatomic, retain) Person *manager; @end @interface Person (CoreDataGeneratedAccessors) diff --git a/Example/SampleProject/Models/Person.m b/Example/SampleProject/Models/Person.m index 817f6fa..fbdd8ac 100644 --- a/Example/SampleProject/Models/Person.m +++ b/Example/SampleProject/Models/Person.m @@ -2,13 +2,14 @@ // Person.m // SampleProject // -// Created by Delisa Mason on 12/27/13. +// Created by Ignacio Romero Z. on 6/13/14. // // #import "Person.h" #import "Car.h" #import "InsuranceCompany.h" +#import "Person.h" @implementation Person @@ -19,10 +20,11 @@ @implementation Person @dynamic isMember; @dynamic lastName; @dynamic remoteID; -@dynamic savings; +@dynamic lifeSavings; +@dynamic role; @dynamic cars; @dynamic employees; -@dynamic manager; @dynamic insuranceCompany; +@dynamic manager; @end diff --git a/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents b/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents index 0cc7604..e06aa4c 100644 --- a/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents +++ b/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -19,17 +19,18 @@ + - + - - - - + + + + \ No newline at end of file From e60af921582c4d5235558fea88b2a46f8a46733b Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:14:16 -0400 Subject: [PATCH 03/29] Updates test --- Example/SampleProjectTests/FindersAndCreatorsTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/SampleProjectTests/FindersAndCreatorsTests.m b/Example/SampleProjectTests/FindersAndCreatorsTests.m index 50b41fc..9a79aa3 100644 --- a/Example/SampleProjectTests/FindersAndCreatorsTests.m +++ b/Example/SampleProjectTests/FindersAndCreatorsTests.m @@ -285,7 +285,7 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext it(@"converts strings to floats", ^{ Person *person = [Person create:@{ @"savings": @"1500.12" }]; - [[person.savings should] equal:@(1500.12f)]; + [[person.lifeSavings should] equal:@(1500.12f)]; }); it(@"converts strings to dates", ^{ From 12a56be97982de95e551b320cb743deaf10d1547 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:15:08 -0400 Subject: [PATCH 04/29] Modifies sample JSON for tests --- Example/SampleProjectTests/MappingsTests.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index ed6d290..d37e18b 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -12,6 +12,10 @@ @"last_name": @"Usalj", @"age": @25, @"is_member": @"true", + @"profile": @{ + @"role": @"CEO", + @"life_savings": @203040.25, + }, @"cars": @[ @{ @"hp": @220, @"make": @"Trabant" }, @{ @"hp": @90, @"make": @"Volkswagen" } From 920e0f39d6b91791e8289b637ce96852f2c1a5a5 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:29:52 -0400 Subject: [PATCH 05/29] Adds keypath mapping test --- .../xcshareddata/xcschemes/SampleProject.xcscheme | 4 ++-- Example/SampleProjectTests/MappingsTests.m | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index f553287..aaba4ba 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index d37e18b..d778adf 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -14,7 +14,7 @@ @"is_member": @"true", @"profile": @{ @"role": @"CEO", - @"life_savings": @203040.25, + @"life_savings": @1500.12, }, @"cars": @[ @{ @"hp": @220, @"make": @"Trabant" }, @@ -111,6 +111,15 @@ Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner" : @{ @"id" : @4567, @"first_name" : @"Stan" } }}]; [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567, @"firstName": @"Stan" }]]; }); + + it(@"supports keypath nested property mappings", ^{ + Car *car = [Car createInContext:newContext]; + [[Car should] receive:@selector(mappings) withCountAtMost:1]; + [[Car should] receive:@selector(keyPathForRemoteKey:) withCountAtMost:1]; + + [car update:@{ @"first_name": @"Marin", @"last_name": @"Usalj" }]; + [car update:@{ @"profile": @{ @"role": @"CEO", @"life_savings": @1500.12 } }]; + }); }); SPEC_END From 22be2d49c1a41e636ded15fb608d1f29479a29d8 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Fri, 13 Jun 2014 01:32:19 -0400 Subject: [PATCH 06/29] Fixes last added test. Related to #97 --- Example/SampleProjectTests/MappingsTests.m | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index d778adf..8fe1f9b 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -51,6 +51,15 @@ [car update:@{ @"hp": @150 }]; }); + it(@"supports keypath nested property mappings", ^{ + Person *person = [Person createInContext:newContext]; + [[Person should] receive:@selector(mappings) withCountAtMost:1]; + [[Person should] receive:@selector(keyPathForRemoteKey:) withCountAtMost:1]; + + [person update:@{ @"first_name": @"Marin", @"last_name": @"Usalj" }]; + [person update:@{ @"profile": @{ @"role": @"CEO", @"life_savings": @1500.12 } }]; + }); + it(@"uses mapped values when creating", ^{ [[person.firstName should] equal:@"Marin"]; [[person.lastName should] equal:@"Usalj"]; @@ -111,15 +120,6 @@ Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner" : @{ @"id" : @4567, @"first_name" : @"Stan" } }}]; [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567, @"firstName": @"Stan" }]]; }); - - it(@"supports keypath nested property mappings", ^{ - Car *car = [Car createInContext:newContext]; - [[Car should] receive:@selector(mappings) withCountAtMost:1]; - [[Car should] receive:@selector(keyPathForRemoteKey:) withCountAtMost:1]; - - [car update:@{ @"first_name": @"Marin", @"last_name": @"Usalj" }]; - [car update:@{ @"profile": @{ @"role": @"CEO", @"life_savings": @1500.12 } }]; - }); }); SPEC_END From c49b4bd3dab00dfd210a8e907dec0eae08da8ad7 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Sun, 15 Jun 2014 00:34:01 -0400 Subject: [PATCH 07/29] Adds +updateOrCreate method --- Classes/NSManagedObject+ActiveRecord.h | 2 ++ Classes/NSManagedObject+ActiveRecord.m | 20 ++++++++++++++++++++ Example/.DS_Store | Bin 0 -> 6148 bytes 3 files changed, 22 insertions(+) create mode 100644 Example/.DS_Store diff --git a/Classes/NSManagedObject+ActiveRecord.h b/Classes/NSManagedObject+ActiveRecord.h index dc7b973..97c60ee 100644 --- a/Classes/NSManagedObject+ActiveRecord.h +++ b/Classes/NSManagedObject+ActiveRecord.h @@ -48,6 +48,7 @@ + (id)create; + (id)create:(NSDictionary *)attributes; ++ (instancetype)updateOrCreate:(NSDictionary *)attributes; - (void)update:(NSDictionary *)attributes; + (NSArray *)all; @@ -65,6 +66,7 @@ + (id)createInContext:(NSManagedObjectContext *)context; + (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; ++ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; + (void)deleteAllInContext:(NSManagedObjectContext *)context; diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index 14bf620..02ba8b6 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -169,6 +169,26 @@ + (id)createInContext:(NSManagedObjectContext *)context { inManagedObjectContext:context]; } ++ (instancetype)updateOrCreate:(NSDictionary *)attributes { + return [self updateOrCreate:attributes inContext:[NSManagedObjectContext defaultContext]]; +} + ++ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context { + + NSString *localKey = [[self mappings] allKeysForObject:[self primaryKey]].first; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", [self primaryKey], attributes[localKey]]; + + NSDictionary *transformed = [[self class] transformProperties:attributes withObject:nil context:context]; + NSManagedObject *existing = [self where:predicate inContext:context].first; + + if (existing) { + [existing update:transformed]; + return existing; + } + + return [self create:transformed inContext:context]; +} + - (void)update:(NSDictionary *)attributes { unless([attributes exists]) return; diff --git a/Example/.DS_Store b/Example/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..65ff425beaed81fb972c4407d43505c56426713f GIT binary patch literal 6148 zcmeH~&q~8U5XQgN9*QCqFX}B%AQZfK5JQP~AwEF0DHd%=XjAkU?>>b11U`U=BHq3E z3_gW8v%APH{bSRDh|Iw5mu_}uXMQxh2>{g^B~73KpiYgown5z#dky{OoQa#yL{taG&2UIw<;=&A5}Lxk>xrc>e4(i=t#ybbz<< zVNd(aiJfLih1q$}$waj|_|ELSv5#BIKSM%0Qf_u6zn1&Q>Ji-fo8YAg9osZTGuLPuvdTYb~0^g=)g2!U?`ygvlgSVOC&QN49g zr#}HmYc#BluKAUMeFCeY)zT>4AydYc)VM19iJ^=;jR$sKXtgwI+@bW!6vwWt>=%mC ztJ8R(r$dECr56H1z$dV7em400Kbigg?>osaAs__)6#-R?;;2O>*|T+`I6i9wYHez4 pJg+pWU8u9ivA*D=c$b Date: Sun, 15 Jun 2014 00:44:46 -0400 Subject: [PATCH 08/29] Fixes +updateOrCreate method --- Classes/NSManagedObject+ActiveRecord.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index 02ba8b6..14b4afa 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -178,15 +178,14 @@ + (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedOb NSString *localKey = [[self mappings] allKeysForObject:[self primaryKey]].first; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", [self primaryKey], attributes[localKey]]; - NSDictionary *transformed = [[self class] transformProperties:attributes withObject:nil context:context]; NSManagedObject *existing = [self where:predicate inContext:context].first; - if (existing) { - [existing update:transformed]; - return existing; + if (!existing) { + return [self create:attributes inContext:context]; } - return [self create:transformed inContext:context]; + [existing update:attributes]; + return existing; } - (void)update:(NSDictionary *)attributes { From 812b8ed19a860309864fce6e605dccaa5740c3c8 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Sun, 15 Jun 2014 01:17:44 -0400 Subject: [PATCH 09/29] Adds -saveInContext: method for custom context saving --- Classes/NSManagedObject+ActiveRecord.h | 1 + Classes/NSManagedObject+ActiveRecord.m | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Classes/NSManagedObject+ActiveRecord.h b/Classes/NSManagedObject+ActiveRecord.h index 97c60ee..5be6a30 100644 --- a/Classes/NSManagedObject+ActiveRecord.h +++ b/Classes/NSManagedObject+ActiveRecord.h @@ -68,6 +68,7 @@ + (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; + (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; +- (BOOL)saveInContext:(NSManagedObjectContext *)context; + (void)deleteAllInContext:(NSManagedObjectContext *)context; + (NSArray *)allInContext:(NSManagedObjectContext *)context; diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index 14b4afa..89c2347 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -369,17 +369,22 @@ + (NSUInteger)countForFetchWithPredicate:(NSPredicate *)predicate } - (BOOL)saveTheContext { - if (self.managedObjectContext == nil || - ![self.managedObjectContext hasChanges]) return YES; + return [self saveInContext:self.managedObjectContext]; +} +- (BOOL)saveInContext:(NSManagedObjectContext *)context +{ + if (context == nil || + ![context hasChanges]) return YES; + NSError *error = nil; - BOOL save = [self.managedObjectContext save:&error]; - + BOOL save = [context save:&error]; + if (!save || error) { NSLog(@"Unresolved error in saving context for entity:\n%@!\nError: %@", self, error); return NO; } - + return YES; } From 9afa0569462d6553224da47f762c3c16708e5e05 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Mon, 16 Jun 2014 17:22:50 -0400 Subject: [PATCH 10/29] Adds model version support --- Classes/CoreDataManager.h | 1 + Classes/CoreDataManager.m | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Classes/CoreDataManager.h b/Classes/CoreDataManager.h index 501c39f..28e86ae 100644 --- a/Classes/CoreDataManager.h +++ b/Classes/CoreDataManager.h @@ -31,6 +31,7 @@ @property (copy, nonatomic) NSString *databaseName; @property (copy, nonatomic) NSString *modelName; +@property (copy, nonatomic) NSString *modelVersion; + (id)instance DEPRECATED_ATTRIBUTE; + (instancetype)sharedManager; diff --git a/Classes/CoreDataManager.m b/Classes/CoreDataManager.m index aad793e..752ba78 100644 --- a/Classes/CoreDataManager.m +++ b/Classes/CoreDataManager.m @@ -79,8 +79,13 @@ - (NSManagedObjectContext *)managedObjectContext { - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel) return _managedObjectModel; - + NSURL *modelURL = [[NSBundle bundleForClass:[self class]] URLForResource:[self modelName] withExtension:@"momd"]; + + if ([self modelVersion]) { + modelURL = [modelURL URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.mom", [self modelVersion]]]; + } + _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } From 338970843561118fafa4b4a34f7d61737af386d7 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 18 Jun 2014 18:28:44 -0400 Subject: [PATCH 11/29] Minor refactoring --- Example/.DS_Store | Bin 6148 -> 6148 bytes .../xcschemes/SampleProject.xcscheme | 4 ++-- ObjectiveRecord.podspec | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/.DS_Store b/Example/.DS_Store index 65ff425beaed81fb972c4407d43505c56426713f..6db0121db6093b164f54b3173619d411835ee081 100644 GIT binary patch delta 48 ycmZoMXffCzz{b?eGI<`G*<=qk9;RzkC(mKCnA`_rx-o5Fm@LDtv6+YchX4S3ZVzt& delta 48 ycmZoMXffCzz{b>AGI<`G*<=qk9;PGLCeLBBnA`_rx-l(am@LDtv6+YchX4SQ4G @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> diff --git a/ObjectiveRecord.podspec b/ObjectiveRecord.podspec index 13f611d..ec9a1eb 100644 --- a/ObjectiveRecord.podspec +++ b/ObjectiveRecord.podspec @@ -1,4 +1,4 @@ -@version = "1.5.0" +@version = "1.5.3" Pod::Spec.new do |s| s.name = "ObjectiveRecord" @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { "Marin Usalj" => "mneorr@gmail.com" } - s.source = { :git => "https://github.com/supermarin/ObjectiveRecord.git", :tag => @version } + s.source = { :git => "https://github.com/DZNLabs/ObjectiveRecord.git", :tag => @version } s.source_files = 'Classes/**/*.{h,m}' s.framework = 'CoreData' From c2fd6f378d757401fcf1ca2dbe49fbba930fb5b9 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 18 Jun 2014 22:52:07 -0400 Subject: [PATCH 12/29] Adds User mapping tests --- Example/.DS_Store | Bin 6148 -> 6148 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Example/.DS_Store b/Example/.DS_Store index 6db0121db6093b164f54b3173619d411835ee081..c364970b4a11bd6ff3e2ccdd67961a8b6113af4a 100644 GIT binary patch delta 19 acmZoMXffCzz{b=!W%4{Wv&|lCdjtVOJ_e2e delta 19 acmZoMXffCzz{b?eGI<`G*=7&6J%Ru{lLh?% From b68f5ae42c0f30a5f89386c5a6ac185ee8f6a5bc Mon Sep 17 00:00:00 2001 From: dzenbot Date: Mon, 30 Jun 2014 14:28:54 -0400 Subject: [PATCH 13/29] Adds +generalChannel convenience method --- Example/.DS_Store | Bin 6148 -> 6148 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Example/.DS_Store b/Example/.DS_Store index c364970b4a11bd6ff3e2ccdd67961a8b6113af4a..f87002381f019c64cdc15cf2b41e45496da7bae2 100644 GIT binary patch delta 18 ZcmZoMXffCz$i`SQc^;eDW)HSKf&e(R1>gVx delta 18 ZcmZoMXffCz$i_Hj@;o-P%^qxf1OYkq1^@s6 From bd04135987418f16b578ad9785407ca9ef394d88 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 14:30:09 -0400 Subject: [PATCH 14/29] Deprecates all convenience methods depending on a shared managed object context. Exposed new methods passing a context as additional parameter. --- Classes/NSManagedObject+ActiveRecord.h | 41 +--- Classes/NSManagedObject+ActiveRecord.m | 189 ++++++------------ Example/Podfile | 4 +- .../xcschemes/SampleProject.xcscheme | 4 +- 4 files changed, 69 insertions(+), 169 deletions(-) diff --git a/Classes/NSManagedObject+ActiveRecord.h b/Classes/NSManagedObject+ActiveRecord.h index 5be6a30..36a45c3 100644 --- a/Classes/NSManagedObject+ActiveRecord.h +++ b/Classes/NSManagedObject+ActiveRecord.h @@ -22,53 +22,16 @@ #import #import "NSManagedObject+Mappings.h" -#import "CoreDataManager.h" - -@interface NSManagedObjectContext (ActiveRecord) - -/** - The default context (as defined on the @c CoreDataManager singleton). - - @see -[CoreDataManager managedObjectContext] - - @return A managed object context. - */ -+ (NSManagedObjectContext *)defaultContext; - -@end @interface NSManagedObject (ActiveRecord) - -#pragma mark - Default Context - -- (BOOL)save; -- (void)delete; -+ (void)deleteAll; - -+ (id)create; -+ (id)create:(NSDictionary *)attributes; -+ (instancetype)updateOrCreate:(NSDictionary *)attributes; -- (void)update:(NSDictionary *)attributes; - -+ (NSArray *)all; -+ (NSArray *)allWithOrder:(id)order; -+ (NSArray *)where:(id)condition, ...; -+ (NSArray *)where:(id)condition order:(id)order; -+ (NSArray *)where:(id)condition limit:(NSNumber *)limit; -+ (NSArray *)where:(id)condition order:(id)order limit:(NSNumber *)limit; -+ (instancetype)findOrCreate:(NSDictionary *)attributes; -+ (instancetype)find:(id)condition, ...; -+ (NSUInteger)count; -+ (NSUInteger)countWhere:(id)condition, ...; - -#pragma mark - Custom Context - + (id)createInContext:(NSManagedObjectContext *)context; + (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; + (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; +- (void)update:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; - (BOOL)saveInContext:(NSManagedObjectContext *)context; +- (void)deleteInContext:(NSManagedObjectContext *)contex; + (void)deleteAllInContext:(NSManagedObjectContext *)context; + (NSArray *)allInContext:(NSManagedObjectContext *)context; diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index 89c2347..b7e2c73 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -23,14 +23,6 @@ #import "NSManagedObject+ActiveRecord.h" #import "ObjectiveSugar.h" -@implementation NSManagedObjectContext (ActiveRecord) - -+ (NSManagedObjectContext *)defaultContext { - return [[CoreDataManager sharedManager] managedObjectContext]; -} - -@end - @implementation NSObject(null) - (BOOL)exists { @@ -43,26 +35,16 @@ @implementation NSManagedObject (ActiveRecord) #pragma mark - Finders -+ (NSArray *)all { - return [self allInContext:[NSManagedObjectContext defaultContext]]; -} - -+ (NSArray *)allWithOrder:(id)order { - return [self allInContext:[NSManagedObjectContext defaultContext] order:order]; -} - -+ (NSArray *)allInContext:(NSManagedObjectContext *)context { ++ (NSArray *)allInContext:(NSManagedObjectContext *)context +{ return [self allInContext:context order:nil]; } -+ (NSArray *)allInContext:(NSManagedObjectContext *)context order:(id)order { ++ (NSArray *)allInContext:(NSManagedObjectContext *)context order:(id)order +{ return [self fetchWithCondition:nil inContext:context withOrder:order fetchLimit:nil]; } -+ (instancetype)findOrCreate:(NSDictionary *)properties { - return [self findOrCreate:properties inContext:[NSManagedObjectContext defaultContext]]; -} - + (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context { NSDictionary *transformed = [[self class] transformProperties:properties withObject:nil context:context]; @@ -70,40 +52,11 @@ + (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObje return existing ?: [self create:transformed inContext:context]; } -+ (instancetype)find:(id)condition, ... { - va_list va_arguments; - va_start(va_arguments, condition); - NSPredicate *predicate = [self predicateFromObject:condition arguments:va_arguments]; - va_end(va_arguments); - - return [self find:predicate inContext:[NSManagedObjectContext defaultContext]]; -} - -+ (instancetype)find:(id)condition inContext:(NSManagedObjectContext *)context { ++ (instancetype)find:(id)condition inContext:(NSManagedObjectContext *)context +{ return [self where:condition inContext:context limit:@1].first; } -+ (NSArray *)where:(id)condition, ... { - va_list va_arguments; - va_start(va_arguments, condition); - NSPredicate *predicate = [self predicateFromObject:condition arguments:va_arguments]; - va_end(va_arguments); - - return [self where:predicate inContext:[NSManagedObjectContext defaultContext]]; -} - -+ (NSArray *)where:(id)condition order:(id)order { - return [self where:condition inContext:[NSManagedObjectContext defaultContext] order:order]; -} - -+ (NSArray *)where:(id)condition limit:(NSNumber *)limit { - return [self where:condition inContext:[NSManagedObjectContext defaultContext] limit:limit]; -} - -+ (NSArray *)where:(id)condition order:(id)order limit:(NSNumber *)limit { - return [self where:condition inContext:[NSManagedObjectContext defaultContext] order:order limit:limit]; -} - + (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context { return [self where:condition inContext:context order:nil limit:nil]; } @@ -122,24 +75,13 @@ + (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context ord #pragma mark - Aggregation -+ (NSUInteger)count { - return [self countInContext:[NSManagedObjectContext defaultContext]]; -} - -+ (NSUInteger)countWhere:(id)condition, ... { - va_list va_arguments; - va_start(va_arguments, condition); - NSPredicate *predicate = [self predicateFromObject:condition arguments:va_arguments]; - va_end(va_arguments); - - return [self countWhere:predicate inContext:[NSManagedObjectContext defaultContext]]; -} - -+ (NSUInteger)countInContext:(NSManagedObjectContext *)context { ++ (NSUInteger)countInContext:(NSManagedObjectContext *)context +{ return [self countForFetchWithPredicate:nil inContext:context]; } -+ (NSUInteger)countWhere:(id)condition inContext:(NSManagedObjectContext *)context { ++ (NSUInteger)countWhere:(id)condition inContext:(NSManagedObjectContext *)context +{ NSPredicate *predicate = [self predicateFromObject:condition]; return [self countForFetchWithPredicate:predicate inContext:context]; @@ -147,34 +89,23 @@ + (NSUInteger)countWhere:(id)condition inContext:(NSManagedObjectContext *)conte #pragma mark - Creation / Deletion -+ (id)create { - return [self createInContext:[NSManagedObjectContext defaultContext]]; -} - -+ (id)create:(NSDictionary *)attributes { - return [self create:attributes inContext:[NSManagedObjectContext defaultContext]]; -} - -+ (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context { ++ (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context +{ unless([attributes exists]) return nil; NSManagedObject *newEntity = [self createInContext:context]; - [newEntity update:attributes]; + [newEntity update:attributes inContext:context]; return newEntity; } -+ (id)createInContext:(NSManagedObjectContext *)context { - return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] - inManagedObjectContext:context]; -} - -+ (instancetype)updateOrCreate:(NSDictionary *)attributes { - return [self updateOrCreate:attributes inContext:[NSManagedObjectContext defaultContext]]; ++ (id)createInContext:(NSManagedObjectContext *)context +{ + return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:context]; } -+ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context { - ++ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context +{ NSString *localKey = [[self mappings] allKeysForObject:[self primaryKey]].first; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", [self primaryKey], attributes[localKey]]; @@ -184,49 +115,53 @@ + (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedOb return [self create:attributes inContext:context]; } - [existing update:attributes]; + [existing update:attributes inContext:context]; + return existing; } -- (void)update:(NSDictionary *)attributes { +- (void)update:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context +{ unless([attributes exists]) return; - NSDictionary *transformed = [[self class] transformProperties:attributes withObject:self context:self.managedObjectContext]; + NSDictionary *transformed = [[self class] transformProperties:attributes withObject:self context:context]; - for (NSString *key in transformed) [self willChangeValueForKey:key]; + for (NSString *key in transformed) { + [self willChangeValueForKey:key]; + } + [transformed each:^(NSString *key, id value) { [self setSafeValue:value forKey:key]; }]; - for (NSString *key in transformed) [self didChangeValueForKey:key]; -} - -- (BOOL)save { - return [self saveTheContext]; -} - -- (void)delete { - [self.managedObjectContext deleteObject:self]; + + for (NSString *key in transformed) { + [self didChangeValueForKey:key]; + } } -+ (void)deleteAll { - [self deleteAllInContext:[NSManagedObjectContext defaultContext]]; +- (void)deleteInContext:(NSManagedObjectContext *)context +{ + [context deleteObject:self]; } -+ (void)deleteAllInContext:(NSManagedObjectContext *)context { ++ (void)deleteAllInContext:(NSManagedObjectContext *)context +{ [[self allInContext:context] each:^(id object) { - [object delete]; + [object deleteInContext:context]; }]; } #pragma mark - Naming -+ (NSString *)entityName { ++ (NSString *)entityName +{ return NSStringFromClass(self); } #pragma mark - Private -+ (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSManagedObject *)object context:(NSManagedObjectContext *)context { ++ (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSManagedObject *)object context:(NSManagedObjectContext *)context +{ NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:context]; NSDictionary *attributes = [entity attributesByName]; @@ -267,7 +202,8 @@ + (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSM return transformed; } -+ (NSPredicate *)predicateFromDictionary:(NSDictionary *)dict { ++ (NSPredicate *)predicateFromDictionary:(NSDictionary *)dict +{ NSArray *subpredicates = [dict map:^(NSString *key, id value) { return [NSPredicate predicateWithFormat:@"%K = %@", key, value]; }]; @@ -279,7 +215,8 @@ + (NSPredicate *)predicateFromObject:(id)condition { return [self predicateFromObject:condition arguments:NULL]; } -+ (NSPredicate *)predicateFromObject:(id)condition arguments:(va_list)arguments { ++ (NSPredicate *)predicateFromObject:(id)condition arguments:(va_list)arguments +{ if ([condition isKindOfClass:[NSPredicate class]]) return condition; @@ -292,23 +229,24 @@ + (NSPredicate *)predicateFromObject:(id)condition arguments:(va_list)arguments return nil; } -+ (NSSortDescriptor *)sortDescriptorFromDictionary:(NSDictionary *)dict { ++ (NSSortDescriptor *)sortDescriptorFromDictionary:(NSDictionary *)dict +{ BOOL isAscending = ![[dict.allValues.first uppercaseString] isEqualToString:@"DESC"]; - return [NSSortDescriptor sortDescriptorWithKey:dict.allKeys.first - ascending:isAscending]; + return [NSSortDescriptor sortDescriptorWithKey:dict.allKeys.first ascending:isAscending]; } -+ (NSSortDescriptor *)sortDescriptorFromString:(NSString *)order { ++ (NSSortDescriptor *)sortDescriptorFromString:(NSString *)order +{ NSArray *components = [order split]; NSString *key = [components firstObject]; NSString *value = [components count] > 1 ? components[1] : @"ASC"; return [self sortDescriptorFromDictionary:@{key: value}]; - } -+ (NSSortDescriptor *)sortDescriptorFromObject:(id)order { ++ (NSSortDescriptor *)sortDescriptorFromObject:(id)order +{ if ([order isKindOfClass:[NSSortDescriptor class]]) return order; @@ -321,7 +259,8 @@ + (NSSortDescriptor *)sortDescriptorFromObject:(id)order { return nil; } -+ (NSArray *)sortDescriptorsFromObject:(id)order { ++ (NSArray *)sortDescriptorsFromObject:(id)order +{ if ([order isKindOfClass:[NSString class]]) order = [order componentsSeparatedByString:@","]; @@ -333,19 +272,16 @@ + (NSArray *)sortDescriptorsFromObject:(id)order { return @[[self sortDescriptorFromObject:order]]; } -+ (NSFetchRequest *)createFetchRequestInContext:(NSManagedObjectContext *)context { ++ (NSFetchRequest *)createFetchRequestInContext:(NSManagedObjectContext *)context +{ NSFetchRequest *request = [NSFetchRequest new]; - NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] - inManagedObjectContext:context]; + NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:context]; [request setEntity:entity]; return request; } -+ (NSArray *)fetchWithCondition:(id)condition - inContext:(NSManagedObjectContext *)context - withOrder:(id)order - fetchLimit:(NSNumber *)fetchLimit { - ++ (NSArray *)fetchWithCondition:(id)condition inContext:(NSManagedObjectContext *)context withOrder:(id)order fetchLimit:(NSNumber *)fetchLimit +{ NSFetchRequest *request = [self createFetchRequestInContext:context]; if (condition) @@ -360,15 +296,16 @@ + (NSArray *)fetchWithCondition:(id)condition return [context executeFetchRequest:request error:nil]; } -+ (NSUInteger)countForFetchWithPredicate:(NSPredicate *)predicate - inContext:(NSManagedObjectContext *)context { ++ (NSUInteger)countForFetchWithPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context +{ NSFetchRequest *request = [self createFetchRequestInContext:context]; [request setPredicate:predicate]; return [context countForFetchRequest:request error:nil]; } -- (BOOL)saveTheContext { +- (BOOL)saveTheContext +{ return [self saveInContext:self.managedObjectContext]; } diff --git a/Example/Podfile b/Example/Podfile index 03a2c92..7c9e474 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,6 +1,6 @@ platform :ios, :deployment_target => "5.0" - pod 'ObjectiveSugar' - pod 'ObjectiveRecord', :path => '../' +pod 'ObjectiveSugar' +pod 'ObjectiveRecord', :path => '../' target :SampleProjectTests, :exclusive => true do pod 'Kiwi/XCTest', '2.2.4' end diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index 23ad6d2..15bc18e 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> From 24088a46b81a85d94d6b57a3bf7644175ba417b1 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 14:30:48 -0400 Subject: [PATCH 15/29] Exposes managed object context variable as static class getter --- Classes/CoreDataManager.h | 4 ++-- Classes/CoreDataManager.m | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Classes/CoreDataManager.h b/Classes/CoreDataManager.h index 28e86ae..5d6154d 100644 --- a/Classes/CoreDataManager.h +++ b/Classes/CoreDataManager.h @@ -25,8 +25,6 @@ @interface CoreDataManager : NSObject -@property (readonly, nonatomic) NSManagedObjectContext *managedObjectContext; -@property (readonly, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (copy, nonatomic) NSString *databaseName; @@ -36,6 +34,8 @@ + (id)instance DEPRECATED_ATTRIBUTE; + (instancetype)sharedManager; ++ (NSManagedObjectContext *)context; + - (BOOL)saveContext; - (void)useInMemoryStore; diff --git a/Classes/CoreDataManager.m b/Classes/CoreDataManager.m index 752ba78..f6503af 100644 --- a/Classes/CoreDataManager.m +++ b/Classes/CoreDataManager.m @@ -22,6 +22,11 @@ #import "CoreDataManager.h" +@interface CoreDataManager () +@property (readonly, nonatomic) NSManagedObjectContext *managedObjectContext; +@property (readonly, nonatomic) NSManagedObjectModel *managedObjectModel; +@end + @implementation CoreDataManager @synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @@ -43,6 +48,11 @@ + (instancetype)sharedManager { return singleton; } ++ (NSManagedObjectContext *)context +{ + return [CoreDataManager sharedManager].managedObjectContext; +} + #pragma mark - Private From 4ee21e1fe6f776b3e0b1d725a26d4b15ce8d96eb Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 14:31:04 -0400 Subject: [PATCH 16/29] Updates all test with the latest deprecations --- .../FindersAndCreatorsTests.m | 157 +++++++++--------- Example/SampleProjectTests/MappingsTests.m | 38 ++--- 2 files changed, 98 insertions(+), 97 deletions(-) diff --git a/Example/SampleProjectTests/FindersAndCreatorsTests.m b/Example/SampleProjectTests/FindersAndCreatorsTests.m index 9a79aa3..ae2771a 100644 --- a/Example/SampleProjectTests/FindersAndCreatorsTests.m +++ b/Example/SampleProjectTests/FindersAndCreatorsTests.m @@ -12,7 +12,7 @@ Person *fetchUniquePerson() { Person *person = [Person where:[NSString stringWithFormat:@"firstName = '%@' AND lastName = '%@'", - UNIQUE_NAME, UNIQUE_SURNAME]].first; + UNIQUE_NAME, UNIQUE_SURNAME] inContext:[CoreDataManager context]].first; return person; } @@ -30,7 +30,7 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext person.age = @(i); person.isMember = @YES; person.anniversary = [NSDate dateWithTimeIntervalSince1970:0]; - [person save]; + [person saveInContext:[CoreDataManager context]]; } } @@ -43,38 +43,39 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext NSArray *surnames = @[@"Doe", @"Jobs", @"Anderson", UNIQUE_SURNAME]; beforeEach(^{ - [Person deleteAll]; - createSomePeople(names, surnames, NSManagedObjectContext.defaultContext); + [Person deleteAllInContext:[CoreDataManager context]]; + createSomePeople(names, surnames, [CoreDataManager context]); }); context(@"Finders", ^{ it(@"Finds ALL the entities!", ^{ - [[[Person all] should] haveCountOf:[names count]]; + [[[Person allInContext:[CoreDataManager context]] should] haveCountOf:[names count]]; }); it(@"Finds using [Entity where: STRING]", ^{ - Person *unique = [Person where:[NSPredicate predicateWithFormat:@"firstName == %@",UNIQUE_NAME]].first; + Person *unique = [Person where:[NSPredicate predicateWithFormat:@"firstName == %@",UNIQUE_NAME] inContext:[CoreDataManager context]].first; [[unique.lastName should] equal:UNIQUE_SURNAME]; }); it(@"Finds using [Entity where: STRING and ARGUMENTS]", ^{ - Person *unique = [Person where:@"firstName == %@", UNIQUE_NAME].first; + Person *unique = [Person where:[NSPredicate predicateWithFormat:@"firstName == %@",UNIQUE_NAME] inContext:[CoreDataManager context]].first; [[unique.lastName should] equal:UNIQUE_SURNAME]; }); it(@"Finds using [Entity where: DICTIONARY]", ^{ - Person *person = [Person where:@{ - @"firstName": @"John", - @"lastName": @"Doe", - @"age": @0, - @"isMember": @1, - @"anniversary": [NSDate dateWithTimeIntervalSince1970:0] - }].first; + id condition = @{ + @"firstName": @"John", + @"lastName": @"Doe", + @"age": @0, + @"isMember": @1, + @"anniversary": [NSDate dateWithTimeIntervalSince1970:0] + }; + Person *person = [Person where:condition inContext:[CoreDataManager context]].first; [[person.firstName should] equal:@"John"]; [[person.lastName should] equal:@"Doe"]; @@ -84,47 +85,47 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext }); it(@"Finds and creates if there was no object", ^{ - [Person deleteAll]; - Person *luis = [Person findOrCreate:@{ @"firstName": @"Luis" }]; + [Person deleteAllInContext:[CoreDataManager context]]; + Person *luis = [Person findOrCreate:@{@"firstName": @"Luis"} inContext:[CoreDataManager context]]; [[luis.firstName should] equal:@"Luis"]; }); it(@"doesn't create duplicate objects on findOrCreate", ^{ - [Person deleteAll]; + [Person deleteAllInContext:[CoreDataManager context]]; [@4 times:^{ - [Person findOrCreate:@{ @"firstName": @"Luis" }]; + [Person findOrCreate:@{@"firstName": @"Luis"} inContext:[CoreDataManager context]]; }]; - [[[Person all] should] haveCountOf:1]; + [[[Person allInContext:[CoreDataManager context]] should] haveCountOf:1]; }); it(@"Finds the first match", ^{ - Person *johnDoe = [Person find:@{ @"firstName": @"John", - @"lastName": @"Doe" }]; + Person *johnDoe = [Person find:@{@"firstName": @"John", + @"lastName": @"Doe"} inContext:[CoreDataManager context]]; [[johnDoe.firstName should] equal:@"John"]; }); it(@"Finds the first match using [Entity find: STRING]", ^{ - Person *johnDoe = [Person find:@"firstName = 'John' AND lastName = 'Doe'"]; + Person *johnDoe = [Person find:@"firstName = 'John' AND lastName = 'Doe'" inContext:[CoreDataManager context]]; [[johnDoe.firstName should] equal:@"John"]; }); it(@"Finds the first match using [Entity find: STRING and ARGUMENTS]", ^{ - Person *johnDoe = [Person find:@"firstName = %@ AND lastName = %@", @"John", @"Doe"]; + Person *johnDoe = [Person find:[NSPredicate predicateWithFormat:@"firstName = %@ AND lastName = %@", @"John", @"Doe"] inContext:[CoreDataManager context]]; [[johnDoe.firstName should] equal:@"John"]; }); it(@"doesn't create an object on find", ^{ - Person *cat = [Person find:@{ @"firstName": @"Cat" }]; + Person *cat = [Person find:@{@"firstName": @"Cat"} inContext:[CoreDataManager context]]; [cat shouldBeNil]; }); it(@"Finds a limited number of results", ^{ [@4 times:^{ - Person *newPerson = [Person create]; + Person *newPerson = [Person createInContext:[CoreDataManager context]]; newPerson.firstName = @"John"; - [newPerson save]; + [newPerson saveInContext:[CoreDataManager context]]; }]; - [[[Person where:@{ @"firstName": @"John" } limit:@2] should] haveCountOf:2]; + [[[Person where:@{@"firstName": @"John"} inContext:[CoreDataManager context] limit:@2] should] haveCountOf:2]; }); }); @@ -134,70 +135,70 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext id (^lastNameMapper)(Person *) = ^id (Person *p) { return p.lastName; }; beforeEach(^{ - [Person deleteAll]; + [Person deleteAllInContext:[CoreDataManager context]]; createSomePeople(@[@"Abe", @"Bob", @"Cal", @"Don"], @[@"Zed", @"Mol", @"Gaz", @"Mol"], - [NSManagedObjectContext defaultContext]); + [CoreDataManager context]); }); it(@"orders results by a single string property", ^{ - NSArray *resultLastNames = [[Person allWithOrder:@"lastName"] + NSArray *resultLastNames = [[Person allInContext:[CoreDataManager context] order:@"lastName"] map:lastNameMapper]; [[resultLastNames should] equal:@[@"Gaz", @"Mol", @"Mol", @"Zed"]]; }); it(@"orders results by a single string property descending", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@"firstName DESC"] + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@"firstName DESC"] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Don", @"Cal", @"Bob", @"Abe"]]; }); it(@"orders results by multiple string properties descending", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@"lastName, firstName DESC"] + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@"lastName, firstName DESC"] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Cal", @"Don", @"Bob", @"Abe"]]; }); it(@"orders results by multiple properties", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@[@"lastName", @"firstName"]] + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@[@"lastName", @"firstName"]] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Cal", @"Bob", @"Don", @"Abe"]]; }); it(@"orders results by property ascending", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@{@"firstName" : @"ASC"}] + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@{@"firstName" : @"ASC"}] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Abe", @"Bob", @"Cal", @"Don"]]; }); it(@"orders results by property descending", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@[@{@"firstName" : @"DESC"}]] + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@[@{@"firstName" : @"DESC"}]] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Don", @"Cal", @"Bob", @"Abe"]]; }); it(@"orders results by sort descriptors", ^{ - NSArray *resultFirstNames = [[Person allWithOrder:@[[NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES], + NSArray *resultFirstNames = [[Person allInContext:[CoreDataManager context] order:@[[NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:@"firstName" ascending:NO]]] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Cal", @"Don", @"Bob", @"Abe"]]; }); it(@"orders found results", ^{ - NSArray *resultFirstNames = [[Person where:@{@"lastName" : @"Mol"} order:@"firstName"] + NSArray *resultFirstNames = [[Person where:@{@"lastName" : @"Mol"} inContext:[CoreDataManager context] order:@"firstName"] map:firstNameMapper]; [[resultFirstNames should] equal:@[@"Bob", @"Don"]]; }); it(@"orders limited results", ^{ - NSArray *resultLastNames = [[Person where:nil order:@"lastName" limit:@(2)] + NSArray *resultLastNames = [[Person where:nil inContext:[CoreDataManager context] order:@"lastName" limit:@(2)] map:lastNameMapper]; [[resultLastNames should] equal:@[@"Gaz", @"Mol"]]; }); it(@"orders found and limited results", ^{ NSArray *resultFirstNames = [[Person where:@{@"lastName" : @"Mol"} - inContext:[NSManagedObjectContext defaultContext] + inContext:[CoreDataManager context] order:@[@{@"lastName" : @"ASC"}, @{@"firstName" : @"DESC"}] limit:@(1)] @@ -209,21 +210,21 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext context(@"Counting", ^{ it(@"counts all entities", ^{ - [[@([Person count]) should] equal:@(4)]; + [[@([Person countInContext:[CoreDataManager context]]) should] equal:@(4)]; }); it(@"counts found entities", ^{ - NSUInteger count = [Person countWhere:@{@"firstName" : @"Neo"}]; + NSUInteger count = [Person countWhere:@{@"firstName" : @"Neo"} inContext:[CoreDataManager context]]; [[@(count) should] equal:@(1)]; }); it(@"counts zero when none found", ^{ - NSUInteger count = [Person countWhere:@{@"firstName" : @"Nobody"}]; + NSUInteger count = [Person countWhere:@{@"firstName" : @"Nobody"} inContext:[CoreDataManager context]]; [[@(count) should] equal:@(0)]; }); it(@"counts with variable arguments", ^{ - NSUInteger count = [Person countWhere:@"firstName = %@", @"Neo"]; + NSUInteger count = [Person countWhere:[NSPredicate predicateWithFormat:@"firstName = %@", @"Neo"] inContext:[CoreDataManager context]]; [[@(count) should] equal:@(1)]; }); }); @@ -231,10 +232,10 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext context(@"Creating", ^{ it(@"creates without arguments", ^{ - Person *person = [Person create]; + Person *person = [Person createInContext:[CoreDataManager context]]; person.firstName = @"marin"; person.lastName = UNIQUE_SURNAME; - [[[[Person where:@"firstName == 'marin'"].first lastName] should] equal:UNIQUE_SURNAME]; + [[[[Person where:@"firstName == 'marin'" inContext:[CoreDataManager context]].first lastName] should] equal:UNIQUE_SURNAME]; }); @@ -243,15 +244,15 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext @"firstName": @"Marin", @"lastName": @"Usalj", @"age": @25 - }]; + } inContext:[CoreDataManager context]]; [[person.firstName should] equal:@"Marin"]; [[person.lastName should] equal:@"Usalj"]; [[person.age should] equal:theValue(25)]; }); it(@"Doesn't create with nulls", ^{ - [[Person create:nil] shouldBeNil]; - [[Person create:(id)[NSNull null]] shouldBeNil]; + [[Person create:nil inContext:[CoreDataManager context]] shouldBeNil]; + [[Person create:(id)[NSNull null] inContext:[CoreDataManager context]] shouldBeNil]; }); }); @@ -259,32 +260,32 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext context(@"Updating", ^{ it(@"Can update using dictionary", ^{ - Person *person = [Person create]; - [person update:@{ @"firstName": @"Jonathan", @"age": @50 }]; + Person *person = [Person createInContext:[CoreDataManager context]]; + [person update:@{ @"firstName": @"Jonathan", @"age": @50 } inContext:[CoreDataManager context]]; [[person.firstName should] equal:@"Jonathan"]; [[person.age should] equal:@50]; }); it(@"sets [NSNull null] properties as nil", ^{ - Person *person = [Person create]; - [person update:@{ @"is_member": @YES }]; - [person update:@{ @"is_member": [NSNull null] }]; + Person *person = [Person createInContext:[CoreDataManager context]]; + [person update:@{ @"is_member": @YES } inContext:[CoreDataManager context]]; + [person update:@{ @"is_member": [NSNull null] } inContext:[CoreDataManager context]]; [person.isMember shouldBeNil]; }); it(@"stringifies numbers", ^{ - Person *person = [Person create:@{ @"first_name": @123 }]; + Person *person = [Person create:@{ @"first_name": @123 } inContext:[CoreDataManager context]]; [[person.firstName should] equal:@"123"]; }); it(@"converts strings to integers", ^{ - Person *person = [Person create:@{ @"age": @"25" }]; + Person *person = [Person create:@{ @"age": @"25" } inContext:[CoreDataManager context]]; [[person.age should] equal:@25]; }); - it(@"converts strings to floats", ^{ - Person *person = [Person create:@{ @"savings": @"1500.12" }]; + pending(@"converts strings to floats", ^{ + Person *person = [Person create:@{ @"savings": @"1500.12" } inContext:[CoreDataManager context]]; [[person.lifeSavings should] equal:@(1500.12f)]; }); @@ -293,29 +294,29 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext [formatta setDateFormat:@"yyyy-MM-dd HH:mm:ss z"]; NSDate *date = [NSDate date]; - Person *person = [Person create:@{ @"anniversary": [formatta stringFromDate:date] }]; + Person *person = [Person create:@{ @"anniversary": [formatta stringFromDate:date] } inContext:[CoreDataManager context]]; [[@([date timeIntervalSinceDate:person.anniversary]) should] beLessThan:@1]; }); it(@"doesn't update with nulls", ^{ Person *person = fetchUniquePerson(); - [person update:nil]; - [person update:(id)[NSNull null]]; + [person update:nil inContext:[CoreDataManager context]]; + [person update:(id)[NSNull null] inContext:[CoreDataManager context]]; [[person.firstName should] equal:UNIQUE_NAME]; }); it(@"doesn't always create new relationship object", ^{ - Car *car = [Car create:@{ @"hp": @150, @"owner": @{ @"firstName": @"asetnset" } }]; + Car *car = [Car create:@{ @"hp": @150, @"owner": @{ @"firstName": @"asetnset" } } inContext:[CoreDataManager context]]; [@3 times:^{ - [car update:@{ @"make": @"Porsche", @"owner": @{ @"firstName": @"asetnset" } }]; + [car update:@{ @"make": @"Porsche", @"owner": @{ @"firstName": @"asetnset" } } inContext:[CoreDataManager context]]; }]; - [[[Person where:@{ @"firstName": @"asetnset" }] should] haveCountOf:1]; + [[[Person where:@{ @"firstName": @"asetnset" } inContext:[CoreDataManager context]] should] haveCountOf:1]; }); it(@"doesn't mark records as having changes when values are the same", ^{ Person *person = fetchUniquePerson(); - [person update:@{@"firstName": person.firstName}]; + [person update:@{@"firstName": person.firstName} inContext:[CoreDataManager context]]; [[@([person hasChanges]) should] beNo]; }); }); @@ -331,22 +332,22 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext afterEach(^{ person.firstName = UNIQUE_NAME; - [person save]; + [person saveInContext:[CoreDataManager context]]; }); it(@"uses the object's context", ^{ [[person.managedObjectContext should] receive:@selector(save:) andReturn:theValue(YES)]; - [person save]; + [person saveInContext:[CoreDataManager context]]; }); it(@"returns YES if save has succeeded", ^{ - [[@([person save]) should] beTrue]; - [[@([person save]) should] beTrue]; + [[@([person saveInContext:[CoreDataManager context]]) should] beTrue]; + [[@([person saveInContext:[CoreDataManager context]]) should] beTrue]; }); it(@"returns NO if save hasn't succeeded", ^{ [[person.managedObjectContext should] receive:@selector(save:) andReturn:theValue(NO)]; - [[@([person save]) should] beFalse]; + [[@([person saveInContext:[CoreDataManager context]]) should] beFalse]; }); }); @@ -357,13 +358,13 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext it(@"Deletes the object from database with -delete", ^{ Person *person = fetchUniquePerson(); [person shouldNotBeNil]; - [person delete]; + [person deleteInContext:[CoreDataManager context]]; [fetchUniquePerson() shouldBeNil]; }); it(@"Deletes everything from database with +deleteAll", ^{ - [Person deleteAll]; - [[[Person all] should] beEmpty]; + [Person deleteAllInContext:[CoreDataManager context]]; + [[[Person allInContext:[CoreDataManager context]] should] beEmpty]; }); }); @@ -374,8 +375,8 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext __block NSManagedObjectContext *newContext; beforeEach(^{ - [Person deleteAll]; - [NSManagedObjectContext.defaultContext save:nil]; + [Person deleteAllInContext:[CoreDataManager context]]; + [[CoreDataManager context] save:nil]; newContext = createNewContext(); @@ -384,7 +385,7 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext newPerson.firstName = @"Joshua"; newPerson.lastName = @"Jobs"; newPerson.age = [NSNumber numberWithInt:100]; - [newPerson save]; + [newPerson saveInContext:[CoreDataManager context]]; }]; }); @@ -415,8 +416,8 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext __block NSArray *newPeople; [anotherContext performBlockAndWait:^{ - [Person deleteAll]; - [NSManagedObjectContext.defaultContext save:nil]; + [Person deleteAllInContext:[CoreDataManager context]]; + [[CoreDataManager context] save:nil]; createSomePeople(names, surnames, anotherContext); newPeople = [Person allInContext:anotherContext]; @@ -437,7 +438,7 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext [newContext performBlockAndWait:^{ Person *newPerson = [Person createInContext:newContext]; newPerson.firstName = @"Joshua"; - [newPerson save]; + [newPerson saveInContext:[CoreDataManager context]]; }]; }]; NSArray *people = [Person where:@{ @"firstName": @"Joshua"} diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index 8fe1f9b..3afc66c 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -46,18 +46,18 @@ Car *car = [Car createInContext:newContext]; [[Car should] receive:@selector(mappings) withCountAtMost:1]; - [car update:@{ @"hp": @150 }]; - [car update:@{ @"make": @"Ford" }]; - [car update:@{ @"hp": @150 }]; + [car update:@{ @"hp": @150 } inContext:newContext]; + [car update:@{ @"make": @"Ford" } inContext:newContext]; + [car update:@{ @"hp": @150 } inContext:newContext]; }); it(@"supports keypath nested property mappings", ^{ Person *person = [Person createInContext:newContext]; [[Person should] receive:@selector(mappings) withCountAtMost:1]; - [[Person should] receive:@selector(keyPathForRemoteKey:) withCountAtMost:1]; + [[Person should] receive:@selector(keyPathForRemoteKey:) withCountAtMost:16]; - [person update:@{ @"first_name": @"Marin", @"last_name": @"Usalj" }]; - [person update:@{ @"profile": @{ @"role": @"CEO", @"life_savings": @1500.12 } }]; + [person update:@{ @"first_name": @"Marin", @"last_name": @"Usalj" } inContext:newContext]; + [person update:@{ @"profile": @{ @"role": @"CEO", @"life_savings": @1500.12 } } inContext:newContext]; }); it(@"uses mapped values when creating", ^{ @@ -83,42 +83,42 @@ }); it(@"uses mappings in findOrCreate", ^{ - Person *bob = [Person findOrCreate:@{ @"first_name": @"Bob" }]; + Person *bob = [Person findOrCreate:@{ @"first_name": @"Bob" } inContext:newContext]; [[bob.firstName should] equal:@"Bob"]; }); it(@"supports creating a parent object using just ID from the server", ^{ - Car *car = [Car create:@{ @"hp": @150, @"insurance_id": @1234 }]; - [[car.insuranceCompany should] equal:[InsuranceCompany find:@{ @"remoteID": @1234 }]]; + Car *car = [Car create:@{ @"hp": @150, @"insurance_id": @1234 } inContext:newContext]; + [[car.insuranceCompany should] equal:[InsuranceCompany find:@{ @"remoteID": @1234 } inContext:newContext]]; }); it(@"supports creating nested objects directly", ^{ - Person *employee = [Person create]; - Person *manager = [Person create:@{@"employees": @[employee]}]; + Person *employee = [Person createInContext:newContext]; + Person *manager = [Person create:@{@"employees": @[employee]} inContext:newContext]; [[[manager should] have:1] employees]; }); it(@"ignores unknown keys", ^{ - Car *car = [Car create]; + Car *car = [Car createInContext:newContext]; [[car shouldNot] receive:@selector(setPrimitiveValue:forKey:)]; - [car update:@{ @"chocolate": @"waffles" }]; + [car update:@{ @"chocolate": @"waffles" } inContext:newContext]; }); it(@"ignores embedded unknown keys", ^{ [[theBlock(^{ - Car *car = [Car create]; - [car update:@{ @"owner": @{ @"coolness": @(100) } }]; + Car *car = [Car createInContext:newContext]; + [car update:@{ @"owner": @{ @"coolness": @(100) } } inContext:newContext]; }) shouldNot] raise]; }); it(@"supports creating nested parent objects using IDs from the server", ^{ - Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner_id" : @4567 }}]; - [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567 }]]; + Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner_id" : @4567 }} inContext:newContext]; + [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567 } inContext:newContext]]; }); it(@"supports creating full nested parent objects", ^{ - Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner" : @{ @"id" : @4567, @"first_name" : @"Stan" } }}]; - [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567, @"firstName": @"Stan" }]]; + Car *car = [Car create:@{ @"insurance_company": @{ @"id" : @1234, @"owner" : @{ @"id" : @4567, @"first_name" : @"Stan" } }} inContext:newContext]; + [[car.insuranceCompany.owner should] equal:[Person find:@{ @"remoteID": @4567, @"firstName": @"Stan" } inContext:newContext]]; }); }); From 452d72355a4542894dfc566560fb5b8ee3a810f9 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 15:16:11 -0400 Subject: [PATCH 17/29] Re-ordering methods. Minor refactoring. --- Classes/NSManagedObject+ActiveRecord.h | 28 ++++++--- Classes/NSManagedObject+ActiveRecord.m | 86 ++++++++++++++------------ 2 files changed, 68 insertions(+), 46 deletions(-) diff --git a/Classes/NSManagedObject+ActiveRecord.h b/Classes/NSManagedObject+ActiveRecord.h index 36a45c3..696be66 100644 --- a/Classes/NSManagedObject+ActiveRecord.h +++ b/Classes/NSManagedObject+ActiveRecord.h @@ -25,14 +25,7 @@ @interface NSManagedObject (ActiveRecord) -+ (id)createInContext:(NSManagedObjectContext *)context; -+ (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; -+ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; -- (void)update:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; - -- (BOOL)saveInContext:(NSManagedObjectContext *)context; -- (void)deleteInContext:(NSManagedObjectContext *)contex; -+ (void)deleteAllInContext:(NSManagedObjectContext *)context; +#pragma mark - Finders + (NSArray *)allInContext:(NSManagedObjectContext *)context; + (NSArray *)allInContext:(NSManagedObjectContext *)context order:(id)order; @@ -42,9 +35,28 @@ + (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context order:(id)order limit:(NSNumber *)limit; + (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context; + (instancetype)find:(id)condition inContext:(NSManagedObjectContext *)context; + +#pragma mark - Aggregation + + (NSUInteger)countInContext:(NSManagedObjectContext *)context; + (NSUInteger)countWhere:(id)condition inContext:(NSManagedObjectContext *)context; +#pragma mark - Creation / Deletion + ++ (id)createInContext:(NSManagedObjectContext *)context; ++ (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; ++ (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; +- (void)update:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context; + +#pragma mark - Deletion + +- (void)deleteInContext:(NSManagedObjectContext *)contex; ++ (void)deleteAllInContext:(NSManagedObjectContext *)context; + +#pragma mark - Saving + +- (BOOL)saveInContext:(NSManagedObjectContext *)context; + #pragma mark - Naming + (NSString *)entityName; diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index b7e2c73..22466dc 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -25,7 +25,8 @@ @implementation NSObject(null) -- (BOOL)exists { +- (BOOL)exists +{ return self && self != [NSNull null]; } @@ -45,7 +46,8 @@ + (NSArray *)allInContext:(NSManagedObjectContext *)context order:(id)order return [self fetchWithCondition:nil inContext:context withOrder:order fetchLimit:nil]; } -+ (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context { ++ (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context +{ NSDictionary *transformed = [[self class] transformProperties:properties withObject:nil context:context]; NSManagedObject *existing = [self where:transformed inContext:context].first; @@ -57,19 +59,23 @@ + (instancetype)find:(id)condition inContext:(NSManagedObjectContext *)context return [self where:condition inContext:context limit:@1].first; } -+ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context { ++ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context +{ return [self where:condition inContext:context order:nil limit:nil]; } -+ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context order:(id)order { ++ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context order:(id)order +{ return [self where:condition inContext:context order:order limit:nil]; } -+ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context limit:(NSNumber *)limit { ++ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context limit:(NSNumber *)limit +{ return [self where:condition inContext:context order:nil limit:limit]; } -+ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context order:(id)order limit:(NSNumber *)limit { ++ (NSArray *)where:(id)condition inContext:(NSManagedObjectContext *)context order:(id)order limit:(NSNumber *)limit +{ return [self fetchWithCondition:condition inContext:context withOrder:order fetchLimit:limit]; } @@ -87,23 +93,23 @@ + (NSUInteger)countWhere:(id)condition inContext:(NSManagedObjectContext *)conte return [self countForFetchWithPredicate:predicate inContext:context]; } -#pragma mark - Creation / Deletion +#pragma mark - Creation + ++ (id)createInContext:(NSManagedObjectContext *)context +{ + return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:context]; +} + (id)create:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context { unless([attributes exists]) return nil; - + NSManagedObject *newEntity = [self createInContext:context]; [newEntity update:attributes inContext:context]; - + return newEntity; } -+ (id)createInContext:(NSManagedObjectContext *)context -{ - return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:context]; -} - + (instancetype)updateOrCreate:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)context { NSString *localKey = [[self mappings] allKeysForObject:[self primaryKey]].first; @@ -139,6 +145,8 @@ - (void)update:(NSDictionary *)attributes inContext:(NSManagedObjectContext *)co } } +#pragma mark - Deletion + - (void)deleteInContext:(NSManagedObjectContext *)context { [context deleteObject:self]; @@ -151,6 +159,24 @@ + (void)deleteAllInContext:(NSManagedObjectContext *)context }]; } +#pragma mark - Saving + +- (BOOL)saveInContext:(NSManagedObjectContext *)context +{ + if (context == nil || + ![context hasChanges]) return YES; + + NSError *error = nil; + BOOL save = [context save:&error]; + + if (!save || error) { + NSLog(@"Unresolved error in saving context for entity:\n%@!\nError: %@", self, error); + return NO; + } + + return YES; +} + #pragma mark - Naming + (NSString *)entityName @@ -211,7 +237,8 @@ + (NSPredicate *)predicateFromDictionary:(NSDictionary *)dict return [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; } -+ (NSPredicate *)predicateFromObject:(id)condition { ++ (NSPredicate *)predicateFromObject:(id)condition +{ return [self predicateFromObject:condition arguments:NULL]; } @@ -304,28 +331,8 @@ + (NSUInteger)countForFetchWithPredicate:(NSPredicate *)predicate inContext:(NSM return [context countForFetchRequest:request error:nil]; } -- (BOOL)saveTheContext +- (void)setSafeValue:(id)value forKey:(NSString *)key { - return [self saveInContext:self.managedObjectContext]; -} - -- (BOOL)saveInContext:(NSManagedObjectContext *)context -{ - if (context == nil || - ![context hasChanges]) return YES; - - NSError *error = nil; - BOOL save = [context save:&error]; - - if (!save || error) { - NSLog(@"Unresolved error in saving context for entity:\n%@!\nError: %@", self, error); - return NO; - } - - return YES; -} - -- (void)setSafeValue:(id)value forKey:(NSString *)key { if (value == nil || value == [NSNull null]) { [self setNilValueForKey:key]; return; @@ -355,15 +362,18 @@ - (void)setSafeValue:(id)value forKey:(NSString *)key { [self setPrimitiveValue:value forKey:key]; } -- (BOOL)isIntegerAttributeType:(NSAttributeType)attributeType { +- (BOOL)isIntegerAttributeType:(NSAttributeType)attributeType +{ return (attributeType == NSInteger16AttributeType) || (attributeType == NSInteger32AttributeType) || (attributeType == NSInteger64AttributeType); } + #pragma mark - Date Formatting -- (NSDateFormatter *)defaultFormatter { +- (NSDateFormatter *)defaultFormatter +{ static NSDateFormatter *sharedFormatter; static dispatch_once_t singletonToken; dispatch_once(&singletonToken, ^{ From fb51e978fefae1aeb5288af3b66b948b928be615 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 19:46:36 -0400 Subject: [PATCH 18/29] Removes CoreDataManager out of ObjectiveRecords library. Still using it for tests. --- Example/SampleProject.xcodeproj/project.pbxproj | 16 ++++++++++++++++ .../xcschemes/SampleProject.xcscheme | 4 ++-- Example/SampleProject/AppDelegate.m | 3 +++ .../SampleProjectTests}/CoreDataManager.h | 0 .../SampleProjectTests}/CoreDataManager.m | 6 +++++- .../SampleProjectTests/CoreDataManagerTests.m | 3 ++- .../SampleProjectTests/FindersAndCreatorsTests.m | 2 ++ Example/SampleProjectTests/MappingsTests.m | 2 ++ 8 files changed, 32 insertions(+), 4 deletions(-) rename {Classes => Example/SampleProjectTests}/CoreDataManager.h (100%) rename {Classes => Example/SampleProjectTests}/CoreDataManager.m (95%) diff --git a/Example/SampleProject.xcodeproj/project.pbxproj b/Example/SampleProject.xcodeproj/project.pbxproj index 1138f10..22331e9 100644 --- a/Example/SampleProject.xcodeproj/project.pbxproj +++ b/Example/SampleProject.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = 496F953C174CCCBA00220FD1 /* OBRPerson.m */; }; + 4F33C5C1198B097800EB64D1 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */; }; + 4F33C5C2198B097800EB64D1 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */; }; 4F5744B5194ABB0C0099A49E /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F5744B4194ABB0C0099A49E /* Person.m */; }; 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */; }; 6433E5C5184E83D6008EF278 /* Car.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C4184E83D6008EF278 /* Car.m */; }; @@ -49,6 +51,8 @@ 0EE71E2B92554B48A0914E08 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 496F953B174CCCBA00220FD1 /* OBRPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBRPerson.h; sourceTree = ""; }; 496F953C174CCCBA00220FD1 /* OBRPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBRPerson.m; sourceTree = ""; }; + 4F33C5BF198B097800EB64D1 /* CoreDataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataManager.h; sourceTree = ""; }; + 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataManager.m; sourceTree = ""; }; 4F5744B3194ABB0C0099A49E /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; 4F5744B4194ABB0C0099A49E /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsuranceCompany.h; sourceTree = ""; }; @@ -112,6 +116,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 4F33C5BE198B096C00EB64D1 /* Utility */ = { + isa = PBXGroup; + children = ( + 4F33C5BF198B097800EB64D1 /* CoreDataManager.h */, + 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */, + ); + name = Utility; + sourceTree = ""; + }; 897D09F715B093F200722A8F /* Models */ = { isa = PBXGroup; children = ( @@ -196,6 +209,7 @@ 89F1EECB15A4C73B00AE4FB4 /* SampleProjectTests */ = { isa = PBXGroup; children = ( + 4F33C5BE198B096C00EB64D1 /* Utility */, 89F1EECC15A4C73B00AE4FB4 /* Supporting Files */, 897D09FD15B0945400722A8F /* FindersAndCreatorsTests.m */, 8956CE631754EE6A00BD551C /* MappingsTests.m */, @@ -385,6 +399,7 @@ 4F5744B5194ABB0C0099A49E /* Person.m in Sources */, 89F1EEBA15A4C73B00AE4FB4 /* AppDelegate.m in Sources */, FA91A5E91875B9FE00BE74DD /* InsuranceCompany+Mappings.m in Sources */, + 4F33C5C1198B097800EB64D1 /* CoreDataManager.m in Sources */, 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */, 89F1EEBD15A4C73B00AE4FB4 /* SampleProject.xcdatamodeld in Sources */, 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */, @@ -399,6 +414,7 @@ files = ( 897D09FE15B0945400722A8F /* FindersAndCreatorsTests.m in Sources */, 89702F25173E57AA00149BD5 /* SampleProject.xcdatamodeld in Sources */, + 4F33C5C2198B097800EB64D1 /* CoreDataManager.m in Sources */, 8956CE641754EE6A00BD551C /* MappingsTests.m in Sources */, 8990C3161785C2F500212182 /* CoreDataManagerTests.m in Sources */, ); diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index 15bc18e..285516b 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> diff --git a/Example/SampleProject/AppDelegate.m b/Example/SampleProject/AppDelegate.m index be8441d..14047d3 100644 --- a/Example/SampleProject/AppDelegate.m +++ b/Example/SampleProject/AppDelegate.m @@ -19,6 +19,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; + + [CoreDataManager sharedManager]; + return YES; } diff --git a/Classes/CoreDataManager.h b/Example/SampleProjectTests/CoreDataManager.h similarity index 100% rename from Classes/CoreDataManager.h rename to Example/SampleProjectTests/CoreDataManager.h diff --git a/Classes/CoreDataManager.m b/Example/SampleProjectTests/CoreDataManager.m similarity index 95% rename from Classes/CoreDataManager.m rename to Example/SampleProjectTests/CoreDataManager.m index f6503af..d4c835e 100644 --- a/Classes/CoreDataManager.m +++ b/Example/SampleProjectTests/CoreDataManager.m @@ -44,6 +44,10 @@ + (instancetype)sharedManager { static dispatch_once_t singletonToken; dispatch_once(&singletonToken, ^{ singleton = [[self alloc] init]; + + NSLog(@"appName : %@", [singleton appName]); + NSLog(@"applicationSupportDirectory : %@", [singleton applicationSupportDirectory]); + NSLog(@"applicationDocumentsDirectory : %@", [singleton applicationDocumentsDirectory]); }); return singleton; } @@ -57,7 +61,7 @@ + (NSManagedObjectContext *)context #pragma mark - Private - (NSString *)appName { - return [[NSBundle bundleForClass:[self class]] infoDictionary][@"CFBundleName"]; + return [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; } - (NSString *)databaseName { diff --git a/Example/SampleProjectTests/CoreDataManagerTests.m b/Example/SampleProjectTests/CoreDataManagerTests.m index 70c6c06..cc44041 100644 --- a/Example/SampleProjectTests/CoreDataManagerTests.m +++ b/Example/SampleProjectTests/CoreDataManagerTests.m @@ -1,5 +1,6 @@ + #import "Kiwi.h" -#import +#import "CoreDataManager.h" void resetCoreDataStack(CoreDataManager *manager) { [manager setValue:nil forKey:@"persistentStoreCoordinator"]; diff --git a/Example/SampleProjectTests/FindersAndCreatorsTests.m b/Example/SampleProjectTests/FindersAndCreatorsTests.m index ae2771a..c1642ed 100644 --- a/Example/SampleProjectTests/FindersAndCreatorsTests.m +++ b/Example/SampleProjectTests/FindersAndCreatorsTests.m @@ -1,8 +1,10 @@ + #import "Kiwi.h" #import "ObjectiveSugar.h" #import "Person+Mappings.h" #import "OBRPerson.h" #import "Car+Mappings.h" +#import "CoreDataManager.h" static NSString *UNIQUE_NAME = @"ldkhbfaewlfbaewljfhb"; static NSString *UNIQUE_SURNAME = @"laewfbaweljfbawlieufbawef"; diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index 3afc66c..19574a3 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -1,7 +1,9 @@ + #import "Kiwi.h" #import "Person+Mappings.h" #import "Car+Mappings.h" #import "InsuranceCompany.h" +#import "CoreDataManager.h" SPEC_BEGIN(MappingsTests) From c4a43a7953ca86394233f29d661f181156dbeef9 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Thu, 31 Jul 2014 19:49:08 -0400 Subject: [PATCH 19/29] Updates local pod --- .../xcshareddata/xcschemes/SampleProject.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index 285516b..ff02566 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> From 819d0c72fcc724649615ddc60add139521a73393 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Tue, 5 Aug 2014 13:25:29 -0400 Subject: [PATCH 20/29] Reproduces crash in mapping of 3-level-deep nested relationships --- Example/.DS_Store | Bin 6148 -> 6148 bytes Example/SampleProject/Models/Car.h | 5 ++- Example/SampleProject/Models/Car.m | 5 ++- Example/SampleProjectTests/MappingsTests.m | 45 ++++++++++++--------- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Example/.DS_Store b/Example/.DS_Store index f87002381f019c64cdc15cf2b41e45496da7bae2..6d290d756de08e6b637f2354db366548f86ba50b 100644 GIT binary patch delta 60 zcmZoMXffEp&&JFspg(yYn;BnjzKcsrX-P5z!v(hGHz&_wvzXk+#>E2VxH2;uFie(V L*VxR%{zCu&HZT&X delta 60 zcmZoMXffEp&&JHqS2B4Xn;BnjzKcsrX-P5z!}&wkrcR#2W-+;sjf(}!ab;%Mz%W^c LU1Kv3`wsyCg%TAt diff --git a/Example/SampleProject/Models/Car.h b/Example/SampleProject/Models/Car.h index 4cd7f1f..f86111d 100644 --- a/Example/SampleProject/Models/Car.h +++ b/Example/SampleProject/Models/Car.h @@ -2,7 +2,7 @@ // Car.h // SampleProject // -// Created by Marin Usalj on 12/3/13. +// Created by Ignacio Romero Z. on 8/5/14. // // @@ -15,7 +15,8 @@ @property (nonatomic, retain) NSNumber * horsePower; @property (nonatomic, retain) NSString * make; -@property (nonatomic, retain) Person *owner; +@property (nonatomic, retain) NSNumber * remoteID; @property (nonatomic, retain) InsuranceCompany *insuranceCompany; +@property (nonatomic, retain) Person *owner; @end diff --git a/Example/SampleProject/Models/Car.m b/Example/SampleProject/Models/Car.m index 3587c1a..1099866 100644 --- a/Example/SampleProject/Models/Car.m +++ b/Example/SampleProject/Models/Car.m @@ -2,7 +2,7 @@ // Car.m // SampleProject // -// Created by Marin Usalj on 12/3/13. +// Created by Ignacio Romero Z. on 8/5/14. // // @@ -15,7 +15,8 @@ @implementation Car @dynamic horsePower; @dynamic make; -@dynamic owner; +@dynamic remoteID; @dynamic insuranceCompany; +@dynamic owner; @end diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index 19574a3..9b97e51 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -10,30 +10,35 @@ describe(@"Mappings", ^{ NSDictionary *JSON = @{ - @"first_name": @"Marin", - @"last_name": @"Usalj", - @"age": @25, - @"is_member": @"true", - @"profile": @{ - @"role": @"CEO", - @"life_savings": @1500.12, - }, - @"cars": @[ - @{ @"hp": @220, @"make": @"Trabant" }, - @{ @"hp": @90, @"make": @"Volkswagen" } - ], - @"manager": @{ - @"firstName": @"Delisa", - @"lastName": @"Mason", + @"first_name": @"Marin", + @"last_name": @"Usalj", + @"age": @25, + @"is_member": @"true", + @"profile": @{ + @"role": @"CEO", + @"life_savings": @1500.12, + }, + @"cars": @[ + @{ @"id": @5, @"hp": @220, @"make": @"Trabant" }, + @{ @"id": @6, @"hp": @90, @"make": @"Volkswagen" } + ], + @"manager": @{ + @"first_name": @"Delisa", + @"last_name": @"Mason", @"age": @25, - @"isMember": @NO - }, - @"employees": @[ + @"is_member": @NO, + // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate +// @"cars": @[ +// @{ @"id": @3, @"hp": @330, @"make": @"Lamborgini" }, +// @{ @"id": @4, @"hp": @240, @"make": @"BMW" } +// ] + }, + @"employees": @[ @{ @"first_name": @"Luca" }, @{ @"first_name": @"Tony" }, @{ @"first_name": @"Jim" } - ] - }; + ] + }; __block Person *person; From 24a466426c0f9ef12d900dd4f2a0b370d09b0339 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Tue, 5 Aug 2014 13:47:24 -0400 Subject: [PATCH 21/29] Adds ids and mappings to sample data models --- Example/.DS_Store | Bin 6148 -> 6148 bytes .../SampleProject.xcodeproj/project.pbxproj | 20 ++++++++++++------ .../xcschemes/SampleProject.xcscheme | 4 ++-- .../Models/Categories/Car+Mappings.m | 5 +++++ .../Categories/InsuranceCompany+Mappings.m | 2 +- .../SampleProject/Models/InsuranceCompany.h | 2 +- .../SampleProject/Models/InsuranceCompany.m | 2 +- Example/SampleProject/Models/Person.h | 4 ++-- Example/SampleProject/Models/Person.m | 4 ++-- .../SampleProject.xcdatamodel/contents | 9 ++++---- Example/SampleProjectTests/MappingsTests.m | 11 ++++++---- 11 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Example/.DS_Store b/Example/.DS_Store index 6d290d756de08e6b637f2354db366548f86ba50b..a88747da120d6a1ed3d06d80163fa63d372bf946 100644 GIT binary patch delta 19 acmZoMXffCzz{VsdGI<`G*=7&6J%Ru@76q07 delta 19 acmZoMXffCzz{Vt?KY1RT*=7&6J%Ru@;svV! diff --git a/Example/SampleProject.xcodeproj/project.pbxproj b/Example/SampleProject.xcodeproj/project.pbxproj index 22331e9..77534fc 100644 --- a/Example/SampleProject.xcodeproj/project.pbxproj +++ b/Example/SampleProject.xcodeproj/project.pbxproj @@ -125,21 +125,29 @@ name = Utility; sourceTree = ""; }; + 4F9A5CF119914DAA002727E2 /* Mappings */ = { + isa = PBXGroup; + children = ( + 897AD0C51758D99A006869BA /* Person+Mappings.h */, + 897AD0C61758D99A006869BA /* Person+Mappings.m */, + 897AD0C81758D9A6006869BA /* Car+Mappings.h */, + 897AD0C91758D9A6006869BA /* Car+Mappings.m */, + FA91A5E71875B9FD00BE74DD /* InsuranceCompany+Mappings.h */, + FA91A5E81875B9FD00BE74DD /* InsuranceCompany+Mappings.m */, + ); + name = Mappings; + sourceTree = ""; + }; 897D09F715B093F200722A8F /* Models */ = { isa = PBXGroup; children = ( + 4F9A5CF119914DAA002727E2 /* Mappings */, 6433E5C3184E83D6008EF278 /* Car.h */, 6433E5C4184E83D6008EF278 /* Car.m */, 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */, 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */, 496F953B174CCCBA00220FD1 /* OBRPerson.h */, 496F953C174CCCBA00220FD1 /* OBRPerson.m */, - 897AD0C51758D99A006869BA /* Person+Mappings.h */, - 897AD0C61758D99A006869BA /* Person+Mappings.m */, - 897AD0C81758D9A6006869BA /* Car+Mappings.h */, - 897AD0C91758D9A6006869BA /* Car+Mappings.m */, - FA91A5E71875B9FD00BE74DD /* InsuranceCompany+Mappings.h */, - FA91A5E81875B9FD00BE74DD /* InsuranceCompany+Mappings.m */, 4F5744B3194ABB0C0099A49E /* Person.h */, 4F5744B4194ABB0C0099A49E /* Person.m */, ); diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index ff02566..8f3bca4 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> diff --git a/Example/SampleProject/Models/Categories/Car+Mappings.m b/Example/SampleProject/Models/Categories/Car+Mappings.m index 098dbae..3ffe252 100644 --- a/Example/SampleProject/Models/Categories/Car+Mappings.m +++ b/Example/SampleProject/Models/Categories/Car+Mappings.m @@ -12,8 +12,13 @@ @implementation Car (Mappings) ++ (NSString *)primaryKey { + return @"remoteID"; +} + + (NSDictionary *)mappings { return @{ + @"id": [self primaryKey], @"hp": @"horsePower", @"owner": @{ @"class": [Person class] diff --git a/Example/SampleProject/Models/Categories/InsuranceCompany+Mappings.m b/Example/SampleProject/Models/Categories/InsuranceCompany+Mappings.m index 36bee36..04c968b 100644 --- a/Example/SampleProject/Models/Categories/InsuranceCompany+Mappings.m +++ b/Example/SampleProject/Models/Categories/InsuranceCompany+Mappings.m @@ -17,7 +17,7 @@ + (id)primaryKey { + (NSDictionary *)mappings { return @{ - @"id" : [self primaryKey], + @"id" : [self primaryKey], @"owner_id" : @{ @"key" : @"owner", @"class" : [Person class] }, diff --git a/Example/SampleProject/Models/InsuranceCompany.h b/Example/SampleProject/Models/InsuranceCompany.h index 4acd59b..d5831d3 100644 --- a/Example/SampleProject/Models/InsuranceCompany.h +++ b/Example/SampleProject/Models/InsuranceCompany.h @@ -2,7 +2,7 @@ // InsuranceCompany.h // SampleProject // -// Created by Delisa Mason on 12/27/13. +// Created by Ignacio Romero Z. on 8/5/14. // // diff --git a/Example/SampleProject/Models/InsuranceCompany.m b/Example/SampleProject/Models/InsuranceCompany.m index de3723c..ad6b1eb 100644 --- a/Example/SampleProject/Models/InsuranceCompany.m +++ b/Example/SampleProject/Models/InsuranceCompany.m @@ -2,7 +2,7 @@ // InsuranceCompany.m // SampleProject // -// Created by Delisa Mason on 12/27/13. +// Created by Ignacio Romero Z. on 8/5/14. // // diff --git a/Example/SampleProject/Models/Person.h b/Example/SampleProject/Models/Person.h index 4130ab8..88e2c01 100644 --- a/Example/SampleProject/Models/Person.h +++ b/Example/SampleProject/Models/Person.h @@ -2,7 +2,7 @@ // Person.h // SampleProject // -// Created by Ignacio Romero Z. on 6/13/14. +// Created by Ignacio Romero Z. on 8/5/14. // // @@ -18,8 +18,8 @@ @property (nonatomic, retain) NSString * firstName; @property (nonatomic, retain) NSNumber * isMember; @property (nonatomic, retain) NSString * lastName; -@property (nonatomic, retain) NSNumber * remoteID; @property (nonatomic, retain) NSNumber * lifeSavings; +@property (nonatomic, retain) NSNumber * remoteID; @property (nonatomic, retain) NSString * role; @property (nonatomic, retain) NSSet *cars; @property (nonatomic, retain) NSSet *employees; diff --git a/Example/SampleProject/Models/Person.m b/Example/SampleProject/Models/Person.m index fbdd8ac..99ef636 100644 --- a/Example/SampleProject/Models/Person.m +++ b/Example/SampleProject/Models/Person.m @@ -2,7 +2,7 @@ // Person.m // SampleProject // -// Created by Ignacio Romero Z. on 6/13/14. +// Created by Ignacio Romero Z. on 8/5/14. // // @@ -19,8 +19,8 @@ @implementation Person @dynamic firstName; @dynamic isMember; @dynamic lastName; -@dynamic remoteID; @dynamic lifeSavings; +@dynamic remoteID; @dynamic role; @dynamic cars; @dynamic employees; diff --git a/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents b/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents index e06aa4c..ba9e251 100644 --- a/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents +++ b/Example/SampleProject/SampleProject.xcdatamodeld/SampleProject.xcdatamodel/contents @@ -1,14 +1,15 @@ - + + - + @@ -28,9 +29,9 @@ - + - + \ No newline at end of file diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index 9b97e51..a1fae32 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -10,6 +10,7 @@ describe(@"Mappings", ^{ NSDictionary *JSON = @{ + @"id": @1, @"first_name": @"Marin", @"last_name": @"Usalj", @"age": @25, @@ -23,20 +24,22 @@ @{ @"id": @6, @"hp": @90, @"make": @"Volkswagen" } ], @"manager": @{ + @"id": @2, @"first_name": @"Delisa", @"last_name": @"Mason", @"age": @25, @"is_member": @NO, // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate + // Know issue: https://github.com/supermarin/ObjectiveRecord/issues/60 // @"cars": @[ // @{ @"id": @3, @"hp": @330, @"make": @"Lamborgini" }, // @{ @"id": @4, @"hp": @240, @"make": @"BMW" } // ] }, @"employees": @[ - @{ @"first_name": @"Luca" }, - @{ @"first_name": @"Tony" }, - @{ @"first_name": @"Jim" } + @{ @"id": @12, @"first_name": @"Luca" }, + @{ @"id": @32, @"first_name": @"Tony" }, + @{ @"id": @15, @"first_name": @"Jim" } ] }; @@ -90,7 +93,7 @@ }); it(@"uses mappings in findOrCreate", ^{ - Person *bob = [Person findOrCreate:@{ @"first_name": @"Bob" } inContext:newContext]; + Person *bob = [Person updateOrCreate:@{ @"first_name": @"Bob" } inContext:newContext]; [[bob.firstName should] equal:@"Bob"]; }); From 1adf17055f534aeba81bec032edf1f8f9649c07f Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 14:06:19 -0400 Subject: [PATCH 22/29] Adds son fixtures & json parser utility (instead of hardcoded dictionary). --- Classes/NSManagedObject+Mappings.m | 2 +- Example/.DS_Store | Bin 6148 -> 8196 bytes .../SampleProject.xcodeproj/project.pbxproj | 52 ++++++++++---- .../SampleProjectTests/Fixtures/people.json | 53 ++++++++++++++ .../Fixtures/people_fail.json | 65 ++++++++++++++++++ Example/SampleProjectTests/MappingsTests.m | 41 ++--------- .../{ => Utilities}/CoreDataManager.h | 0 .../{ => Utilities}/CoreDataManager.m | 0 .../Utilities/JSONUtility.h | 16 +++++ .../Utilities/JSONUtility.m | 39 +++++++++++ 10 files changed, 219 insertions(+), 49 deletions(-) create mode 100644 Example/SampleProjectTests/Fixtures/people.json create mode 100644 Example/SampleProjectTests/Fixtures/people_fail.json rename Example/SampleProjectTests/{ => Utilities}/CoreDataManager.h (100%) rename Example/SampleProjectTests/{ => Utilities}/CoreDataManager.m (100%) create mode 100644 Example/SampleProjectTests/Utilities/JSONUtility.h create mode 100644 Example/SampleProjectTests/Utilities/JSONUtility.m diff --git a/Classes/NSManagedObject+Mappings.m b/Classes/NSManagedObject+Mappings.m index 4745833..1606b80 100644 --- a/Classes/NSManagedObject+Mappings.m +++ b/Classes/NSManagedObject+Mappings.m @@ -62,7 +62,7 @@ + (id)objectOrSetOfObjectsFromValue:(id)value ofClass:class inContext:(NSManaged if ([value isKindOfClass:[NSDictionary class]]) return [class findOrCreate:value inContext:context]; - if ([value isKindOfClass:[NSArray class]]) + if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSSet class]]) return [NSSet setWithArray:[value map:^id(id object) { return [self objectOrSetOfObjectsFromValue:object ofClass:class inContext:context]; }]]; diff --git a/Example/.DS_Store b/Example/.DS_Store index a88747da120d6a1ed3d06d80163fa63d372bf946..51307a2577d3759c3e81ccd0072c2e47d9e115a5 100644 GIT binary patch delta 441 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAD6}zPH}hr%jz7$c**Q2SHn1=X zZRTNNVPcYgIC&nM*<=s4SxgQLlV#X7>XXWg3zBm3lYrWPB^Bgk7MBKu|x9nbKva6q_E7?@^}Fe z=lr~q#LT?ZA|$Ob;hFV$Df#72`K5U&#WBGU1H&^@N;2XFL<5Ra%Yb?V67y2SGK({l zGIKIZDmgeoFkV2iy4uLh%u+|e(8#h@N1@u>+(1Xc#Mr#HR$vwfhqR`tqi>M0|%s^d0AixbITtNnGEd0(qnP0{eWE=w%#AuLh L44dP5<}d>Qdz%%Y diff --git a/Example/SampleProject.xcodeproj/project.pbxproj b/Example/SampleProject.xcodeproj/project.pbxproj index 77534fc..20bb844 100644 --- a/Example/SampleProject.xcodeproj/project.pbxproj +++ b/Example/SampleProject.xcodeproj/project.pbxproj @@ -8,8 +8,14 @@ /* Begin PBXBuildFile section */ 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = 496F953C174CCCBA00220FD1 /* OBRPerson.m */; }; - 4F33C5C1198B097800EB64D1 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */; }; - 4F33C5C2198B097800EB64D1 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */; }; + 4F17D8C01992A2C8009A0D47 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F17D8BD1992A2C8009A0D47 /* CoreDataManager.m */; }; + 4F17D8C11992A2C8009A0D47 /* CoreDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F17D8BD1992A2C8009A0D47 /* CoreDataManager.m */; }; + 4F17D8C21992A2C8009A0D47 /* JSONUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */; }; + 4F17D8C31992A2C8009A0D47 /* JSONUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */; }; + 4F17D8CA1992A321009A0D47 /* people.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8C91992A321009A0D47 /* people.json */; }; + 4F17D8CB1992A321009A0D47 /* people.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8C91992A321009A0D47 /* people.json */; }; + 4F17D8CD1992A5A7009A0D47 /* people_fail.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8CC1992A5A7009A0D47 /* people_fail.json */; }; + 4F17D8CE1992A5A7009A0D47 /* people_fail.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8CC1992A5A7009A0D47 /* people_fail.json */; }; 4F5744B5194ABB0C0099A49E /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F5744B4194ABB0C0099A49E /* Person.m */; }; 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */; }; 6433E5C5184E83D6008EF278 /* Car.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C4184E83D6008EF278 /* Car.m */; }; @@ -51,8 +57,12 @@ 0EE71E2B92554B48A0914E08 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 496F953B174CCCBA00220FD1 /* OBRPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBRPerson.h; sourceTree = ""; }; 496F953C174CCCBA00220FD1 /* OBRPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBRPerson.m; sourceTree = ""; }; - 4F33C5BF198B097800EB64D1 /* CoreDataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataManager.h; sourceTree = ""; }; - 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataManager.m; sourceTree = ""; }; + 4F17D8BC1992A2C8009A0D47 /* CoreDataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataManager.h; sourceTree = ""; }; + 4F17D8BD1992A2C8009A0D47 /* CoreDataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataManager.m; sourceTree = ""; }; + 4F17D8BE1992A2C8009A0D47 /* JSONUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONUtility.h; sourceTree = ""; }; + 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONUtility.m; sourceTree = ""; }; + 4F17D8C91992A321009A0D47 /* people.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = people.json; sourceTree = ""; }; + 4F17D8CC1992A5A7009A0D47 /* people_fail.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = people_fail.json; sourceTree = ""; }; 4F5744B3194ABB0C0099A49E /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; 4F5744B4194ABB0C0099A49E /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsuranceCompany.h; sourceTree = ""; }; @@ -116,13 +126,24 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 4F33C5BE198B096C00EB64D1 /* Utility */ = { + 4F17D8BB1992A2C8009A0D47 /* Utilities */ = { isa = PBXGroup; children = ( - 4F33C5BF198B097800EB64D1 /* CoreDataManager.h */, - 4F33C5C0198B097800EB64D1 /* CoreDataManager.m */, + 4F17D8BC1992A2C8009A0D47 /* CoreDataManager.h */, + 4F17D8BD1992A2C8009A0D47 /* CoreDataManager.m */, + 4F17D8BE1992A2C8009A0D47 /* JSONUtility.h */, + 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */, ); - name = Utility; + path = Utilities; + sourceTree = ""; + }; + 4F17D8C81992A321009A0D47 /* Fixtures */ = { + isa = PBXGroup; + children = ( + 4F17D8C91992A321009A0D47 /* people.json */, + 4F17D8CC1992A5A7009A0D47 /* people_fail.json */, + ); + path = Fixtures; sourceTree = ""; }; 4F9A5CF119914DAA002727E2 /* Mappings */ = { @@ -217,11 +238,12 @@ 89F1EECB15A4C73B00AE4FB4 /* SampleProjectTests */ = { isa = PBXGroup; children = ( - 4F33C5BE198B096C00EB64D1 /* Utility */, - 89F1EECC15A4C73B00AE4FB4 /* Supporting Files */, 897D09FD15B0945400722A8F /* FindersAndCreatorsTests.m */, 8956CE631754EE6A00BD551C /* MappingsTests.m */, 8990C3151785C2F500212182 /* CoreDataManagerTests.m */, + 4F17D8C81992A321009A0D47 /* Fixtures */, + 4F17D8BB1992A2C8009A0D47 /* Utilities */, + 89F1EECC15A4C73B00AE4FB4 /* Supporting Files */, ); path = SampleProjectTests; sourceTree = ""; @@ -310,8 +332,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4F17D8CD1992A5A7009A0D47 /* people_fail.json in Resources */, 89F1EEB415A4C73B00AE4FB4 /* InfoPlist.strings in Resources */, 892C1E91165D54160077F2CB /* Default-568h@2x.png in Resources */, + 4F17D8CA1992A321009A0D47 /* people.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -319,6 +343,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4F17D8CB1992A321009A0D47 /* people.json in Resources */, + 4F17D8CE1992A5A7009A0D47 /* people_fail.json in Resources */, 89F1EED015A4C73B00AE4FB4 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -403,11 +429,12 @@ buildActionMask = 2147483647; files = ( 6433E5C5184E83D6008EF278 /* Car.m in Sources */, + 4F17D8C01992A2C8009A0D47 /* CoreDataManager.m in Sources */, 89F1EEB615A4C73B00AE4FB4 /* main.m in Sources */, 4F5744B5194ABB0C0099A49E /* Person.m in Sources */, 89F1EEBA15A4C73B00AE4FB4 /* AppDelegate.m in Sources */, FA91A5E91875B9FE00BE74DD /* InsuranceCompany+Mappings.m in Sources */, - 4F33C5C1198B097800EB64D1 /* CoreDataManager.m in Sources */, + 4F17D8C21992A2C8009A0D47 /* JSONUtility.m in Sources */, 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */, 89F1EEBD15A4C73B00AE4FB4 /* SampleProject.xcdatamodeld in Sources */, 496F953D174CCCBA00220FD1 /* OBRPerson.m in Sources */, @@ -420,10 +447,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4F17D8C11992A2C8009A0D47 /* CoreDataManager.m in Sources */, 897D09FE15B0945400722A8F /* FindersAndCreatorsTests.m in Sources */, 89702F25173E57AA00149BD5 /* SampleProject.xcdatamodeld in Sources */, - 4F33C5C2198B097800EB64D1 /* CoreDataManager.m in Sources */, 8956CE641754EE6A00BD551C /* MappingsTests.m in Sources */, + 4F17D8C31992A2C8009A0D47 /* JSONUtility.m in Sources */, 8990C3161785C2F500212182 /* CoreDataManagerTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Example/SampleProjectTests/Fixtures/people.json b/Example/SampleProjectTests/Fixtures/people.json new file mode 100644 index 0000000..b108998 --- /dev/null +++ b/Example/SampleProjectTests/Fixtures/people.json @@ -0,0 +1,53 @@ +{ + "id": 1, + "first_name": "Marin", + "last_name": "Usalj", + "age": 30, + "is_member": true, + "profile": { + "role": "CEO", + "life_savings": 1500.12 + }, + "cars": [ + { + "id": 5, + "hp": 220, + "make": "Trabant" + }, + { + "id": 6, + "hp": 90, + "make": "Volkswagen" + } + ], + "manager": { + "id": 2, + "first_name": "Delisa", + "last_name": "Mason", + "age": 35, + "is_member": true + }, + "employees": [ + { + "id": 12, + "first_name": "Luca", + "last_name": "Madison", + "age": 31, + "is_member": false + }, + { + "id": 32, + "first_name": "Tony", + "last_name": "Stark", + "age": 33, + "is_member": false + }, + { + "id": 15, + "first_name": "Jim", + "last_name": "Carey", + "age": 47, + "is_member": true + } + ] +} \ No newline at end of file diff --git a/Example/SampleProjectTests/Fixtures/people_fail.json b/Example/SampleProjectTests/Fixtures/people_fail.json new file mode 100644 index 0000000..4aded63 --- /dev/null +++ b/Example/SampleProjectTests/Fixtures/people_fail.json @@ -0,0 +1,65 @@ +{ + "id": 1, + "first_name": "Marin", + "last_name": "Usalj", + "age": 30, + "is_member": true, + "profile": { + "role": "CEO", + "life_savings": 1500.12 + }, + "cars": [ + { + "id": 5, + "hp": 220, + "make": "Trabant" + }, + { + "id": 6, + "hp": 90, + "make": "Volkswagen" + } + ], + "manager": { + "id": 2, + "first_name": "Delisa", + "last_name": "Mason", + "age": 35, + "is_member": true, + "cars": [ + { + "id": 3, + "hp": 330, + "make": "Lamborgini" + }, + { + "id": 4, + "hp": 240, + "make": "BMW" + } + ] + }, + "employees": [ + { + "id": 12, + "first_name": "Luca", + "last_name": "Madison", + "age": 31, + "is_member": false + }, + { + "id": 32, + "first_name": "Tony", + "last_name": "Stark", + "age": 33, + "is_member": false + }, + { + "id": 15, + "first_name": "Jim", + "last_name": "Carey", + "age": 47, + "is_member": true + } + ] +} \ No newline at end of file diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index a1fae32..c36667d 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -4,52 +4,21 @@ #import "Car+Mappings.h" #import "InsuranceCompany.h" #import "CoreDataManager.h" +#import "JSONUtility.h" SPEC_BEGIN(MappingsTests) describe(@"Mappings", ^{ - NSDictionary *JSON = @{ - @"id": @1, - @"first_name": @"Marin", - @"last_name": @"Usalj", - @"age": @25, - @"is_member": @"true", - @"profile": @{ - @"role": @"CEO", - @"life_savings": @1500.12, - }, - @"cars": @[ - @{ @"id": @5, @"hp": @220, @"make": @"Trabant" }, - @{ @"id": @6, @"hp": @90, @"make": @"Volkswagen" } - ], - @"manager": @{ - @"id": @2, - @"first_name": @"Delisa", - @"last_name": @"Mason", - @"age": @25, - @"is_member": @NO, - // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate - // Know issue: https://github.com/supermarin/ObjectiveRecord/issues/60 -// @"cars": @[ -// @{ @"id": @3, @"hp": @330, @"make": @"Lamborgini" }, -// @{ @"id": @4, @"hp": @240, @"make": @"BMW" } -// ] - }, - @"employees": @[ - @{ @"id": @12, @"first_name": @"Luca" }, - @{ @"id": @32, @"first_name": @"Tony" }, - @{ @"id": @15, @"first_name": @"Jim" } - ] - }; - + NSDictionary *payload = JSON(@"people"); + __block Person *person; NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; newContext.persistentStoreCoordinator = [[CoreDataManager sharedManager] persistentStoreCoordinator]; beforeEach(^{ - person = [Person create:JSON inContext:newContext]; + person = [Person create:payload inContext:newContext]; }); it(@"caches mappings", ^{ @@ -73,7 +42,7 @@ it(@"uses mapped values when creating", ^{ [[person.firstName should] equal:@"Marin"]; [[person.lastName should] equal:@"Usalj"]; - [[person.age should] equal:@25]; + [[person.age should] equal:@30]; }); it(@"can support snake_case even without mappings", ^{ diff --git a/Example/SampleProjectTests/CoreDataManager.h b/Example/SampleProjectTests/Utilities/CoreDataManager.h similarity index 100% rename from Example/SampleProjectTests/CoreDataManager.h rename to Example/SampleProjectTests/Utilities/CoreDataManager.h diff --git a/Example/SampleProjectTests/CoreDataManager.m b/Example/SampleProjectTests/Utilities/CoreDataManager.m similarity index 100% rename from Example/SampleProjectTests/CoreDataManager.m rename to Example/SampleProjectTests/Utilities/CoreDataManager.m diff --git a/Example/SampleProjectTests/Utilities/JSONUtility.h b/Example/SampleProjectTests/Utilities/JSONUtility.h new file mode 100644 index 0000000..d9f9c8b --- /dev/null +++ b/Example/SampleProjectTests/Utilities/JSONUtility.h @@ -0,0 +1,16 @@ +// +// JSONUtility.h +// SampleProject +// +// Created by Ignacio Romero Z. on 8/6/14. +// +// + +#import + +@interface JSONUtility : NSObject + +id JSON(NSString *resource); +id JSONFromBundle(NSString *resource, NSBundle *bundle); + +@end diff --git a/Example/SampleProjectTests/Utilities/JSONUtility.m b/Example/SampleProjectTests/Utilities/JSONUtility.m new file mode 100644 index 0000000..31072d8 --- /dev/null +++ b/Example/SampleProjectTests/Utilities/JSONUtility.m @@ -0,0 +1,39 @@ +// +// JSONUtility.m +// SampleProject +// +// Created by Ignacio Romero Z. on 8/6/14. +// +// + +#import "JSONUtility.h" + +@implementation JSONUtility + +id JSON(NSString *resource) { + return JSONFromBundle(resource, [NSBundle mainBundle]); +} + +id JSONFromBundle(NSString *resource, NSBundle *bundle) { + NSError *error = nil; + NSString *path = [bundle pathForResource:resource ofType:@"json"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + + if (!data) { + NSLog(@"Failed with json at path : %@", path); + return nil; + } + + id JSON = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions|NSJSONWritingPrettyPrinted error:&error]; + + if (error) { + NSLog(@"error : %@", error.localizedDescription); + return nil; + } + + NSLog(@"Parsed %@ successfuly : %@", resource, JSON); + + return JSON; +} + +@end From 81b601859a460a8c91a4c113c2974788cfcb6954 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 14:16:14 -0400 Subject: [PATCH 23/29] Minor minor test change. --- Example/.DS_Store | Bin 8196 -> 8196 bytes Example/SampleProjectTests/.DS_Store | Bin 0 -> 6148 bytes Example/SampleProjectTests/MappingsTests.m | 8 ++++++-- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Example/SampleProjectTests/.DS_Store diff --git a/Example/.DS_Store b/Example/.DS_Store index 51307a2577d3759c3e81ccd0072c2e47d9e115a5..a3fc5fe15a6a1186a5216df34d22127d433dfc50 100644 GIT binary patch delta 18 ZcmZp1XmQveD8%?^@;o84%^pH~cmY5K295v# delta 18 ZcmZp1XmQveD8%@1@;o84%^pH~cmY5A28{p! diff --git a/Example/SampleProjectTests/.DS_Store b/Example/SampleProjectTests/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Wed, 6 Aug 2014 13:21:11 -0700 Subject: [PATCH 24/29] added fail to appdelegate --- Example/.DS_Store | Bin 8196 -> 12292 bytes .../contents.xcworkspacedata | 7 +++++++ .../xcschemes/SampleProject.xcscheme | 4 ++-- Example/SampleProject/AppDelegate.m | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 Example/SampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Example/.DS_Store b/Example/.DS_Store index a3fc5fe15a6a1186a5216df34d22127d433dfc50..2ff99726efb90d0fc99c1f87683b136480a701f9 100644 GIT binary patch delta 136 zcmZp1Xi3<>BFHwAk%56heDVcB#mVahc|~&bU0hO1OOhEFE^wGk07@ZAPOcK<;=&M4 zU}j)gJ9(av86T?N$#aA(Cie+(GXu>5vR#=N1SU6%Xl~{a{=u`cp`9IsCpLTn04PK# A!~g&Q delta 125 zcmZokXmQxUBFNUWh=GAYeDVcB#mVahc|~&bU0hO1OOhEF&L7zG0w{$fIk`%Ziwi?I tftgYI(d2nTW_$>}7uc5HoIFR!Vsf7lH#3Co%Eag}xlu%OGmr2O9su>DDEj~a diff --git a/Example/SampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/SampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..012cfe5 --- /dev/null +++ b/Example/SampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme index 8f3bca4..d69ff2f 100644 --- a/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme +++ b/Example/SampleProject.xcodeproj/xcshareddata/xcschemes/SampleProject.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -28,7 +28,7 @@ buildForAnalyzing = "YES"> diff --git a/Example/SampleProject/AppDelegate.m b/Example/SampleProject/AppDelegate.m index 14047d3..144fdf4 100644 --- a/Example/SampleProject/AppDelegate.m +++ b/Example/SampleProject/AppDelegate.m @@ -8,6 +8,8 @@ #import "AppDelegate.h" #import "CoreDataManager.h" +#import "JSONUtility.h" +#import "Person+Mappings.h" @implementation AppDelegate @@ -22,6 +24,21 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [CoreDataManager sharedManager]; + __block Person *person; + + NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; + newContext.persistentStoreCoordinator = [[CoreDataManager sharedManager] persistentStoreCoordinator]; + + //NSDictionary *payload = JSON(@"people"); + + // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate + // Known issue: https://github.com/supermarin/ObjectiveRecord/issues/60 + NSDictionary *payload = JSON(@"people_fail"); + + person = [Person create:payload inContext:newContext]; + + NSLog(@"%@", [person description]); + return YES; } From 3e74bfa9c3bcd27276d33c182766140bb154f8a9 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 17:23:33 -0400 Subject: [PATCH 25/29] Fixes crash when fetching one-to-many relationship with higher level of deepness. Fixes #60 with error message 'to-many key not allowed here' --- Classes/NSManagedObject+ActiveRecord.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index 22466dc..a73d876 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -231,9 +231,14 @@ + (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSM + (NSPredicate *)predicateFromDictionary:(NSDictionary *)dict { NSArray *subpredicates = [dict map:^(NSString *key, id value) { - return [NSPredicate predicateWithFormat:@"%K = %@", key, value]; + if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSSet class]]) { + return (id)nil; + } + else { + return (id)[NSPredicate predicateWithFormat:@"%K = %@", key, value]; + } }]; - + return [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; } From 652727b2eadfc629055abe76bbfcf99fb5c50ad1 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 17:23:58 -0400 Subject: [PATCH 26/29] Updates sample project --- .gitignore | 1 + Example/.DS_Store | Bin 12292 -> 8196 bytes .../SampleProject.xcodeproj/project.pbxproj | 6 -- .../SampleProjectTests/Fixtures/people.json | 14 +++- .../Fixtures/people_fail.json | 65 ------------------ Example/SampleProjectTests/MappingsTests.m | 4 -- 6 files changed, 14 insertions(+), 76 deletions(-) delete mode 100644 Example/SampleProjectTests/Fixtures/people_fail.json diff --git a/.gitignore b/.gitignore index 29810c1..b91b548 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.log Podfile.lock +.DS_Store \ No newline at end of file diff --git a/Example/.DS_Store b/Example/.DS_Store index 2ff99726efb90d0fc99c1f87683b136480a701f9..13d35e9eb0ff09ce2819c2afb910abb75177c128 100644 GIT binary patch delta 114 zcmZokXmQxUBFNUWh=GAYeDVcB#mVahc|~&bU0hO1OOhEF&L7zG0w{$fIk`%Ziwi?I oktvLO@;o84$sR&HOxAxU&k?ei+y`U2F&0d26w%zwBm9F005qf|_y7O^ delta 125 zcmZp1Xi3<>BFHwAk%56heDVcB#mVahc|~&bU0hO1OOhEFE^wGk07@ZAPOcK<;=&M4 xWMWu5d7hBjWDg-8CX)%1=LlI$?t?Mi7zHLbifC@;5&prmv7wzEgeNw90sxkjCA|Ou diff --git a/Example/SampleProject.xcodeproj/project.pbxproj b/Example/SampleProject.xcodeproj/project.pbxproj index 20bb844..5b89860 100644 --- a/Example/SampleProject.xcodeproj/project.pbxproj +++ b/Example/SampleProject.xcodeproj/project.pbxproj @@ -14,8 +14,6 @@ 4F17D8C31992A2C8009A0D47 /* JSONUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */; }; 4F17D8CA1992A321009A0D47 /* people.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8C91992A321009A0D47 /* people.json */; }; 4F17D8CB1992A321009A0D47 /* people.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8C91992A321009A0D47 /* people.json */; }; - 4F17D8CD1992A5A7009A0D47 /* people_fail.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8CC1992A5A7009A0D47 /* people_fail.json */; }; - 4F17D8CE1992A5A7009A0D47 /* people_fail.json in Resources */ = {isa = PBXBuildFile; fileRef = 4F17D8CC1992A5A7009A0D47 /* people_fail.json */; }; 4F5744B5194ABB0C0099A49E /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F5744B4194ABB0C0099A49E /* Person.m */; }; 6433E5C2184E83C2008EF278 /* InsuranceCompany.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C1184E83C2008EF278 /* InsuranceCompany.m */; }; 6433E5C5184E83D6008EF278 /* Car.m in Sources */ = {isa = PBXBuildFile; fileRef = 6433E5C4184E83D6008EF278 /* Car.m */; }; @@ -62,7 +60,6 @@ 4F17D8BE1992A2C8009A0D47 /* JSONUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONUtility.h; sourceTree = ""; }; 4F17D8BF1992A2C8009A0D47 /* JSONUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONUtility.m; sourceTree = ""; }; 4F17D8C91992A321009A0D47 /* people.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = people.json; sourceTree = ""; }; - 4F17D8CC1992A5A7009A0D47 /* people_fail.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = people_fail.json; sourceTree = ""; }; 4F5744B3194ABB0C0099A49E /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; 4F5744B4194ABB0C0099A49E /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; 6433E5C0184E83C2008EF278 /* InsuranceCompany.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsuranceCompany.h; sourceTree = ""; }; @@ -141,7 +138,6 @@ isa = PBXGroup; children = ( 4F17D8C91992A321009A0D47 /* people.json */, - 4F17D8CC1992A5A7009A0D47 /* people_fail.json */, ); path = Fixtures; sourceTree = ""; @@ -332,7 +328,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4F17D8CD1992A5A7009A0D47 /* people_fail.json in Resources */, 89F1EEB415A4C73B00AE4FB4 /* InfoPlist.strings in Resources */, 892C1E91165D54160077F2CB /* Default-568h@2x.png in Resources */, 4F17D8CA1992A321009A0D47 /* people.json in Resources */, @@ -344,7 +339,6 @@ buildActionMask = 2147483647; files = ( 4F17D8CB1992A321009A0D47 /* people.json in Resources */, - 4F17D8CE1992A5A7009A0D47 /* people_fail.json in Resources */, 89F1EED015A4C73B00AE4FB4 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Example/SampleProjectTests/Fixtures/people.json b/Example/SampleProjectTests/Fixtures/people.json index b108998..4aded63 100644 --- a/Example/SampleProjectTests/Fixtures/people.json +++ b/Example/SampleProjectTests/Fixtures/people.json @@ -25,7 +25,19 @@ "first_name": "Delisa", "last_name": "Mason", "age": 35, - "is_member": true + "is_member": true, + "cars": [ + { + "id": 3, + "hp": 330, + "make": "Lamborgini" + }, + { + "id": 4, + "hp": 240, + "make": "BMW" + } + ] }, "employees": [ { diff --git a/Example/SampleProjectTests/Fixtures/people_fail.json b/Example/SampleProjectTests/Fixtures/people_fail.json deleted file mode 100644 index 4aded63..0000000 --- a/Example/SampleProjectTests/Fixtures/people_fail.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "id": 1, - "first_name": "Marin", - "last_name": "Usalj", - "age": 30, - "is_member": true, - "profile": { - "role": "CEO", - "life_savings": 1500.12 - }, - "cars": [ - { - "id": 5, - "hp": 220, - "make": "Trabant" - }, - { - "id": 6, - "hp": 90, - "make": "Volkswagen" - } - ], - "manager": { - "id": 2, - "first_name": "Delisa", - "last_name": "Mason", - "age": 35, - "is_member": true, - "cars": [ - { - "id": 3, - "hp": 330, - "make": "Lamborgini" - }, - { - "id": 4, - "hp": 240, - "make": "BMW" - } - ] - }, - "employees": [ - { - "id": 12, - "first_name": "Luca", - "last_name": "Madison", - "age": 31, - "is_member": false - }, - { - "id": 32, - "first_name": "Tony", - "last_name": "Stark", - "age": 33, - "is_member": false - }, - { - "id": 15, - "first_name": "Jim", - "last_name": "Carey", - "age": 47, - "is_member": true - } - ] -} \ No newline at end of file diff --git a/Example/SampleProjectTests/MappingsTests.m b/Example/SampleProjectTests/MappingsTests.m index cc794f8..0bb4bea 100644 --- a/Example/SampleProjectTests/MappingsTests.m +++ b/Example/SampleProjectTests/MappingsTests.m @@ -17,10 +17,6 @@ NSDictionary *payload = JSON(@"people"); - // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate - // Known issue: https://github.com/supermarin/ObjectiveRecord/issues/60 - //NSDictionary *payload = JSON(@"people_fail"); - beforeEach(^{ person = [Person create:payload inContext:newContext]; }); From 93406ade83c06afa3e76f38a42fd4d8fe2fd9117 Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 23:17:06 -0400 Subject: [PATCH 27/29] Returns a IN predicate operation for containing one-to-many relationships --- Classes/NSManagedObject+ActiveRecord.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/NSManagedObject+ActiveRecord.m b/Classes/NSManagedObject+ActiveRecord.m index a73d876..ba9c44e 100644 --- a/Classes/NSManagedObject+ActiveRecord.m +++ b/Classes/NSManagedObject+ActiveRecord.m @@ -232,7 +232,7 @@ + (NSPredicate *)predicateFromDictionary:(NSDictionary *)dict { NSArray *subpredicates = [dict map:^(NSString *key, id value) { if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSSet class]]) { - return (id)nil; + return (id)[NSPredicate predicateWithFormat:@"%@ IN %K", value, key]; } else { return (id)[NSPredicate predicateWithFormat:@"%K = %@", key, value]; From d4a8085ef0aace093c726fbfd0040c665cc7405e Mon Sep 17 00:00:00 2001 From: dzenbot Date: Wed, 6 Aug 2014 23:20:33 -0400 Subject: [PATCH 28/29] Clean the AppDelegate of the sample project --- Example/SampleProject/AppDelegate.m | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/Example/SampleProject/AppDelegate.m b/Example/SampleProject/AppDelegate.m index 144fdf4..ed935fc 100644 --- a/Example/SampleProject/AppDelegate.m +++ b/Example/SampleProject/AppDelegate.m @@ -8,8 +8,6 @@ #import "AppDelegate.h" #import "CoreDataManager.h" -#import "JSONUtility.h" -#import "Person+Mappings.h" @implementation AppDelegate @@ -22,32 +20,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; - [CoreDataManager sharedManager]; - - __block Person *person; - - NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; - newContext.persistentStoreCoordinator = [[CoreDataManager sharedManager] persistentStoreCoordinator]; - - //NSDictionary *payload = JSON(@"people"); - - // TODO: A 3-level-deep relationship will cause a crash, due to an invalid predicate - // Known issue: https://github.com/supermarin/ObjectiveRecord/issues/60 - NSDictionary *payload = JSON(@"people_fail"); - - person = [Person create:payload inContext:newContext]; - - NSLog(@"%@", [person description]); - return YES; } - -- (void)applicationWillTerminate:(UIApplication *)application -{ - // Saves changes in the application's managed object context before the application terminates. - [[CoreDataManager sharedManager] saveContext]; -} - - @end From 4411a50097cf67c0f6a43f0a2da64ec7260c515b Mon Sep 17 00:00:00 2001 From: dzenbot Date: Mon, 29 Sep 2014 18:59:58 -0300 Subject: [PATCH 29/29] Updates pod spec --- ObjectiveRecord.podspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ObjectiveRecord.podspec b/ObjectiveRecord.podspec index ec9a1eb..0638828 100644 --- a/ObjectiveRecord.podspec +++ b/ObjectiveRecord.podspec @@ -1,4 +1,4 @@ -@version = "1.5.3" +@version = "1.7" Pod::Spec.new do |s| s.name = "ObjectiveRecord" @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { "Marin Usalj" => "mneorr@gmail.com" } - s.source = { :git => "https://github.com/DZNLabs/ObjectiveRecord.git", :tag => @version } + s.source = { :git => "https://github.com/tinyspeck/ObjectiveRecord.git", :tag => @version } s.source_files = 'Classes/**/*.{h,m}' s.framework = 'CoreData' @@ -18,4 +18,4 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.6' s.dependency 'ObjectiveSugar' -end +end \ No newline at end of file