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