Add app group, share keychain. Take a first pass at file migration to shared data directory.
This commit is contained in:
parent
1ccf5132c1
commit
cd11ec5698
|
@ -2052,6 +2052,9 @@
|
||||||
LastSwiftMigration = 0800;
|
LastSwiftMigration = 0800;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
SystemCapabilities = {
|
SystemCapabilities = {
|
||||||
|
com.apple.ApplicationGroups.iOS = {
|
||||||
|
enabled = 1;
|
||||||
|
};
|
||||||
com.apple.DataProtection = {
|
com.apple.DataProtection = {
|
||||||
enabled = 1;
|
enabled = 1;
|
||||||
};
|
};
|
||||||
|
@ -2061,6 +2064,9 @@
|
||||||
com.apple.InterAppAudio = {
|
com.apple.InterAppAudio = {
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
};
|
};
|
||||||
|
com.apple.Keychain = {
|
||||||
|
enabled = 1;
|
||||||
|
};
|
||||||
com.apple.Push = {
|
com.apple.Push = {
|
||||||
enabled = 1;
|
enabled = 1;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<dict>
|
<dict>
|
||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
|
<key>com.apple.developer.default-data-protection</key>
|
||||||
|
<string>NSFileProtectionComplete</string>
|
||||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||||
<array>
|
<array>
|
||||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||||
|
@ -16,5 +18,13 @@
|
||||||
<array>
|
<array>
|
||||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.org.whispersystems.signal.group</string>
|
||||||
|
</array>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>$(AppIdentifierPrefix)org.whispersystems.signal</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -1389,9 +1389,17 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
||||||
static NSString *profileAvatarsDirPath = nil;
|
static NSString *profileAvatarsDirPath = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
NSString *documentsPath =
|
NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath];
|
||||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath];
|
||||||
profileAvatarsDirPath = [documentsPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
|
||||||
|
NSString *oldProfileAvatarsDirPath = [documentDirPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||||
|
NSString *newProfileAvatarsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||||
|
|
||||||
|
[OWSFileSystem moveAppFilePath:oldProfileAvatarsDirPath
|
||||||
|
sharedDataFilePath:newProfileAvatarsDirPath
|
||||||
|
exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"];
|
||||||
|
|
||||||
|
profileAvatarsDirPath = newProfileAvatarsDirPath;
|
||||||
|
|
||||||
BOOL isDirectory;
|
BOOL isDirectory;
|
||||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory];
|
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory];
|
||||||
|
|
|
@ -185,9 +185,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
static NSString *attachmentsFolder = nil;
|
static NSString *attachmentsFolder = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
NSString *documentsPath =
|
NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath];
|
||||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath];
|
||||||
attachmentsFolder = [documentsPath stringByAppendingPathComponent:@"Attachments"];
|
|
||||||
|
NSString *oldAttachmentsDirPath = [documentDirPath stringByAppendingPathComponent:@"Attachments"];
|
||||||
|
NSString *newAttachmentsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"Attachments"];
|
||||||
|
|
||||||
|
[OWSFileSystem moveAppFilePath:oldAttachmentsDirPath
|
||||||
|
sharedDataFilePath:newAttachmentsDirPath
|
||||||
|
exceptionName:@"CouldNotMigrateAttachmentsDirectory"];
|
||||||
|
|
||||||
|
attachmentsFolder = newAttachmentsDirPath;
|
||||||
|
|
||||||
BOOL isDirectory;
|
BOOL isDirectory;
|
||||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory];
|
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory];
|
||||||
|
|
|
@ -63,10 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
|
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
|
||||||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
|
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
|
||||||
|
|
||||||
#pragma mark - Utilities
|
|
||||||
|
|
||||||
- (void)protectFolderAtPath:(NSString *)path;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -24,13 +24,18 @@
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessible = @"TSStorageManagerExceptionNameDatabasePasswordInaccessible";
|
NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessible
|
||||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded =
|
= @"TSStorageManagerExceptionName_DatabasePasswordInaccessible";
|
||||||
@"TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded";
|
NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
|
||||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordUnwritable = @"TSStorageManagerExceptionNameDatabasePasswordUnwritable";
|
= @"TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded";
|
||||||
NSString *const TSStorageManagerExceptionNameNoDatabase = @"TSStorageManagerExceptionNameNoDatabase";
|
NSString *const TSStorageManagerExceptionName_DatabasePasswordUnwritable
|
||||||
|
= @"TSStorageManagerExceptionName_DatabasePasswordUnwritable";
|
||||||
|
NSString *const TSStorageManagerExceptionName_NoDatabase = @"TSStorageManagerExceptionName_NoDatabase";
|
||||||
|
NSString *const TSStorageManagerExceptionName_CouldNotMoveDatabaseFile
|
||||||
|
= @"TSStorageManagerExceptionName_CouldNotMoveDatabaseFile";
|
||||||
|
NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
||||||
|
= @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory";
|
||||||
|
|
||||||
static const NSString *const databaseName = @"Signal.sqlite";
|
|
||||||
static NSString *keychainService = @"TSKeyChainService";
|
static NSString *keychainService = @"TSKeyChainService";
|
||||||
static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
||||||
|
|
||||||
|
@ -231,7 +236,7 @@ void setDatabaseInitialized()
|
||||||
// Sleep to give analytics events time to be delivered.
|
// Sleep to give analytics events time to be delivered.
|
||||||
[NSThread sleepForTimeInterval:15.0f];
|
[NSThread sleepForTimeInterval:15.0f];
|
||||||
|
|
||||||
[NSException raise:TSStorageManagerExceptionNameNoDatabase format:@"Failed to initialize database."];
|
[NSException raise:TSStorageManagerExceptionName_NoDatabase format:@"Failed to initialize database."];
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSSingletonAssert();
|
OWSSingletonAssert();
|
||||||
|
@ -253,6 +258,7 @@ void setDatabaseInitialized()
|
||||||
options.cipherKeyBlock = ^{
|
options.cipherKeyBlock = ^{
|
||||||
return databasePassword;
|
return databasePassword;
|
||||||
};
|
};
|
||||||
|
options.enableMultiProcessSupport = YES;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_database = [[OWSDatabase alloc] initWithPath:[self dbPath]
|
_database = [[OWSDatabase alloc] initWithPath:[self dbPath]
|
||||||
|
@ -350,9 +356,14 @@ void setDatabaseInitialized()
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)protectSignalFiles {
|
- (void)protectSignalFiles {
|
||||||
[OWSFileSystem protectFolderAtPath:[self dbPath]];
|
// The old database location was in the Document directory,
|
||||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-shm"]];
|
// so protect the database files individually.
|
||||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-wal"]];
|
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]];
|
||||||
|
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_SHM]];
|
||||||
|
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_WAL]];
|
||||||
|
|
||||||
|
// Protect the entire new database directory.
|
||||||
|
[OWSFileSystem protectFolderAtPath:[self newDatabaseDirPath]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable YapDatabaseConnection *)newDatabaseConnection
|
- (nullable YapDatabaseConnection *)newDatabaseConnection
|
||||||
|
@ -364,33 +375,118 @@ void setDatabaseInitialized()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)dbExists {
|
- (NSString *)oldDatabaseDirPath
|
||||||
return [[NSFileManager defaultManager] fileExistsAtPath:[self dbPath]];
|
{
|
||||||
|
return [OWSFileSystem appDocumentDirectoryPath];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)dbPath {
|
- (NSString *)newDatabaseDirPath
|
||||||
NSString *databasePath;
|
{
|
||||||
|
NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"];
|
||||||
|
|
||||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
#if TARGET_OS_IPHONE
|
if (![fileManager fileExistsAtPath:databaseDirPath]) {
|
||||||
NSURL *fileURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
NSError *_Nullable error;
|
||||||
NSString *path = [fileURL path];
|
BOOL success = [fileManager createDirectoryAtPath:databaseDirPath
|
||||||
databasePath = [path stringByAppendingPathComponent:databaseName];
|
withIntermediateDirectories:NO
|
||||||
#elif TARGET_OS_MAC
|
attributes:nil
|
||||||
|
error:&error];
|
||||||
|
if (!success || error) {
|
||||||
|
NSString *errorDescription =
|
||||||
|
[NSString stringWithFormat:@"%@ Could not create new database directory: %@, error: %@",
|
||||||
|
self.logTag,
|
||||||
|
databaseDirPath,
|
||||||
|
error];
|
||||||
|
OWSFail(@"%@", errorDescription);
|
||||||
|
[NSException raise:TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
||||||
|
format:@"%@", errorDescription];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return databaseDirPath;
|
||||||
|
}
|
||||||
|
|
||||||
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
|
- (NSString *)databaseFilename
|
||||||
NSArray *urlPaths = [fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
|
{
|
||||||
|
return @"Signal.sqlite";
|
||||||
|
}
|
||||||
|
|
||||||
NSURL *appDirectory = [[urlPaths objectAtIndex:0] URLByAppendingPathComponent:bundleID isDirectory:YES];
|
- (NSString *)databaseFilename_SHM
|
||||||
|
{
|
||||||
|
return [self.databaseFilename stringByAppendingString:@"-shm"];
|
||||||
|
}
|
||||||
|
|
||||||
if (![fileManager fileExistsAtPath:[appDirectory path]]) {
|
- (NSString *)databaseFilename_WAL
|
||||||
[fileManager createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:nil];
|
{
|
||||||
|
return [self.databaseFilename stringByAppendingString:@"-wal"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)oldDatabaseFilePath
|
||||||
|
{
|
||||||
|
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)oldDatabaseFilePath_SHM
|
||||||
|
{
|
||||||
|
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)oldDatabaseFilePath_WAL
|
||||||
|
{
|
||||||
|
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)newDatabaseFilePath
|
||||||
|
{
|
||||||
|
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)newDatabaseFilePath_SHM
|
||||||
|
{
|
||||||
|
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)newDatabaseFilePath_WAL
|
||||||
|
{
|
||||||
|
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)dbPath
|
||||||
|
{
|
||||||
|
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath
|
||||||
|
sharedDataFilePath:self.newDatabaseFilePath
|
||||||
|
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||||
|
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_SHM
|
||||||
|
sharedDataFilePath:self.newDatabaseFilePath_SHM
|
||||||
|
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||||
|
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_WAL
|
||||||
|
sharedDataFilePath:self.newDatabaseFilePath_WAL
|
||||||
|
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||||
|
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
BOOL hasAllNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] &&
|
||||||
|
[fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] &&
|
||||||
|
[fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]);
|
||||||
|
BOOL hasAnyNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] ||
|
||||||
|
[fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] ||
|
||||||
|
[fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]);
|
||||||
|
if (!hasAllNewFiles && !hasAnyNewFiles) {
|
||||||
|
for (NSString *filePath in @[
|
||||||
|
self.newDatabaseFilePath,
|
||||||
|
self.newDatabaseFilePath_SHM,
|
||||||
|
self.newDatabaseFilePath_WAL,
|
||||||
|
self.newDatabaseFilePath,
|
||||||
|
self.newDatabaseFilePath_SHM,
|
||||||
|
self.newDatabaseFilePath_WAL,
|
||||||
|
]) {
|
||||||
|
DDLogInfo(@"%@ Database file %@ exists %d", self.logTag, filePath, [fileManager fileExistsAtPath:filePath]);
|
||||||
|
}
|
||||||
|
OWSFail(@"%@ Incomplete set of database files.", self.logTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
databasePath = [appDirectory.filePathURL.absoluteString stringByAppendingPathComponent:databaseName];
|
DDLogError(@"databasePath: %@", self.newDatabaseFilePath);
|
||||||
#endif
|
[DDLog flushLog];
|
||||||
|
|
||||||
return databasePath;
|
return self.newDatabaseFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)isDatabasePasswordAccessible
|
+ (BOOL)isDatabasePasswordAccessible
|
||||||
|
@ -421,7 +517,7 @@ void setDatabaseInitialized()
|
||||||
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
|
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
|
||||||
// but it could also just be that the user hasn't yet unlocked their device since our password is
|
// but it could also just be that the user hasn't yet unlocked their device since our password is
|
||||||
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
||||||
[NSException raise:TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded
|
[NSException raise:TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
|
||||||
format:@"%@", errorDescription];
|
format:@"%@", errorDescription];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +579,7 @@ void setDatabaseInitialized()
|
||||||
// Sleep to give analytics events time to be delivered.
|
// Sleep to give analytics events time to be delivered.
|
||||||
[NSThread sleepForTimeInterval:15.0f];
|
[NSThread sleepForTimeInterval:15.0f];
|
||||||
|
|
||||||
[NSException raise:TSStorageManagerExceptionNameDatabasePasswordUnwritable
|
[NSException raise:TSStorageManagerExceptionName_DatabasePasswordUnwritable
|
||||||
format:@"Setting DB password failed with error: %@", keySetError];
|
format:@"Setting DB password failed with error: %@", keySetError];
|
||||||
} else {
|
} else {
|
||||||
DDLogWarn(@"Succesfully set new DB password.");
|
DDLogWarn(@"Succesfully set new DB password.");
|
||||||
|
|
|
@ -10,6 +10,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
+ (void)protectFolderAtPath:(NSString *)path;
|
+ (void)protectFolderAtPath:(NSString *)path;
|
||||||
|
|
||||||
|
+ (NSString *)appDocumentDirectoryPath;
|
||||||
|
|
||||||
|
+ (NSString *)appSharedDataDirectoryPath;
|
||||||
|
|
||||||
|
+ (void)moveAppFilePath:(NSString *)oldFilePath
|
||||||
|
sharedDataFilePath:(NSString *)newFilePath
|
||||||
|
exceptionName:(NSString *)exceptionName;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -28,6 +28,56 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSString *)appDocumentDirectoryPath
|
||||||
|
{
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
NSURL *documentDirectoryURL =
|
||||||
|
[[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||||
|
return [documentDirectoryURL path];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)appSharedDataDirectoryPath
|
||||||
|
{
|
||||||
|
NSURL *groupContainerDirectoryURL = [[NSFileManager defaultManager]
|
||||||
|
containerURLForSecurityApplicationGroupIdentifier:@"group.org.whispersystems.signal.group"];
|
||||||
|
return [groupContainerDirectoryURL path];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)moveAppFilePath:(NSString *)oldFilePath
|
||||||
|
sharedDataFilePath:(NSString *)newFilePath
|
||||||
|
exceptionName:(NSString *)exceptionName
|
||||||
|
{
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
if (![fileManager fileExistsAtPath:oldFilePath]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([fileManager fileExistsAtPath:newFilePath]) {
|
||||||
|
DDLogError(@"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDate *startDate = [NSDate new];
|
||||||
|
|
||||||
|
NSError *_Nullable error;
|
||||||
|
BOOL success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
|
||||||
|
if (!success || error) {
|
||||||
|
NSString *errorDescription =
|
||||||
|
[NSString stringWithFormat:@"%@ Could not move database file from %@ to %@, error: %@",
|
||||||
|
self.logTag,
|
||||||
|
oldFilePath,
|
||||||
|
newFilePath,
|
||||||
|
error];
|
||||||
|
OWSFail(@"%@", errorDescription);
|
||||||
|
[NSException raise:exceptionName format:@"%@", errorDescription];
|
||||||
|
}
|
||||||
|
|
||||||
|
DDLogInfo(@"%@ Moving file or directory from %@ to %@ in: %f",
|
||||||
|
self.logTag,
|
||||||
|
oldFilePath,
|
||||||
|
newFilePath,
|
||||||
|
fabs([startDate timeIntervalSinceNow]));
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
Loading…
Reference in New Issue