Skip to content

Commit fea4a9d

Browse files
committed
Check manifest's last modified date during migration
1 parent 94f5abe commit fea4a9d

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

ios/RNCAsyncStorage.m

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,17 @@ static void RCTAppendError(NSDictionary *error, NSMutableArray<NSDictionary *> *
8787
return storageDirectory;
8888
}
8989

90+
static NSString *RCTCreateManifestFilePath(NSString *storageDirectory)
91+
{
92+
return [RCTCreateStorageDirectoryPath(storageDirectory) stringByAppendingString:RCTManifestFileName];
93+
}
94+
9095
static NSString *RCTGetManifestFilePath()
9196
{
9297
static NSString *manifestFilePath = nil;
9398
static dispatch_once_t onceToken;
9499
dispatch_once(&onceToken, ^{
95-
manifestFilePath = [RCTGetStorageDirectory() stringByAppendingPathComponent:RCTManifestFileName];
100+
manifestFilePath = RCTCreateManifestFilePath(RCTStorageDirectory);
96101
});
97102
return manifestFilePath;
98103
}
@@ -162,44 +167,70 @@ static dispatch_queue_t RCTGetMethodQueue()
162167
return error ? RCTMakeError(@"Failed to delete storage directory.", error, nil) : nil;
163168
}
164169

170+
static NSDate *RCTManifestModificationDate(NSString *manifestFilePath)
171+
{
172+
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:manifestFilePath error:nil];
173+
return [attributes fileModificationDate];
174+
}
165175

166176
NSString *const RCTOldStorageDirectory = @"RNCAsyncLocalStorage_V1";
167177
/**
168178
* Creates an NSException used during Storage Directory Migration.
169179
*/
170-
static void RCTStorageDirectoryMigrationLogError(NSString *reason, NSError *error) {
180+
static void RCTStorageDirectoryMigrationLogError(NSString *reason, NSError *error)
181+
{
171182
NSLog(@"%@: %@", reason, error ? error.description : @"");
172183
}
173184

185+
static void RCTStorageDirectoryCleanupOld()
186+
{
187+
NSError *error;
188+
if (![[NSFileManager defaultManager] removeItemAtPath:RCTCreateStorageDirectoryPath(RCTOldStorageDirectory) error:&error]) {
189+
RCTStorageDirectoryMigrationLogError(@"Failed to remove old storage directory during migration", error);
190+
}
191+
}
192+
193+
static void RCTStorageDirectoryMigrate()
194+
{
195+
NSError *error;
196+
// Migrate data by copying old storage directory to new storage directory location
197+
if (![[NSFileManager defaultManager] copyItemAtPath:RCTCreateStorageDirectoryPath(RCTOldStorageDirectory) toPath:RCTGetStorageDirectory() error:&error]) {
198+
RCTStorageDirectoryMigrationLogError(@"Failed to copy old storage directory to new storage directory location during migration", error);
199+
} else {
200+
// If copying succeeds, remove old storage directory
201+
RCTStorageDirectoryCleanupOld();
202+
}
203+
}
204+
174205
/**
175206
* This check is added to make sure that anyone coming from pre-1.2.2 does not lose cached data.
176207
* Data is migrated from the "RNCAsyncLocalStorage_V1" directory to the "RCTAsyncLocalStorage_V1" directory.
177208
*/
178-
static void RCTStorageDirectoryMigrationCheck() {
209+
static void RCTStorageDirectoryMigrationCheck()
210+
{
179211
static dispatch_once_t onceToken;
180212
dispatch_once(&onceToken, ^{
181213
NSError *error;
182214
BOOL isDir;
183-
// If the old directory exists, it means we need to migrate data to the new directory
215+
// If the old directory exists, it means we may need to migrate old data to the new directory
184216
if ([[NSFileManager defaultManager] fileExistsAtPath:RCTCreateStorageDirectoryPath(RCTOldStorageDirectory) isDirectory:&isDir] && isDir) {
185217
// Check if the new storage directory location already exists
186-
BOOL newStorageDirectoryExists = [[NSFileManager defaultManager] fileExistsAtPath:RCTGetStorageDirectory() isDirectory:&isDir];
187-
if (newStorageDirectoryExists) {
188-
// If the new storage directory location already exists, remove existing directory
189-
newStorageDirectoryExists = !([[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDirectory() error:&error]);
190-
if (newStorageDirectoryExists) {
191-
RCTStorageDirectoryMigrationLogError(@"Failed to clear pre-existing storage directory", error);
192-
}
193-
}
194-
if (!newStorageDirectoryExists) {
195-
// If new storage direction doesn't exist, copy old storage directory to new location
196-
if (![[NSFileManager defaultManager] copyItemAtPath:RCTCreateStorageDirectoryPath(RCTOldStorageDirectory) toPath:RCTGetStorageDirectory() error:&error]) {
197-
RCTStorageDirectoryMigrationLogError(@"Failed to copy old storage directory to new storage directory", error);
218+
if ([[NSFileManager defaultManager] fileExistsAtPath:RCTGetStorageDirectory()]) {
219+
// If new storage location exists, check if the new storage has been modified sooner
220+
if ([RCTManifestModificationDate(RCTGetManifestFilePath()) compare:RCTManifestModificationDate(RCTCreateManifestFilePath(RCTOldStorageDirectory))] == 1) {
221+
// If new location has been modified more recently, simply clean out old data
222+
RCTStorageDirectoryCleanupOld();
198223
} else {
199-
// If copying succeeds, remove old storage directory
200-
[[NSFileManager defaultManager] removeItemAtPath:RCTCreateStorageDirectoryPath(RCTOldStorageDirectory) error:&error];
201-
if (error) RCTStorageDirectoryMigrationLogError(@"Failed to remove old storage directory after migration", error);
224+
// If old location has been modified more recently, remove new storage and migrate
225+
if (![[NSFileManager defaultManager] removeItemAtPath:RCTGetStorageDirectory() error:&error]) {
226+
RCTStorageDirectoryMigrationLogError(@"Failed to remove new storage directory during migration", error);
227+
} else {
228+
RCTStorageDirectoryMigrate();
229+
}
202230
}
231+
} else {
232+
// If new storage location doesn't exist, migrate data
233+
RCTStorageDirectoryMigrate();
203234
}
204235
}
205236
});
@@ -216,7 +247,8 @@ @implementation RNCAsyncStorage
216247
NSMutableDictionary<NSString *, NSString *> *_manifest;
217248
}
218249

219-
+ (BOOL)requiresMainQueueSetup {
250+
+ (BOOL)requiresMainQueueSetup
251+
{
220252
return NO;
221253
}
222254

0 commit comments

Comments
 (0)