mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Don't mark app as ready until all version migrations are done.
This commit is contained in:
parent
3e09143a3e
commit
be1fde905c
15 changed files with 167 additions and 20 deletions
|
@ -60,6 +60,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
@property (nonatomic) UIWindow *screenProtectionWindow;
|
||||
@property (nonatomic) BOOL hasInitialRootViewController;
|
||||
@property (nonatomic) BOOL areVersionMigrationsComplete;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -167,7 +168,11 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
[VersionMigrations performUpdateCheck];
|
||||
[VersionMigrations performUpdateCheckWithCompletion:^{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[self versionMigrationsDidComplete];
|
||||
}];
|
||||
|
||||
// Accept push notification when app is not open
|
||||
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
|
@ -819,11 +824,43 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)versionMigrationsDidComplete
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
DDLogInfo(@"%@ versionMigrationsDidComplete", self.logTag);
|
||||
|
||||
self.areVersionMigrationsComplete = YES;
|
||||
|
||||
[self checkIfAppIsReady];
|
||||
}
|
||||
|
||||
- (void)storageIsReady
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
DDLogInfo(@"%@ storageIsReady", self.logTag);
|
||||
|
||||
[self checkIfAppIsReady];
|
||||
}
|
||||
|
||||
- (void)checkIfAppIsReady
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
// App isn't ready until storage is ready AND all version migrations are complete.
|
||||
if (!self.areVersionMigrationsComplete) {
|
||||
return;
|
||||
}
|
||||
if (![OWSStorage isStorageReady]) {
|
||||
return;
|
||||
}
|
||||
if ([AppReadiness isAppReady]) {
|
||||
// Only mark the app as ready once.
|
||||
return;
|
||||
}
|
||||
|
||||
DDLogInfo(@"%@ checkIfAppIsReady", self.logTag);
|
||||
|
||||
[OWSPreferences setIsRegistered:[TSAccountManager isRegistered]];
|
||||
|
||||
// Note that this does much more than set a flag;
|
||||
|
|
|
@ -2,11 +2,15 @@
|
|||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#define RECENT_CALLS_DEFAULT_KEY @"RPRecentCallsDefaultKey"
|
||||
|
||||
typedef void (^VersionMigrationCompletion)(void);
|
||||
|
||||
@interface VersionMigrations : NSObject
|
||||
|
||||
+ (void)performUpdateCheck;
|
||||
+ (void)performUpdateCheckWithCompletion:(VersionMigrationCompletion)completion;
|
||||
|
||||
+ (BOOL)isVersion:(NSString *)thisVersionString
|
||||
atLeast:(NSString *)openLowerBoundVersionString
|
||||
|
@ -17,3 +21,5 @@
|
|||
+ (BOOL)isVersion:(NSString *)thisVersionString lessThan:(NSString *)thatVersionString;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#import <SignalServiceKit/TSNetworkManager.h>
|
||||
#import <YapDatabase/YapDatabase.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#define NEEDS_TO_REGISTER_PUSH_KEY @"Register For Push"
|
||||
#define NEEDS_TO_REGISTER_ATTRIBUTES @"Register Attributes"
|
||||
|
||||
|
@ -28,11 +30,12 @@
|
|||
|
||||
#pragma mark Utility methods
|
||||
|
||||
+ (void)performUpdateCheck
|
||||
+ (void)performUpdateCheckWithCompletion:(VersionMigrationCompletion)completion
|
||||
{
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
OWSAssert([Environment current]);
|
||||
OWSAssert(completion);
|
||||
|
||||
NSString *previousVersion = AppVersion.instance.lastAppVersion;
|
||||
NSString *currentVersion = AppVersion.instance.currentAppVersion;
|
||||
|
@ -47,6 +50,9 @@
|
|||
OWSDatabaseMigrationRunner *runner =
|
||||
[[OWSDatabaseMigrationRunner alloc] initWithStorageManager:[TSStorageManager sharedManager]];
|
||||
[runner assumeAllExistingMigrationsRun];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,7 +85,8 @@
|
|||
[self clearBloomFilterCache];
|
||||
}
|
||||
|
||||
[[[OWSDatabaseMigrationRunner alloc] initWithStorageManager:[TSStorageManager sharedManager]] runAllOutstanding];
|
||||
[[[OWSDatabaseMigrationRunner alloc] initWithStorageManager:[TSStorageManager sharedManager]]
|
||||
runAllOutstandingWithCompletion:completion];
|
||||
}
|
||||
|
||||
+ (BOOL)isVersion:(NSString *)thisVersionString
|
||||
|
@ -189,3 +196,5 @@
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWS100RemoveTSRecipientsMigration.h"
|
||||
|
@ -19,6 +19,8 @@ static NSString *const OWS100RemoveTSRecipientsMigrationId = @"100";
|
|||
|
||||
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(transaction);
|
||||
|
||||
NSUInteger legacyRecipientCount = [transaction numberOfKeysInCollection:@"TSRecipient"];
|
||||
DDLogWarn(@"Removing %lu objects from TSRecipient collection", (unsigned long)legacyRecipientCount);
|
||||
[transaction removeAllObjectsInCollection:@"TSRecipient"];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWS101ExistingUsersBlockOnIdentityChange.h"
|
||||
|
@ -24,6 +24,8 @@ static NSString *const OWS101ExistingUsersBlockOnIdentityChangeMigrationId = @"1
|
|||
|
||||
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(transaction);
|
||||
|
||||
OWSFail(@"[OWS101ExistingUsersBlockOnIdentityChange] has been obviated.");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWS102MoveLoggingPreferenceToUserDefaults.h"
|
||||
|
@ -20,6 +20,8 @@ static NSString *const OWS102MoveLoggingPreferenceToUserDefaultsMigrationId = @"
|
|||
|
||||
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(transaction);
|
||||
|
||||
DDLogWarn(@"[OWS102MoveLoggingPreferenceToUserDefaultsMigrationId] copying existing logging preference to "
|
||||
@"NSUserDefaults");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWS103EnableVideoCalling.h"
|
||||
|
@ -18,8 +18,10 @@ static NSString *const OWS103EnableVideoCallingMigrationId = @"103";
|
|||
}
|
||||
|
||||
// Override parent migration
|
||||
- (void)runUp
|
||||
- (void)runUpWithCompletion:(OWSDatabaseMigrationCompletion)completion
|
||||
{
|
||||
OWSAssert(completion);
|
||||
|
||||
DDLogWarn(@"%@ running migration...", self.logTag);
|
||||
if ([TSAccountManager isRegistered]) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
@ -28,18 +30,24 @@ static NSString *const OWS103EnableVideoCallingMigrationId = @"103";
|
|||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
DDLogInfo(@"%@ successfully ran", self.logTag);
|
||||
[self save];
|
||||
|
||||
completion();
|
||||
}
|
||||
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
if (!IsNSErrorNetworkFailure(error)) {
|
||||
OWSProdError([OWSAnalyticsEvents errorEnableVideoCallingRequestFailed]);
|
||||
}
|
||||
DDLogError(@"%@ failed with error: %@", self.logTag, error);
|
||||
|
||||
completion();
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
DDLogInfo(@"%@ skipping; not registered", self.logTag);
|
||||
[self save];
|
||||
|
||||
completion();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ static NSString *const OWS104CreateRecipientIdentitiesMigrationId = @"104";
|
|||
|
||||
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(transaction);
|
||||
|
||||
NSMutableDictionary<NSString *, NSData *> *identityKeys = [NSMutableDictionary new];
|
||||
|
||||
[transaction
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -20,7 +20,7 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration {
|
|||
|
||||
// Overriding runUp since we have some specific completion criteria which
|
||||
// is more likely to fail since it involves network requests.
|
||||
override public func runUp() {
|
||||
override public func runUp(completion:@escaping ((Void)) -> Void) {
|
||||
guard type(of: self).sharedCompleteRegistrationFixerJob == nil else {
|
||||
owsFail("\(self.TAG) should only be called once.")
|
||||
return
|
||||
|
@ -29,6 +29,8 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration {
|
|||
let job = CompleteRegistrationFixerJob(completionHandler: {
|
||||
Logger.info("\(self.TAG) Completed. Saving.")
|
||||
self.save()
|
||||
|
||||
completion()
|
||||
})
|
||||
|
||||
type(of: self).sharedCompleteRegistrationFixerJob = job
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalServiceKit/TSYapDatabaseObject.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(void);
|
||||
|
||||
@class TSStorageManager;
|
||||
|
||||
@interface OWSDatabaseMigration : TSYapDatabaseObject
|
||||
|
@ -18,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Blocking migrations running too long will crash the app, effectively bricking install
|
||||
// because the user will never get past it.
|
||||
// If you must write a launch-blocking migration, override runUp.
|
||||
- (void)runUp;
|
||||
- (void)runUpWithCompletion:(OWSDatabaseMigrationCompletion)completion;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -46,8 +46,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSRaiseException(NSInternalInconsistencyException, @"Must override %@ in subclass", NSStringFromSelector(_cmd));
|
||||
}
|
||||
|
||||
- (void)runUp
|
||||
- (void)runUpWithCompletion:(OWSDatabaseMigrationCompletion)completion
|
||||
{
|
||||
OWSAssert(completion);
|
||||
|
||||
[self.storageManager.newDatabaseConnection
|
||||
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||
[self runUpWithTransaction:transaction];
|
||||
|
@ -55,6 +57,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
completionBlock:^{
|
||||
DDLogInfo(@"Completed migration %@", self.uniqueId);
|
||||
[self save];
|
||||
|
||||
completion();
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^OWSDatabaseMigrationCompletion)(void);
|
||||
|
||||
@class TSStorageManager;
|
||||
|
||||
@interface OWSDatabaseMigrationRunner : NSObject
|
||||
|
@ -15,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
/**
|
||||
* Run any outstanding version migrations.
|
||||
*/
|
||||
- (void)runAllOutstanding;
|
||||
- (void)runAllOutstandingWithCompletion:(OWSDatabaseMigrationCompletion)completion;
|
||||
|
||||
/**
|
||||
* On new installations, no need to migrate anything.
|
||||
|
|
|
@ -50,21 +50,54 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
}
|
||||
|
||||
- (void)runAllOutstanding
|
||||
- (void)runAllOutstandingWithCompletion:(OWSDatabaseMigrationCompletion)completion
|
||||
{
|
||||
[self runMigrations:self.allMigrations];
|
||||
[self runMigrations:self.allMigrations completion:completion];
|
||||
}
|
||||
|
||||
- (void)runMigrations:(NSArray<OWSDatabaseMigration *> *)migrations
|
||||
completion:(OWSDatabaseMigrationCompletion)completion
|
||||
{
|
||||
OWSAssert(migrations);
|
||||
OWSAssert(completion);
|
||||
|
||||
NSMutableArray<OWSDatabaseMigration *> *migrationsToRun = [NSMutableArray new];
|
||||
for (OWSDatabaseMigration *migration in migrations) {
|
||||
if ([OWSDatabaseMigration fetchObjectWithUniqueID:migration.uniqueId]) {
|
||||
DDLogDebug(@"%@ Skipping previously run migration: %@", self.logTag, migration);
|
||||
} else {
|
||||
DDLogWarn(@"%@ Running migration: %@", self.logTag, migration);
|
||||
[migration runUp];
|
||||
[migrationsToRun addObject:migration];
|
||||
}
|
||||
}
|
||||
|
||||
if (migrationsToRun.count < 1) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSUInteger totalMigrationCount = migrationsToRun.count;
|
||||
__block NSUInteger completedMigrationCount = 0;
|
||||
void (^checkMigrationCompletion)(void) = ^{
|
||||
@synchronized(self)
|
||||
{
|
||||
completedMigrationCount++;
|
||||
if (completedMigrationCount == totalMigrationCount) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (OWSDatabaseMigration *migration in migrationsToRun) {
|
||||
if ([OWSDatabaseMigration fetchObjectWithUniqueID:migration.uniqueId]) {
|
||||
DDLogDebug(@"%@ Skipping previously run migration: %@", self.logTag, migration);
|
||||
} else {
|
||||
DDLogWarn(@"%@ Running migration: %@", self.logTag, migration);
|
||||
[migration runUpWithCompletion:checkMigrationCompletion];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
extern NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange;
|
||||
|
||||
// This class can be safely accessed and used from any thread.
|
||||
|
|
|
@ -20,6 +20,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
|
||||
private var hasInitialRootViewController = false
|
||||
private var isReadyForAppExtensions = false
|
||||
private var areVersionMigrationsComplete = false
|
||||
|
||||
private var progressPoller: ProgressPoller?
|
||||
var loadViewController: SAELoadViewController?
|
||||
|
@ -98,7 +99,11 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
VersionMigrations.performUpdateCheck()
|
||||
VersionMigrations.performUpdateCheck(completion: {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
self.versionMigrationsDidComplete()
|
||||
})
|
||||
|
||||
self.isNavigationBarHidden = true
|
||||
|
||||
|
@ -186,12 +191,44 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func versionMigrationsDidComplete() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.debug("\(self.logTag) \(#function)")
|
||||
|
||||
areVersionMigrationsComplete = true
|
||||
|
||||
checkIsAppReady()
|
||||
}
|
||||
|
||||
@objc
|
||||
func storageIsReady() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.debug("\(self.logTag) \(#function)")
|
||||
|
||||
checkIsAppReady()
|
||||
}
|
||||
|
||||
@objc
|
||||
func checkIsAppReady() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
// App isn't ready until storage is ready AND all version migrations are complete.
|
||||
guard areVersionMigrationsComplete else {
|
||||
return
|
||||
}
|
||||
guard OWSStorage.isStorageReady() else {
|
||||
return
|
||||
}
|
||||
guard AppReadiness.isAppReady() else {
|
||||
// Only mark the app as ready once.
|
||||
return
|
||||
}
|
||||
|
||||
Logger.debug("\(self.logTag) \(#function)")
|
||||
|
||||
// Note that this does much more than set a flag;
|
||||
// it will also run all deferred blocks.
|
||||
AppReadiness.setAppIsReady()
|
||||
|
|
Loading…
Reference in a new issue