@@ -174,61 +174,50 @@ static dispatch_queue_t RCTGetMethodQueue()
174
174
return error ? RCTMakeError (@" Failed to delete storage directory." , error, nil ) : nil ;
175
175
}
176
176
177
+
178
+ NSString *OldStorageDirectory = @" RNCAsyncLocalStorage_V1" ;
179
+ /* *
180
+ * Creates an NSException used during Storage Directory Migration.
181
+ */
182
+ static NSException *RCTStorageDirectionMigrationException (NSString *reason, NSError *error) {
183
+ NSMutableString *reasonString = [[NSMutableString alloc ] initWithString: reason];
184
+ [reasonString appendString: @" - " ];
185
+ [reasonString appendString: [error description ]];
186
+ return [[NSException alloc ] initWithName: @" RCTStorageDirectoryMigrationFailure" reason: reasonString userInfo: nil ];
187
+ }
188
+
177
189
/* *
178
190
* This check is added to make sure that anyone coming from pre-1.2.2 does not lose cached data.
179
191
* Data is migrated from the "RNCAsyncLocalStorage_V1" directory to the "RCTAsyncLocalStorage_V1" directory.
180
192
*/
181
193
static void RCTStorageDirectoryMigrationCheck () {
182
- NSString *oldStorageDir = RCTCreateStorageDirectoryPath (@" RNCAsyncLocalStorage_V1" );
183
-
184
- NSError *error;
185
- BOOL isDir;
186
- BOOL oldExists = [[NSFileManager defaultManager ] fileExistsAtPath: oldStorageDir isDirectory: &isDir];
187
-
188
- // If the old directory exists, it means we need to migrate data to the new directory
189
- if (oldExists && isDir) {
190
-
191
- BOOL migrationSuccess;
192
- // If the new storage directory already exists, then this may be caused by ever older data being left behind from previous versions.
193
- // This old data will need to be overwritten.
194
- NSString *newStorageDir = RCTGetStorageDirectory ();
195
- BOOL newExists = [[NSFileManager defaultManager ] fileExistsAtPath: newStorageDir isDirectory: &isDir];
196
- if (newExists && isDir) {
197
- NSString *backupStorageDir = RCTCreateStorageDirectoryPath (@" RCTBackupAsyncLocalStorage_V1" );
198
- // Replace any possible existing data in the new storage with old storage directory
199
- migrationSuccess = [[NSFileManager defaultManager ] replaceItemAtURL: [[NSURL alloc ] initWithString: newStorageDir]
200
- withItemAtURL: [[NSURL alloc ] initWithString: oldStorageDir]
201
- backupItemName: backupStorageDir
202
- options: NSFileManagerItemReplacementUsingNewMetadataOnly
203
- resultingItemURL: nil
204
- error: &error];
205
- if (error || !migrationSuccess) {
206
- // Attempt to recover from failed overwriting
207
- [[NSFileManager defaultManager ] removeItemAtPath: newStorageDir error: nil ];
208
- [[NSFileManager defaultManager ] copyItemAtPath: backupStorageDir toPath: newStorageDir error: nil ];
209
- [[NSFileManager defaultManager ] removeItemAtPath: backupStorageDir error: nil ];
210
- if (error) {
211
- RCTMakeError (@" Failed to overwrite old storage directory to new storage directory location during migration" , error, nil );
212
- return ;
194
+ static dispatch_once_t onceToken;
195
+ dispatch_once (&onceToken, ^{
196
+ NSError *error;
197
+ BOOL isDir;
198
+ // If the old directory exists, it means we need to migrate data to the new directory
199
+ if ([[NSFileManager defaultManager ] fileExistsAtPath: RCTCreateStorageDirectoryPath (OldStorageDirectory) isDirectory: &isDir] && isDir) {
200
+ // Check if the new storage directory location already exists
201
+ BOOL newStorageDirectoryExists = [[NSFileManager defaultManager ] fileExistsAtPath: RCTGetStorageDirectory () isDirectory: &isDir];
202
+ if (newStorageDirectoryExists) {
203
+ // If the new storage directory location already exists, remove existing directory
204
+ newStorageDirectoryExists = !([[NSFileManager defaultManager ] removeItemAtPath: RCTGetStorageDirectory () error: &error]);
205
+ if (newStorageDirectoryExists) {
206
+ @throw RCTStorageDirectionMigrationException (@" Failed to clear pre-existing storage directory" , error);
213
207
}
214
208
}
215
- } else {
216
- // Copy over the old storage directory to new storage directory path
217
- migrationSuccess = [[NSFileManager defaultManager ] copyItemAtPath: oldStorageDir toPath: newStorageDir error: &error];
218
- if (error) {
219
- RCTMakeError (@" Failed to copy old storage directory to new storage directory location during migration" , error, nil );
220
- return ;
221
- }
222
- }
223
-
224
- // If the migration was a success, remove old storage directory
225
- if (migrationSuccess) {
226
- [[NSFileManager defaultManager ] removeItemAtPath: oldStorageDir error: &error];
227
- if (error) {
228
- RCTMakeError (@" Failed to remove old storage directory after migration" , error, nil );
209
+ if (!newStorageDirectoryExists) {
210
+ // If new storage direction doesn't exist, copy old storage directory to new location
211
+ if (![[NSFileManager defaultManager ] copyItemAtPath: RCTCreateStorageDirectoryPath (OldStorageDirectory) toPath: RCTGetStorageDirectory () error: &error]) {
212
+ @throw RCTStorageDirectionMigrationException (@" Failed to copy old storage directory to new storage directory" , error);
213
+ } else {
214
+ // If copying succeeds, remove old storage directory
215
+ [[NSFileManager defaultManager ] removeItemAtPath: RCTCreateStorageDirectoryPath (OldStorageDirectory) error: &error];
216
+ if (error) @throw RCTStorageDirectionMigrationException (@" Failed to remove old storage directory after migration" , error);
217
+ }
229
218
}
230
219
}
231
- }
220
+ });
232
221
}
233
222
234
223
#pragma mark - RNCAsyncStorage
0 commit comments