From 49bae5cf0316db88339a92b089426680830ac00e Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sat, 17 Feb 2018 09:26:34 -0500 Subject: [PATCH 1/3] Properly update offline cache with latest version of the object --- .../OfflineStore/PFOfflineStore.m | 17 +++++++++++++---- Parse/Tests/Unit/QueryUnitTests.m | 19 ------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m b/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m index f178dd32d..48347c9b1 100644 --- a/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m +++ b/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m @@ -15,6 +15,7 @@ #import "PFAssert.h" #import "PFDecoder.h" #import "PFEncoder.h" +#import "PFLogging.h" #import "PFErrorUtilities.h" #import "PFFileManager.h" #import "PFJSONSerialization.h" @@ -1028,15 +1029,23 @@ - (void)updateObjectIdForObject:(PFObject *)object @synchronized(self.lock) { // See if there's already an entry for new objectId. PFObject *existing = [self.classNameAndObjectIdToObjectMap objectForKey:key]; - PFConsistencyAssert(existing == nil || existing == object, - @"Attempted to change an objectId to one that's already known to the OfflineStore. className: %@ old: %@, new: %@", - className, oldObjectId, newObjectId); - + if (existing != nil && existing != object) { + PFLogError(PFLoggingTagCommon, + @"Attempted to change an objectId to one that's already known to the OfflineStore. className: %@ old: %@, new: %@", + className, oldObjectId, newObjectId); + PFLogError(PFLoggingTagCommon, + @"Set a breakpoint on PFOfflineStoreAttemptedToChange() to debug the issue"); + PFLogError(PFLoggingTagCommon, + @"Starting 1.17.0, the new object will replace the old one, if this is causing unexpected behaviours, please open an issue https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/new"); + PFOfflineStoreAttemptedToChange(); + } // Okay, all clear to add the new reference. [self.classNameAndObjectIdToObjectMap setObject:object forKey:key]; } } +void PFOfflineStoreAttemptedToChange() {} + - (NSString *)_generateKeyForClassName:(NSString *)className objectId:(NSString *)objectId { return [NSString stringWithFormat:@"%@:%@", className, objectId]; diff --git a/Parse/Tests/Unit/QueryUnitTests.m b/Parse/Tests/Unit/QueryUnitTests.m index a1da7d8c4..25c060c85 100644 --- a/Parse/Tests/Unit/QueryUnitTests.m +++ b/Parse/Tests/Unit/QueryUnitTests.m @@ -1413,23 +1413,4 @@ - (void)testHash { XCTAssertEqual([queryA hash], [queryB hash]); } -- (void)testReproduceIssue1202 { - [[Parse _currentManager] clearEventuallyQueue]; - [Parse _clearCurrentManager]; - [Parse enableLocalDatastore]; - [Parse setApplicationId:@"a" clientKey:@"b"]; - PFObject *objectA = [PFObject objectWithClassName:@"Object" dictionary:@{@"objectId":@"yolo", @"key": @"value"}]; - objectA.objectId = @"yolo"; - PFObject *objectB = [PFObject objectWithClassName:@"Object" dictionary:@{@"objectId":@"yolo", @"key": @"value"}]; - @try { - objectB.objectId = @"yolo"; - XCTFail(); - } - @catch (NSException *e) { - XCTAssertEqual(e.name, NSInternalInconsistencyException); - XCTAssertEqualObjects(e.reason, @"Attempted to change an objectId to one that's already known to the OfflineStore. className: Object old: (null), new: yolo"); - } -} - - @end From 462347113aee80f98ae2bf134391ce7c747e6d3e Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sat, 17 Feb 2018 13:53:43 -0500 Subject: [PATCH 2/3] Proper name --- .../Internal/LocalDataStore/OfflineStore/PFOfflineStore.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m b/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m index 48347c9b1..4ff79b01a 100644 --- a/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m +++ b/Parse/Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m @@ -1034,17 +1034,17 @@ - (void)updateObjectIdForObject:(PFObject *)object @"Attempted to change an objectId to one that's already known to the OfflineStore. className: %@ old: %@, new: %@", className, oldObjectId, newObjectId); PFLogError(PFLoggingTagCommon, - @"Set a breakpoint on PFOfflineStoreAttemptedToChange() to debug the issue"); + @"Set a breakpoint on PFOfflineStoreReplaceExisingObject() to debug the issue"); PFLogError(PFLoggingTagCommon, @"Starting 1.17.0, the new object will replace the old one, if this is causing unexpected behaviours, please open an issue https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/new"); - PFOfflineStoreAttemptedToChange(); + PFOfflineStoreReplaceExisingObject(); } // Okay, all clear to add the new reference. [self.classNameAndObjectIdToObjectMap setObject:object forKey:key]; } } -void PFOfflineStoreAttemptedToChange() {} +void PFOfflineStoreReplaceExisingObject() {} - (NSString *)_generateKeyForClassName:(NSString *)className objectId:(NSString *)objectId { From 0695ed3ff11f5726b8c9976536711bc42a6a1c51 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 18 Feb 2018 13:48:14 -0500 Subject: [PATCH 3/3] Adds test asserting the object is properly replaced --- Parse/Tests/Unit/QueryUnitTests.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Parse/Tests/Unit/QueryUnitTests.m b/Parse/Tests/Unit/QueryUnitTests.m index 25c060c85..a9ccda784 100644 --- a/Parse/Tests/Unit/QueryUnitTests.m +++ b/Parse/Tests/Unit/QueryUnitTests.m @@ -1413,4 +1413,18 @@ - (void)testHash { XCTAssertEqual([queryA hash], [queryB hash]); } +- (void)testReproduceIssue1202 { + [[Parse _currentManager] clearEventuallyQueue]; + [Parse _clearCurrentManager]; + [Parse enableLocalDatastore]; + [Parse setApplicationId:@"a" clientKey:@"b"]; + PFObject *objectA = [PFObject objectWithClassName:@"Object" dictionary:@{@"objectId":@"yolo", @"key": @"value"}]; + objectA.objectId = @"yolo"; + PFObject *objectB = [PFObject objectWithClassName:@"Object" dictionary:@{@"objectId":@"yolo", @"key": @"value2"}]; + objectB.objectId = @"yolo"; + PFObject *currentObject = [PFObject objectWithoutDataWithClassName:@"Object" objectId:@"yolo"]; + XCTAssertEqual(currentObject[@"key"], @"value2"); +} + + @end