diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5571ea35c..56ed19a1a 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -550,7 +550,7 @@ static NSTimeInterval launchStartedAt; if (!AppReadiness.isAppReady) { OWSLogWarn(@"Ignoring openURL: app not ready."); - // We don't need to use [AppReadiness runNowOrWhenAppIsReady:]; + // We don't need to use [AppReadiness runNowOrWhenAppDidBecomeReady:]; // the only URLs we handle in Signal iOS at the moment are used // for resuming the verification step of the registration flow. return NO; @@ -596,7 +596,7 @@ static NSTimeInterval launchStartedAt; [self ensureRootViewController]; - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self handleActivation]; }]; @@ -616,7 +616,7 @@ static NSTimeInterval launchStartedAt; - (void)enableBackgroundRefreshIfNecessary { - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ if (OWS2FAManager.sharedManager.is2FAEnabled && [self.tsAccountManager isRegistered]) { // Ping server once a day to keep-alive 2FA clients. const NSTimeInterval kBackgroundRefreshInterval = 24 * 60 * 60; @@ -732,7 +732,7 @@ static NSTimeInterval launchStartedAt; OWSAssertIsOnMainThread(); [SignalApp clearAllNotifications]; - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [OWSMessageUtils.sharedManager updateApplicationBadgeCount]; }]; } @@ -747,7 +747,7 @@ static NSTimeInterval launchStartedAt; return; } - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ if (![self.tsAccountManager isRegistered]) { UIAlertController *controller = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_WELCOME", nil) @@ -818,7 +818,7 @@ static NSTimeInterval launchStartedAt; return NO; } - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ NSString *_Nullable phoneNumber = handle; if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { phoneNumber = [self.primaryStorage phoneNumberForCallKitId:handle]; @@ -875,7 +875,7 @@ static NSTimeInterval launchStartedAt; return NO; } - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ NSString *_Nullable phoneNumber = handle; if ([handle hasPrefix:CallKitCallManager.kAnonymousCallHandlePrefix]) { phoneNumber = [self.primaryStorage phoneNumberForCallKitId:handle]; @@ -980,7 +980,7 @@ static NSTimeInterval launchStartedAt; } OWSLogInfo(@"%@", notification); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [[PushManager sharedManager] application:application didReceiveLocalNotification:notification]; }]; } @@ -1003,7 +1003,7 @@ static NSTimeInterval launchStartedAt; // later, after this method returns. // // https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [[PushManager sharedManager] application:application handleActionWithIdentifier:identifier forLocalNotification:notification @@ -1032,7 +1032,7 @@ static NSTimeInterval launchStartedAt; // later, after this method returns. // // https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623068-application?language=objc - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [[PushManager sharedManager] application:application handleActionWithIdentifier:identifier forLocalNotification:notification @@ -1045,7 +1045,7 @@ static NSTimeInterval launchStartedAt; performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { OWSLogInfo(@"performing background fetch"); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ __block AnyPromise *job = [AppEnvironment.shared.messageFetcherJob run].then(^{ // HACK: Call completion handler after n seconds. // diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index 59edfd871..5bb0e7064 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -105,13 +105,13 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe { OWSLogInfo(@"received remote notification"); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self.messageFetcherJob run]; }]; } - (void)applicationDidBecomeActive { - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self.messageFetcherJob run]; }]; } @@ -130,7 +130,7 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe // If we want to re-introduce silent pushes we can remove this assert. OWSFailDebug(@"Unexpected content-available push."); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ completionHandler(UIBackgroundFetchResultNewData); }); diff --git a/Signal/src/util/OWSScreenLockUI.m b/Signal/src/util/OWSScreenLockUI.m index 8733561cb..3397272ac 100644 --- a/Signal/src/util/OWSScreenLockUI.m +++ b/Signal/src/util/OWSScreenLockUI.m @@ -138,7 +138,7 @@ NS_ASSUME_NONNULL_BEGIN // // It's not safe to access OWSScreenLock.isScreenLockEnabled // until the app is ready. - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppWillBecomeReady:^{ self.isScreenLockLocked = OWSScreenLock.sharedManager.isScreenLockEnabled; [self ensureUI]; @@ -251,7 +251,7 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertIsOnMainThread(); if (!AppReadiness.isAppReady) { - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppWillBecomeReady:^{ [self ensureUI]; }]; return; diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index d2b2ac0bc..5aed90189 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -214,7 +214,7 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag } - (void)sendConfigurationSyncMessage { - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self sendConfigurationSyncMessage_AppReady]; }]; } diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index 4932ee240..82433ab4d 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -64,7 +64,7 @@ class ContactsFrameworkContactStoreAdaptee: NSObject, ContactStoreAdaptee { @objc func didBecomeActive() { - AppReadiness.runNowOrWhenAppIsReady { + AppReadiness.runNowOrWhenAppDidBecomeReady { let currentSortOrder = CNContactsUserDefaults.shared().sortOrder guard currentSortOrder != self.lastSortOrder else { diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index cbebf20b2..3f66e4766 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -94,7 +94,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); OWSSingletonAssert(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self rotateLocalProfileKeyIfNecessary]; }]; @@ -1479,7 +1479,7 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); - (void)blockListDidChange:(NSNotification *)notification { OWSAssertIsOnMainThread(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self rotateLocalProfileKeyIfNecessary]; }]; } diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index 01b124339..e8e6165b9 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -85,7 +85,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa object:nil]; } - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self updateAccountAttributesIfNecessary]; }]; @@ -683,7 +683,7 @@ NSString *const TSAccountManager_NeedsAccountAttributesUpdateKey = @"TSAccountMa - (void)reachabilityChanged { OWSAssertIsOnMainThread(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self updateAccountAttributesIfNecessary]; }]; } diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index 49f05fc88..ac9968280 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -269,7 +269,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo object:nil]; // Start processing. - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self drainQueue]; }]; diff --git a/SignalServiceKit/src/Messages/OWSBlockingManager.m b/SignalServiceKit/src/Messages/OWSBlockingManager.m index 9c81aa91c..873193adf 100644 --- a/SignalServiceKit/src/Messages/OWSBlockingManager.m +++ b/SignalServiceKit/src/Messages/OWSBlockingManager.m @@ -422,7 +422,7 @@ NSString *const kOWSBlockingManager_SyncedBlockedGroupIdsKey = @"kOWSBlockingMan { OWSAssertIsOnMainThread(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ @synchronized(self) { [self syncBlockListIfNecessary]; diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index 8765de154..63c3d2cd9 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -69,7 +69,7 @@ void AssertIsOnDisappearingMessagesQueue() // suspenders in case a deletion schedule is missed. NSTimeInterval kFallBackTimerInterval = 5 * kMinuteInterval; - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ if (CurrentAppContext().isMainApp) { self.fallbackTimer = [NSTimer weakScheduledTimerWithTimeInterval:kFallBackTimerInterval target:self @@ -405,7 +405,7 @@ void AssertIsOnDisappearingMessagesQueue() { OWSAssertIsOnMainThread(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ dispatch_async(OWSDisappearingMessagesJob.serialQueue, ^{ [self runLoop]; }); diff --git a/SignalServiceKit/src/Messages/OWSIdentityManager.m b/SignalServiceKit/src/Messages/OWSIdentityManager.m index c9cd36a15..a17d6f442 100644 --- a/SignalServiceKit/src/Messages/OWSIdentityManager.m +++ b/SignalServiceKit/src/Messages/OWSIdentityManager.m @@ -569,7 +569,7 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa { OWSAssertIsOnMainThread(); - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self syncQueuedVerificationStates]; }]; } diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 39fee3fac..e25af91e6 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -185,7 +185,7 @@ NS_ASSUME_NONNULL_BEGIN } else { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [OWSMessageUtils.sharedManager updateApplicationBadgeCount]; }]; }); diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index 5ad0c8f94..d9acc5ece 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -248,7 +248,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin _finder = finder; _isDrainingQueue = NO; - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self drainQueue]; }]; diff --git a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m index c81b161ef..9c341988e 100644 --- a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m @@ -65,7 +65,7 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa object:nil]; // Start processing. - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self process]; }]; diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index ce42b8962..b106fbb3b 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -157,7 +157,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE OWSSingletonAssert(); // Start processing. - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self scheduleProcessing]; }]; diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 012c03eed..e2dfef96d 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -122,7 +122,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { } @objc public func setup() { - AppReadiness.runNowOrWhenAppIsReady { + AppReadiness.runNowOrWhenAppDidBecomeReady { guard TSAccountManager.isRegistered() else { return } diff --git a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m index b2f514781..7b284baba 100644 --- a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m +++ b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.m @@ -1048,7 +1048,7 @@ NSString *NSStringFromOWSWebSocketType(OWSWebSocketType type) if (!AppReadiness.isAppReady) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - [AppReadiness runNowOrWhenAppIsReady:^{ + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ [self applyDesiredSocketState]; }]; }); diff --git a/SignalServiceKit/src/Util/AppReadiness.h b/SignalServiceKit/src/Util/AppReadiness.h index 8a446fe93..32ddecd70 100755 --- a/SignalServiceKit/src/Util/AppReadiness.h +++ b/SignalServiceKit/src/Util/AppReadiness.h @@ -21,7 +21,14 @@ typedef void (^AppReadyBlock)(void); // // This method should only be called on the main thread. // The block will always be called on the main thread. -+ (void)runNowOrWhenAppIsReady:(AppReadyBlock)block NS_SWIFT_NAME(runNowOrWhenAppIsReady(_:)); ++ (void)runNowOrWhenAppWillBecomeReady:(AppReadyBlock)block NS_SWIFT_NAME(runNowOrWhenAppWillBecomeReady(_:)); + +// If the app is ready, the block is called immediately; +// otherwise it is called when the app becomes ready. +// +// This method should only be called on the main thread. +// The block will always be called on the main thread. ++ (void)runNowOrWhenAppDidBecomeReady:(AppReadyBlock)block NS_SWIFT_NAME(runNowOrWhenAppDidBecomeReady(_:)); @end diff --git a/SignalServiceKit/src/Util/AppReadiness.m b/SignalServiceKit/src/Util/AppReadiness.m index f8ec61506..efed97e16 100755 --- a/SignalServiceKit/src/Util/AppReadiness.m +++ b/SignalServiceKit/src/Util/AppReadiness.m @@ -11,7 +11,8 @@ NS_ASSUME_NONNULL_BEGIN @property (atomic) BOOL isAppReady; -@property (nonatomic) NSMutableArray *appReadyBlocks; +@property (nonatomic) NSMutableArray *appWillBecomeReadyBlocks; +@property (nonatomic) NSMutableArray *appDidBecomeReadyBlocks; @end @@ -39,7 +40,8 @@ NS_ASSUME_NONNULL_BEGIN OWSSingletonAssert(); - self.appReadyBlocks = [NSMutableArray new]; + self.appWillBecomeReadyBlocks = [NSMutableArray new]; + self.appDidBecomeReadyBlocks = [NSMutableArray new]; return self; } @@ -49,14 +51,14 @@ NS_ASSUME_NONNULL_BEGIN return [self.sharedManager isAppReady]; } -+ (void)runNowOrWhenAppIsReady:(AppReadyBlock)block ++ (void)runNowOrWhenAppWillBecomeReady:(AppReadyBlock)block { DispatchMainThreadSafe(^{ - [self.sharedManager runNowOrWhenAppIsReady:block]; + [self.sharedManager runNowOrWhenAppWillBecomeReady:block]; }); } -- (void)runNowOrWhenAppIsReady:(AppReadyBlock)block +- (void)runNowOrWhenAppWillBecomeReady:(AppReadyBlock)block { OWSAssertIsOnMainThread(); OWSAssertDebug(block); @@ -72,7 +74,33 @@ NS_ASSUME_NONNULL_BEGIN return; } - [self.appReadyBlocks addObject:block]; + [self.appWillBecomeReadyBlocks addObject:block]; +} + ++ (void)runNowOrWhenAppDidBecomeReady:(AppReadyBlock)block +{ + DispatchMainThreadSafe(^{ + [self.sharedManager runNowOrWhenAppDidBecomeReady:block]; + }); +} + +- (void)runNowOrWhenAppDidBecomeReady:(AppReadyBlock)block +{ + OWSAssertIsOnMainThread(); + OWSAssertDebug(block); + + if (CurrentAppContext().isRunningTests) { + // We don't need to an any "on app ready" work + // in the tests. + return; + } + + if (self.isAppReady) { + block(); + return; + } + + [self.appDidBecomeReadyBlocks addObject:block]; } + (void)setAppIsReady @@ -97,10 +125,16 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertIsOnMainThread(); OWSAssertDebug(self.isAppReady); - NSArray *appReadyBlocks = [self.appReadyBlocks copy]; - [self.appReadyBlocks removeAllObjects]; + NSArray *appWillBecomeReadyBlocks = [self.appWillBecomeReadyBlocks copy]; + [self.appWillBecomeReadyBlocks removeAllObjects]; + NSArray *appDidBecomeReadyBlocks = [self.appDidBecomeReadyBlocks copy]; + [self.appDidBecomeReadyBlocks removeAllObjects]; - for (AppReadyBlock block in appReadyBlocks) { + // We invoke the _will become_ blocks before the _did become_ blocks. + for (AppReadyBlock block in appWillBecomeReadyBlocks) { + block(); + } + for (AppReadyBlock block in appDidBecomeReadyBlocks) { block(); } } diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 7dbe23962..d390825da 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -402,7 +402,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.debug("") if isReadyForAppExtensions { - AppReadiness.runNowOrWhenAppIsReady { [weak self] in + AppReadiness.runNowOrWhenAppDidBecomeReady { [weak self] in AssertIsOnMainThread() guard let strongSelf = self else { return } strongSelf.activate()