Skip to content

Commit 4f7e55a

Browse files
author
Jorge Leandro Perez
authored
Merge pull request #606 from Simperium/issue/ephemeral-storage
Enabling JSONStorage Support
2 parents 82554ea + b85d05e commit 4f7e55a

16 files changed

Lines changed: 309 additions & 81 deletions

Simperium.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
B57421D52510FA67006F2A71 /* NSURLRequest+Simperium.h in Headers */ = {isa = PBXBuildFile; fileRef = B57421D22510FA67006F2A71 /* NSURLRequest+Simperium.h */; };
5353
B57421D62510FA67006F2A71 /* NSURLRequest+Simperium.m in Sources */ = {isa = PBXBuildFile; fileRef = B57421D32510FA67006F2A71 /* NSURLRequest+Simperium.m */; };
5454
B57421D72510FA67006F2A71 /* NSURLRequest+Simperium.m in Sources */ = {isa = PBXBuildFile; fileRef = B57421D32510FA67006F2A71 /* NSURLRequest+Simperium.m */; };
55+
B57CFA1C25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CFA1A25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h */; };
56+
B57CFA1D25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CFA1A25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h */; };
57+
B57CFA1E25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = B57CFA1B25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m */; };
58+
B57CFA1F25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = B57CFA1B25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m */; };
59+
B57CFA2925B1100600ABA284 /* SPThreadsafeMutableDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B57CFA2825B1100600ABA284 /* SPThreadsafeMutableDictionaryTests.m */; };
5560
B57FA3AE190052C800957205 /* MockStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B57FA3AD190052C800957205 /* MockStorage.m */; };
5661
B57FA3B21900568A00957205 /* SPRelationshipResolverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B57FA3B11900568A00957205 /* SPRelationshipResolverTests.m */; };
5762
B585125A2485FE32002BD70C /* SPAuthenticationValidatorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B58512592485FE32002BD70C /* SPAuthenticationValidatorTests.m */; };
@@ -603,6 +608,9 @@
603608
B5728F9B250FD4A700D1DA07 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = DEVELOPER_DIR; };
604609
B57421D22510FA67006F2A71 /* NSURLRequest+Simperium.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSURLRequest+Simperium.h"; sourceTree = "<group>"; };
605610
B57421D32510FA67006F2A71 /* NSURLRequest+Simperium.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSURLRequest+Simperium.m"; sourceTree = "<group>"; };
611+
B57CFA1A25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPThreadsafeMutableDictionary.h; sourceTree = "<group>"; };
612+
B57CFA1B25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SPThreadsafeMutableDictionary.m; sourceTree = "<group>"; };
613+
B57CFA2825B1100600ABA284 /* SPThreadsafeMutableDictionaryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SPThreadsafeMutableDictionaryTests.m; sourceTree = "<group>"; };
606614
B57FA3AC190052C800957205 /* MockStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockStorage.h; sourceTree = "<group>"; };
607615
B57FA3AD190052C800957205 /* MockStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MockStorage.m; sourceTree = "<group>"; };
608616
B57FA3B11900568A00957205 /* SPRelationshipResolverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPRelationshipResolverTests.m; sourceTree = "<group>"; };
@@ -900,6 +908,8 @@
900908
24A73F5517E250E0000CA275 /* SPPersistentMutableDictionary.m */,
901909
B5EC2C2318858E3E0067E3B8 /* SPPersistentMutableSet.h */,
902910
B5EC2C2418858E3E0067E3B8 /* SPPersistentMutableSet.m */,
911+
B57CFA1A25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h */,
912+
B57CFA1B25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m */,
903913
B5549FE118457F72007EA226 /* SPThreadsafeMutableSet.h */,
904914
B5549FE218457F72007EA226 /* SPThreadsafeMutableSet.m */,
905915
B5EB86981822E34F007450FF /* SPLogger.h */,
@@ -1232,6 +1242,7 @@
12321242
B5C7D7F8183411B900E9109C /* SPPersistentMutableDictionaryTests.m */,
12331243
B5EC2C27188595420067E3B8 /* SPPersistentMutableSetTests.m */,
12341244
B5549FE5184581BF007EA226 /* SPThreadsafeMutableSetTests.m */,
1245+
B57CFA2825B1100600ABA284 /* SPThreadsafeMutableDictionaryTests.m */,
12351246
B597DD58183128FE005E95D7 /* SPWebSocketInterfaceTests.m */,
12361247
B5DE0E0E1850D0200080C44D /* SPCoreDataStorageTests.m */,
12371248
B5DF229418B41FB700874C75 /* SPMemberJSONTests.m */,
@@ -1359,6 +1370,7 @@
13591370
B5FC08BA1D662D5300045DB9 /* TrustKit+Private.h in Headers */,
13601371
B5CAA4C11CAAB40F006FE048 /* SPNetworkInterface.h in Headers */,
13611372
B5CAA4C61CAAB44E006FE048 /* SPStorageProvider.h in Headers */,
1373+
B57CFA1C25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h in Headers */,
13621374
B5CAA4C01CAAB405006FE048 /* SPUser.h in Headers */,
13631375
B5CAA4C81CAAB50E006FE048 /* SPSwizzle.h in Headers */,
13641376
B5FC08A21D662D5300045DB9 /* parse_configuration.h in Headers */,
@@ -1441,6 +1453,7 @@
14411453
B5F6A4C3251024380001D7E3 /* NSURLSession+Simperium.h in Headers */,
14421454
B5CAA5BA1CAAED3D006FE048 /* Simperium.h in Headers */,
14431455
B5A8773522DCD37F00FC22C7 /* SPAuthenticationInterface.h in Headers */,
1456+
B57CFA1D25B10B7100ABA284 /* SPThreadsafeMutableDictionary.h in Headers */,
14441457
B5CAA5BC1CAAED3D006FE048 /* SPAuthenticationConfiguration.h in Headers */,
14451458
B5CAA5BD1CAAED3D006FE048 /* SPAuthenticator.h in Headers */,
14461459
B5CAA5BE1CAAED3D006FE048 /* SPBucket.h in Headers */,
@@ -1776,6 +1789,7 @@
17761789
B5CAA5491CAABC16006FE048 /* SPNetworkInterface.m in Sources */,
17771790
B5CAA54A1CAABC1D006FE048 /* SPProcessorConstants.m in Sources */,
17781791
B5CAA6511CAAF2F8006FE048 /* SPAuthenticationViewController.m in Sources */,
1792+
B57CFA1E25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m in Sources */,
17791793
B5CAA54B1CAABC23006FE048 /* NSError+Simperium.m in Sources */,
17801794
);
17811795
runOnlyForDeploymentPostprocessing = 0;
@@ -1860,6 +1874,7 @@
18601874
B5CAA5AD1CAAED3D006FE048 /* SPNetworkInterface.m in Sources */,
18611875
B5CAA5AE1CAAED3D006FE048 /* SPProcessorConstants.m in Sources */,
18621876
B5CAA5AF1CAAED3D006FE048 /* NSError+Simperium.m in Sources */,
1877+
B57CFA1F25B10B7100ABA284 /* SPThreadsafeMutableDictionary.m in Sources */,
18631878
B5CAA63E1CAAF1D9006FE048 /* SPAuthenticationButtonCell.m in Sources */,
18641879
);
18651880
runOnlyForDeploymentPostprocessing = 0;
@@ -1868,6 +1883,7 @@
18681883
isa = PBXSourcesBuildPhase;
18691884
buildActionMask = 2147483647;
18701885
files = (
1886+
B57CFA2925B1100600ABA284 /* SPThreadsafeMutableDictionaryTests.m in Sources */,
18711887
B53F75A91A1BAB4600C0DDFB /* SPStorageObserverAdapter.m in Sources */,
18721888
B565ECA31832643000D162FF /* TestObject.m in Sources */,
18731889
B57FA3AE190052C800957205 /* MockStorage.m in Sources */,

Simperium/SPBucket.m

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,25 @@ - (void)statsWithCallback:(SPBucketStatsCallback)callback {
158158
}
159159

160160
- (NSString *)lastChangeSignature {
161-
if (!_lastChangeSignature) {
162-
// Load it
161+
// Load it: Skip for Ephemeral Storage
162+
if (!_lastChangeSignature && !_storage.isEphemeral) {
163163
NSString *sigKey = [NSString stringWithFormat:@"lastChangeSignature-%@", self.instanceLabel];
164164
NSString *signature = [[NSUserDefaults standardUserDefaults] objectForKey:sigKey];
165165
_lastChangeSignature = [signature copy];
166166
}
167+
167168
return _lastChangeSignature;
168169
}
169170

170171
- (void)setLastChangeSignature:(NSString *)signature {
172+
171173
_lastChangeSignature = [signature copy];
172174

173-
// Persist it
175+
// Persist it: Skip for Ephemeral Storage
176+
if (self.storage.isEphemeral) {
177+
return;
178+
}
179+
174180
NSString *sigKey = [NSString stringWithFormat:@"lastChangeSignature-%@", self.instanceLabel];
175181
[[NSUserDefaults standardUserDefaults] setObject:_lastChangeSignature forKey: sigKey];
176182
[[NSUserDefaults standardUserDefaults] synchronize];

Simperium/SPCoreDataStorage.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ - (NSSet *)stashedObjects {
400400
return [self.privateStashedObjects copy];
401401
}
402402

403+
- (BOOL)isEphemeral {
404+
return NO;
405+
}
406+
403407

404408
#pragma mark - Stashing and unstashing entities
405409

Simperium/SPDiffable.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
@property (nonatomic, copy) NSString *ghostData;
1111
@property (nonatomic, copy) NSString *simperiumKey;
1212
@property (nonatomic, weak) SPBucket *bucket;
13+
@property (nonatomic, copy, readonly) NSDictionary *dictionary;
14+
@property (nonatomic, copy, readonly) NSString *version;
1315

1416
- (void)simperiumSetValue:(id)value forKey:(NSString *)key;
1517
- (id)simperiumValueForKey:(NSString *)key;
1618
- (void)loadMemberData:(NSDictionary *)data;
1719
- (void)willBeRead;
18-
- (NSDictionary *)dictionary;
19-
- (NSString *)version;
2020
- (id)object;
2121

2222
@optional

Simperium/SPDiffer.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ - (BOOL)applyDiffFromDictionary:(NSDictionary *)diff toObject:(id<SPDiffable>)ob
121121
if (change == nil) {
122122
continue;
123123
}
124-
124+
125+
// Dynamic Schema: Ensure the Member is available
126+
// TODO: Implement Support for Dynamic Members with different encoding
127+
[self.schema ensureDynamicMemberExistsForObject:key key:change[OP_VALUE]];
128+
125129
// Make sure the member exists and is tracked by Simperium
126130
SPMember *member = [self.schema memberForKey:key];
127131
if (!member) {
@@ -181,6 +185,9 @@ - (BOOL)applyGhostDiffFromDictionary:(NSDictionary *)diff toObject:(id<SPDiffabl
181185
if (change == nil) {
182186
continue;
183187
}
188+
189+
// Dynamic Schema: Ensure the Member is available
190+
[self.schema ensureDynamicMemberExistsForObject:change[OP_VALUE] key:key];
184191

185192
// Make sure the member exists and is tracked by Simperium
186193
SPMember *member = [self.schema memberForKey:key];

Simperium/SPJSONStorage.m

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
#import "SPObject.h"
1111
#import "SPGhost.h"
1212
#import "NSString+Simperium.h"
13-
#import "NSMutableDictionary+Simperium.h"
1413
#import "SPBucket+Internals.h"
1514
#import "SPSchema.h"
1615
#import "SPDiffer.h"
17-
#import "SPswizzle.h"
1816

1917

2018
@interface NSMutableDictionary ()
@@ -44,10 +42,6 @@ - (instancetype)initWithDelegate:(id<SPStorageObserver>)aDelegate
4442

4543
NSString *queueLabel = @"com.simperium.JSONstorage";
4644
_storageQueue = dispatch_queue_create([queueLabel cStringUsingEncoding:NSUTF8StringEncoding], NULL);
47-
48-
NSError *error = nil;
49-
[NSMutableDictionary sp_swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(simperiumSetObject:forKey:) error:&error];
50-
[NSMutableDictionary sp_swizzleMethod:@selector(setValue:forKey:) withMethod:@selector(simperiumSetValue:forKey:) error:&error];
5145
}
5246

5347
return self;
@@ -57,9 +51,7 @@ - (instancetype)initWithDelegate:(id<SPStorageObserver>)aDelegate
5751
- (void)object:(id)object forKey:(NSString *)simperiumKey didChangeValue:(id)value forKey:(NSString *)key {
5852
// Update the schema if applicable
5953
SPObject *spObject = [_allObjects objectForKey:simperiumKey];
60-
[spObject.bucket.differ.schema addMemberForObject:value key:key];
61-
62-
// TODO: track the change here so saving can be smart
54+
[spObject.bucket.differ.schema ensureDynamicMemberExistsForObject:value key:key];
6355
}
6456

6557
- (SPStorage *)threadSafeStorage {
@@ -94,11 +86,7 @@ - (NSArray *)objectsForKeys:(NSSet *)keys bucketName:(NSString *)bucketName
9486
}
9587
});
9688

97-
if (!someObjects) {
98-
someObjects = @[];
99-
}
100-
101-
return someObjects;
89+
return someObjects ?: @[];
10290
}
10391

10492
- (id)objectAtIndex:(NSUInteger)index bucketName:(NSString *)bucketName {
@@ -111,25 +99,25 @@ - (NSArray *)objectsForBucketName:(NSString *)bucketName predicate:(NSPredicate
11199
dispatch_sync(_storageQueue, ^{
112100
NSDictionary *objectDict = [_objects objectForKey:bucketName];
113101
if (objectDict) {
114-
bucketObjects = [_objects allValues];
102+
bucketObjects = [objectDict allValues];
115103

116-
if (predicate)
104+
if (predicate) {
117105
bucketObjects = [bucketObjects filteredArrayUsingPredicate:predicate];
106+
}
118107
}
119108
});
120-
121-
if (!bucketObjects) {
122-
bucketObjects = @[];
123-
}
124-
return bucketObjects;
109+
110+
return bucketObjects ?: @[];
125111
}
126112

127113
- (NSArray *)objectKeysForBucketName:(NSString *)bucketName {
128114
__block NSArray *bucketObjects = [self objectsForBucketName:bucketName predicate:nil];
129115

130116
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:[bucketObjects count]];
131117
for (id<SPDiffable>object in bucketObjects) {
132-
[keys addObject:[object simperiumKey]];
118+
if (object.simperiumKey) {
119+
[keys addObject:object.simperiumKey];
120+
}
133121
}
134122

135123
return keys;
@@ -303,15 +291,20 @@ - (BOOL)save {
303291
// triggered from the main thread and could take awhile
304292

305293
// Sync all changes: Fake it for now by trying to send all objects
294+
295+
// TODO: JSONStorage is readonly at this stage.
296+
// Local changes should be captured via `didChangeValue:forKey:`
297+
/*
306298
NSMutableSet *updatedObjects = [NSMutableSet set];
307299
308300
for (NSDictionary *objectDict in _objects.allValues) {
309301
NSArray *objectsAsList = [objectDict allValues];
310302
[updatedObjects addObjectsFromArray:objectsAsList];
311303
}
304+
*/
312305

313306
[_delegate storageWillSave:self deletedObjects:nil];
314-
[_delegate storageDidSave:self insertedObjects:nil updatedObjects:updatedObjects];
307+
[_delegate storageDidSave:self insertedObjects:nil updatedObjects:nil];
315308

316309
return NO;
317310
}
@@ -337,6 +330,10 @@ - (NSSet *)stashedObjects {
337330
return nil;
338331
}
339332

333+
- (BOOL)isEphemeral {
334+
return YES;
335+
}
336+
340337
- (void)stashUnsavedObjects {
341338
// NO-OP
342339
}

Simperium/SPObject.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@
99
#import <Foundation/Foundation.h>
1010
#import "SPDiffable.h"
1111

12-
@interface SPObject : NSObject<SPDiffable> {
13-
NSMutableDictionary *dict;
14-
NSString *simperiumKey;
15-
}
12+
@interface SPObject : NSObject<SPDiffable>
1613

17-
@property (nonatomic, strong) NSMutableDictionary *dict;
1814
@property (nonatomic, strong) SPGhost *ghost;
1915
@property (nonatomic, copy) NSString *ghostData;
2016
@property (nonatomic, copy) NSString *simperiumKey;
21-
@property (nonatomic, copy) NSString *version;
17+
@property (nonatomic, copy, readonly) NSString *version;
18+
@property (nonatomic, copy, readonly) NSDictionary *dictionary;
2219

2320
- (instancetype)initWithDictionary:(NSMutableDictionary *)dictionary;
2421

0 commit comments

Comments
 (0)