@@ -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+
9095static 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
166176NSString *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