From edaf65223a034d32c08108b05b5fe56ea2cbfa22 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 28 Nov 2017 13:46:26 -0500 Subject: [PATCH] Migrate to shared data NSUserDefaults. --- Signal/src/AppDelegate.m | 28 +++++++++ Signal/src/Profiles/OWSProfileManager.h | 2 + Signal/src/Profiles/OWSProfileManager.m | 29 +++++---- Signal/src/environment/OWSPreferences.h | 3 + Signal/src/environment/OWSPreferences.m | 30 ++++++--- Signal/src/environment/VersionMigrations.m | 47 +++++++------- .../Messages/Attachments/TSAttachmentStream.h | 2 + .../Messages/Attachments/TSAttachmentStream.m | 29 +++++---- .../src/Storage/TSStorageManager.h | 2 + .../src/Storage/TSStorageManager.m | 61 +++++++------------ SignalServiceKit/src/Util/AppVersion.m | 21 +++---- .../src/Util/NSUserDefaults+OWS.h | 17 ++++++ .../src/Util/NSUserDefaults+OWS.m | 37 +++++++++++ 13 files changed, 206 insertions(+), 102 deletions(-) create mode 100644 SignalServiceKit/src/Util/NSUserDefaults+OWS.h create mode 100644 SignalServiceKit/src/Util/NSUserDefaults+OWS.m diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5f2707044..1607ffdd9 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -24,6 +24,7 @@ #import "VersionMigrations.h" #import "ViewControllerUtils.h" #import +#import #import #import #import @@ -103,6 +104,18 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; DDLogWarn(@"%@ application: didFinishLaunchingWithOptions.", self.logTag); + // We need to this _after_ we set up logging but _before_ we do + // anything else. + [self ensureMigrationToSharedData]; + +#if RELEASE + // ensureMigrationToSharedData may have changed the state of the logging + // preference, so honor that change if necessary. + if (loggingIsEnabled && !OWSPreferences.loggingIsEnabled) { + [DebugLogger.sharedLogger disableFileLogging]; + } +#endif + [AppVersion instance]; [self startupLogging]; @@ -176,6 +189,21 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; return YES; } +- (void)ensureMigrationToSharedData +{ + if ([OWSPreferences hasMigratedToSharedData]) { + return; + } + + [NSUserDefaults migrateToSharedUserDefaults]; + + [TSStorageManager migrateToSharedData]; + [OWSProfileManager migrateToSharedData]; + [TSAttachmentStream migrateToSharedData]; + + [OWSPreferences setHasMigratedToSharedData:YES]; +} + - (void)startupLogging { DDLogInfo(@"iOS Version: %@", [UIDevice currentDevice].systemVersion); diff --git a/Signal/src/Profiles/OWSProfileManager.h b/Signal/src/Profiles/OWSProfileManager.h index 3d67415f0..331dddb23 100644 --- a/Signal/src/Profiles/OWSProfileManager.h +++ b/Signal/src/Profiles/OWSProfileManager.h @@ -29,6 +29,8 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter; - (void)resetProfileStorage; ++ (void)migrateToSharedData; + #pragma mark - Local Profile // These two methods should only be called from the main thread. diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index ba6fe9109..2cef339a7 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -1384,22 +1384,29 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; return image; } ++ (NSString *)oldProfileAvatarsDirPath +{ + return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; +} + ++ (NSString *)newProfileAvatarsDirPath +{ + return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"ProfileAvatars"]; +} + ++ (void)migrateToSharedData +{ + [OWSFileSystem moveAppFilePath:self.oldProfileAvatarsDirPath + sharedDataFilePath:self.newProfileAvatarsDirPath + exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; +} + - (NSString *)profileAvatarsDirPath { static NSString *profileAvatarsDirPath = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; - NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; - - NSString *oldProfileAvatarsDirPath = [documentDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; - NSString *newProfileAvatarsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"ProfileAvatars"]; - - [OWSFileSystem moveAppFilePath:oldProfileAvatarsDirPath - sharedDataFilePath:newProfileAvatarsDirPath - exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"]; - - profileAvatarsDirPath = newProfileAvatarsDirPath; + profileAvatarsDirPath = OWSProfileManager.newProfileAvatarsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory]; diff --git a/Signal/src/environment/OWSPreferences.h b/Signal/src/environment/OWSPreferences.h index 27a0d674c..822f9fe4d 100644 --- a/Signal/src/environment/OWSPreferences.h +++ b/Signal/src/environment/OWSPreferences.h @@ -27,6 +27,9 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog; #pragma mark - Specific Preferences ++ (BOOL)hasMigratedToSharedData; ++ (void)setHasMigratedToSharedData:(BOOL)value; + - (BOOL)getHasSentAMessage; - (void)setHasSentAMessage:(BOOL)enabled; diff --git a/Signal/src/environment/OWSPreferences.m b/Signal/src/environment/OWSPreferences.m index 6e7e66467..c7fa02d3c 100644 --- a/Signal/src/environment/OWSPreferences.m +++ b/Signal/src/environment/OWSPreferences.m @@ -4,6 +4,7 @@ #import "OWSPreferences.h" #import "TSStorageHeaders.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -22,6 +23,7 @@ NSString *const OWSPreferencesKeyCallKitPrivacyEnabled = @"CallKitPrivacyEnabled NSString *const OWSPreferencesKeyCallsHideIPAddress = @"CallsHideIPAddress"; NSString *const OWSPreferencesKeyHasDeclinedNoContactsView = @"hasDeclinedNoContactsView"; NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; +NSString *const OWSPreferencesKey_HasMigratedToSharedData = @"hasMigratedToSharedData"; @implementation OWSPreferences @@ -40,10 +42,7 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; #pragma mark - Helpers - (void)clear { - @synchronized(self) { - NSString *appDomain = NSBundle.mainBundle.bundleIdentifier; - [NSUserDefaults.standardUserDefaults removePersistentDomainForName:appDomain]; - } + [NSUserDefaults removeAll]; } - (nullable id)tryGetValueForKey:(NSString *)key @@ -61,6 +60,23 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; #pragma mark - Specific Preferences ++ (BOOL)hasMigratedToSharedData +{ + NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKey_HasMigratedToSharedData]; + + if (preference) { + return [preference boolValue]; + } else { + return NO; + } +} + ++ (void)setHasMigratedToSharedData:(BOOL)value +{ + [NSUserDefaults.appUserDefaults setObject:@(value) forKey:OWSPreferencesKey_HasMigratedToSharedData]; + [NSUserDefaults.appUserDefaults synchronize]; +} + - (BOOL)screenSecurityIsEnabled { NSNumber *preference = [self tryGetValueForKey:OWSPreferencesKeyScreenSecurity]; @@ -94,7 +110,7 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; + (BOOL)loggingIsEnabled { - NSNumber *preference = [NSUserDefaults.standardUserDefaults objectForKey:OWSPreferencesKeyEnableDebugLog]; + NSNumber *preference = [NSUserDefaults.appUserDefaults objectForKey:OWSPreferencesKeyEnableDebugLog]; if (preference) { return [preference boolValue]; @@ -108,8 +124,8 @@ NSString *const OWSPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion"; // Logging preferences are stored in UserDefaults instead of the database, so that we can (optionally) start // logging before the database is initialized. This is important because sometimes there are problems *with* the // database initialization, and without logging it would be hard to track down. - [NSUserDefaults.standardUserDefaults setObject:@(flag) forKey:OWSPreferencesKeyEnableDebugLog]; - [NSUserDefaults.standardUserDefaults synchronize]; + [NSUserDefaults.appUserDefaults setObject:@(flag) forKey:OWSPreferencesKeyEnableDebugLog]; + [NSUserDefaults.appUserDefaults synchronize]; } - (void)setHasSentAMessage:(BOOL)enabled diff --git a/Signal/src/environment/VersionMigrations.m b/Signal/src/environment/VersionMigrations.m index 5afe4810d..ebf2caf29 100644 --- a/Signal/src/environment/VersionMigrations.m +++ b/Signal/src/environment/VersionMigrations.m @@ -8,9 +8,10 @@ #import "OWSDatabaseMigrationRunner.h" #import "PushManager.h" #import "SignalKeyingStorage.h" -#import "TSAccountManager.h" -#import "TSNetworkManager.h" #import +#import +#import +#import #define NEEDS_TO_REGISTER_PUSH_KEY @"Register For Push" #define NEEDS_TO_REGISTER_ATTRIBUTES @"Register Attributes" @@ -125,39 +126,39 @@ + (void)blockingAttributesUpdate { LIControllerBlockingOperation blockingOperation = ^BOOL(void) { - [[NSUserDefaults standardUserDefaults] setObject:@YES forKey:NEEDS_TO_REGISTER_ATTRIBUTES]; + [[NSUserDefaults appUserDefaults] setObject:@YES forKey:NEEDS_TO_REGISTER_ATTRIBUTES]; - __block dispatch_semaphore_t sema = dispatch_semaphore_create(0); + __block dispatch_semaphore_t sema = dispatch_semaphore_create(0); - __block BOOL success; + __block BOOL success; - TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithManualMessageFetching:NO]; - [[TSNetworkManager sharedManager] makeRequest:request - success:^(NSURLSessionDataTask *task, id responseObject) { - success = YES; - dispatch_semaphore_signal(sema); - } - failure:^(NSURLSessionDataTask *task, NSError *error) { - if (!IsNSErrorNetworkFailure(error)) { - OWSProdError([OWSAnalyticsEvents errorUpdateAttributesRequestFailed]); - } - success = NO; - DDLogError(@"Updating attributess failed with error: %@", error.description); - dispatch_semaphore_signal(sema); - }]; + TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithManualMessageFetching:NO]; + [[TSNetworkManager sharedManager] makeRequest:request + success:^(NSURLSessionDataTask *task, id responseObject) { + success = YES; + dispatch_semaphore_signal(sema); + } + failure:^(NSURLSessionDataTask *task, NSError *error) { + if (!IsNSErrorNetworkFailure(error)) { + OWSProdError([OWSAnalyticsEvents errorUpdateAttributesRequestFailed]); + } + success = NO; + DDLogError(@"Updating attributess failed with error: %@", error.description); + dispatch_semaphore_signal(sema); + }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); - return success; + return success; }; LIControllerRetryBlock retryBlock = [LockInteractionController defaultNetworkRetry]; [LockInteractionController performBlock:blockingOperation completionBlock:^{ - [[NSUserDefaults standardUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_ATTRIBUTES]; - DDLogWarn(@"Successfully updated attributes."); + [[NSUserDefaults appUserDefaults] removeObjectForKey:NEEDS_TO_REGISTER_ATTRIBUTES]; + DDLogWarn(@"Successfully updated attributes."); } retryBlock:retryBlock usesNetwork:YES]; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index ac8f9c490..21cd8eb98 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -57,6 +57,8 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)audioDurationSeconds; ++ (void)migrateToSharedData; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index a40b62ee5..187ad5498 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -180,22 +180,29 @@ NS_ASSUME_NONNULL_BEGIN return [dataSource writeToPath:filePath]; } ++ (NSString *)oldAttachmentsDirPath +{ + return [[OWSFileSystem appDocumentDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; +} + ++ (NSString *)newAttachmentsDirPath +{ + return [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"Attachments"]; +} + ++ (void)migrateToSharedData +{ + [OWSFileSystem moveAppFilePath:self.oldAttachmentsDirPath + sharedDataFilePath:self.newAttachmentsDirPath + exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; +} + + (NSString *)attachmentsFolder { static NSString *attachmentsFolder = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath]; - NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath]; - - NSString *oldAttachmentsDirPath = [documentDirPath stringByAppendingPathComponent:@"Attachments"]; - NSString *newAttachmentsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"Attachments"]; - - [OWSFileSystem moveAppFilePath:oldAttachmentsDirPath - sharedDataFilePath:newAttachmentsDirPath - exceptionName:@"CouldNotMigrateAttachmentsDirectory"]; - - attachmentsFolder = newAttachmentsDirPath; + attachmentsFolder = TSAttachmentStream.newAttachmentsDirPath; BOOL isDirectory; BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory]; diff --git a/SignalServiceKit/src/Storage/TSStorageManager.h b/SignalServiceKit/src/Storage/TSStorageManager.h index 0dbd4ad4a..38ce97988 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.h +++ b/SignalServiceKit/src/Storage/TSStorageManager.h @@ -63,6 +63,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection; @property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; ++ (void)migrateToSharedData; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index dbe9d99b1..a4b18c3ae 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -207,10 +207,11 @@ void setDatabaseInitialized() static TSStorageManager *sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - sharedManager = [[self alloc] initDefault]; #if TARGET_OS_IPHONE - [sharedManager protectSignalFiles]; + [TSStorageManager protectSignalFiles]; #endif + + sharedManager = [[self alloc] initDefault]; }); return sharedManager; } @@ -355,7 +356,8 @@ void setDatabaseInitialized() [TSDatabaseView asyncRegistrationCompletion]; } -- (void)protectSignalFiles { ++ (void)protectSignalFiles +{ // The old database location was in the Document directory, // so protect the database files individually. [OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]]; @@ -375,12 +377,12 @@ void setDatabaseInitialized() return FALSE; } -- (NSString *)oldDatabaseDirPath ++ (NSString *)oldDatabaseDirPath { return [OWSFileSystem appDocumentDirectoryPath]; } -- (NSString *)newDatabaseDirPath ++ (NSString *)newDatabaseDirPath { NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"]; @@ -405,52 +407,52 @@ void setDatabaseInitialized() return databaseDirPath; } -- (NSString *)databaseFilename ++ (NSString *)databaseFilename { return @"Signal.sqlite"; } -- (NSString *)databaseFilename_SHM ++ (NSString *)databaseFilename_SHM { return [self.databaseFilename stringByAppendingString:@"-shm"]; } -- (NSString *)databaseFilename_WAL ++ (NSString *)databaseFilename_WAL { return [self.databaseFilename stringByAppendingString:@"-wal"]; } -- (NSString *)oldDatabaseFilePath ++ (NSString *)oldDatabaseFilePath { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -- (NSString *)oldDatabaseFilePath_SHM ++ (NSString *)oldDatabaseFilePath_SHM { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -- (NSString *)oldDatabaseFilePath_WAL ++ (NSString *)oldDatabaseFilePath_WAL { return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } -- (NSString *)newDatabaseFilePath ++ (NSString *)newDatabaseFilePath { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename]; } -- (NSString *)newDatabaseFilePath_SHM ++ (NSString *)newDatabaseFilePath_SHM { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM]; } -- (NSString *)newDatabaseFilePath_WAL ++ (NSString *)newDatabaseFilePath_WAL { return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL]; } -- (NSString *)dbPath ++ (void)migrateToSharedData { [OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath sharedDataFilePath:self.newDatabaseFilePath @@ -461,32 +463,13 @@ void setDatabaseInitialized() [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); - } +- (NSString *)dbPath +{ + DDLogVerbose(@"databasePath: %@", TSStorageManager.newDatabaseFilePath); - DDLogError(@"databasePath: %@", self.newDatabaseFilePath); - [DDLog flushLog]; - - return self.newDatabaseFilePath; + return TSStorageManager.newDatabaseFilePath; } + (BOOL)isDatabasePasswordAccessible diff --git a/SignalServiceKit/src/Util/AppVersion.m b/SignalServiceKit/src/Util/AppVersion.m index 44fc99807..2c5dd8815 100755 --- a/SignalServiceKit/src/Util/AppVersion.m +++ b/SignalServiceKit/src/Util/AppVersion.m @@ -3,6 +3,7 @@ // #import "AppVersion.h" +#import NSString *const kNSUserDefaults_FirstAppVersion = @"kNSUserDefaults_FirstAppVersion"; NSString *const kNSUserDefaults_LastAppVersion = @"kNSUserDefaults_LastVersion"; @@ -36,24 +37,22 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion = @"kNSUserDefault // The version of the app when it was first launched. // nil if the app has never been launched before. - self.firstAppVersion = [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_FirstAppVersion]; + self.firstAppVersion = [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_FirstAppVersion]; // The version of the app the last time it was launched. // nil if the app has never been launched before. - self.lastAppVersion = [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_LastAppVersion]; + self.lastAppVersion = [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_LastAppVersion]; self.lastCompletedLaunchAppVersion = - [[NSUserDefaults standardUserDefaults] objectForKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; + [[NSUserDefaults appUserDefaults] objectForKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; // Ensure the value for the "first launched version". if (!self.firstAppVersion) { self.firstAppVersion = self.currentAppVersion; - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_FirstAppVersion]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_FirstAppVersion]; } // Update the value for the "most recently launched version". - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_LastAppVersion]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion forKey:kNSUserDefaults_LastAppVersion]; + [[NSUserDefaults appUserDefaults] synchronize]; DDLogInfo(@"%@ firstAppVersion: %@", self.logTag, self.firstAppVersion); DDLogInfo(@"%@ lastAppVersion: %@", self.logTag, self.lastAppVersion); @@ -68,9 +67,9 @@ NSString *const kNSUserDefaults_LastCompletedLaunchAppVersion = @"kNSUserDefault self.lastCompletedLaunchAppVersion = self.currentAppVersion; // Update the value for the "most recently launch-completed version". - [[NSUserDefaults standardUserDefaults] setObject:self.currentAppVersion - forKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [[NSUserDefaults appUserDefaults] setObject:self.currentAppVersion + forKey:kNSUserDefaults_LastCompletedLaunchAppVersion]; + [[NSUserDefaults appUserDefaults] synchronize]; } - (BOOL)isFirstLaunch diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.h b/SignalServiceKit/src/Util/NSUserDefaults+OWS.h new file mode 100644 index 000000000..24bbbcbc2 --- /dev/null +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.h @@ -0,0 +1,17 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@interface NSUserDefaults (OWS) + ++ (NSUserDefaults *)appUserDefaults; + ++ (void)migrateToSharedUserDefaults; + ++ (void)removeAll; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Util/NSUserDefaults+OWS.m b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m new file mode 100644 index 000000000..1bff0e3e3 --- /dev/null +++ b/SignalServiceKit/src/Util/NSUserDefaults+OWS.m @@ -0,0 +1,37 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "NSUserDefaults+OWS.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSUserDefaults (OWS) + ++ (NSUserDefaults *)appUserDefaults +{ + return [[NSUserDefaults alloc] initWithSuiteName:@"group.org.whispersystems.signal.group"]; +} + ++ (void)migrateToSharedUserDefaults +{ + NSUserDefaults *appUserDefaults = self.appUserDefaults; + + NSDictionary *dictionary = [NSUserDefaults standardUserDefaults].dictionaryRepresentation; + for (NSString *key in dictionary) { + id value = dictionary[key]; + OWSAssert(value); + [appUserDefaults setObject:value forKey:key]; + } +} + ++ (void)removeAll +{ + NSString *appDomain = NSBundle.mainBundle.bundleIdentifier; + [NSUserDefaults.standardUserDefaults removePersistentDomainForName:appDomain]; + // TODO: How to clear the shared user defaults? +} + +@end + +NS_ASSUME_NONNULL_END