diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5571ea35c..414ea5ab8 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. // @@ -1130,17 +1130,9 @@ static NSTimeInterval launchStartedAt; [AppVersion.sharedInstance mainAppLaunchDidComplete]; - [Environment.shared.contactsManager setup]; - [Environment.shared.contactsManager startObserving]; - - // If there were any messages in our local queue which we hadn't yet processed. - [SSKEnvironment.shared.messageReceiver handleAnyUnprocessedEnvelopesAsync]; - [SSKEnvironment.shared.batchMessageProcessor handleAnyUnprocessedEnvelopesAsync]; [Environment.shared.audioSession setup]; [SSKEnvironment.shared.reachabilityManager setup]; - [SSKEnvironment.shared.messageSenderJobQueue setup]; - [AppEnvironment.shared.sessionResetJobQueue setup]; if (!Environment.shared.preferences.hasGeneratedThumbnails) { [self.primaryStorage.newDatabaseConnection diff --git a/Signal/src/Jobs/SessionResetJob.swift b/Signal/src/Jobs/SessionResetJob.swift index 7f68eaf5c..4fbac02b2 100644 --- a/Signal/src/Jobs/SessionResetJob.swift +++ b/Signal/src/Jobs/SessionResetJob.swift @@ -23,6 +23,15 @@ public class SessionResetJobQueue: NSObject, JobQueue { public let requiresInternet: Bool = true public var runningOperations: [SessionResetOperation] = [] + @objc + public override init() { + super.init() + + AppReadiness.runNowOrWhenAppWillBecomeReady { + self.setup() + } + } + @objc public func setup() { defaultSetup() 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/OWSContactsManager.h b/SignalMessaging/contacts/OWSContactsManager.h index 4a6f2ed70..7e8ba009c 100644 --- a/SignalMessaging/contacts/OWSContactsManager.h +++ b/SignalMessaging/contacts/OWSContactsManager.h @@ -25,8 +25,6 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; - (id)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage; -- (void)startObserving; - #pragma mark - Accessors @property (nonnull, readonly) ImageCache *avatarCache; @@ -44,8 +42,6 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; - (SignalAccount *)fetchOrBuildSignalAccountForRecipientId:(NSString *)recipientId; - (BOOL)hasSignalAccountForRecipientId:(NSString *)recipientId; -- (void)setup; - #pragma mark - System Contact Fetching // Must call `requestSystemContactsOnce` before accessing this method diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index 5a3158bc7..f0c80d672 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -82,6 +82,12 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan OWSSingletonAssert(); + [AppReadiness runNowOrWhenAppWillBecomeReady:^{ + [self setup]; + + [self startObserving]; + }]; + return self; } @@ -402,10 +408,12 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan { OWSAssertIsOnMainThread(); - NSString *recipientId = notification.userInfo[kNSNotificationKey_ProfileRecipientId]; - OWSAssertDebug(recipientId.length > 0); + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + NSString *recipientId = notification.userInfo[kNSNotificationKey_ProfileRecipientId]; + OWSAssertDebug(recipientId.length > 0); - [self.avatarCache removeAllImagesForKey:recipientId]; + [self.avatarCache removeAllImagesForKey:recipientId]; + }]; } - (void)updateWithContacts:(NSArray *)contacts 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.h b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.h index 017dc21ab..c9664e5aa 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.h +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.h @@ -24,8 +24,6 @@ NS_ASSUME_NONNULL_BEGIN plaintextData:(NSData *_Nullable)plaintextData transaction:(YapDatabaseReadWriteTransaction *)transaction; -- (void)handleAnyUnprocessedEnvelopesAsync; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index 49f05fc88..1ac05f937 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -269,8 +269,10 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo object:nil]; // Start processing. - [AppReadiness runNowOrWhenAppIsReady:^{ - [self drainQueue]; + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self drainQueue]; + } }]; return self; @@ -458,6 +460,12 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo _processingQueue = processingQueue; + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self.processingQueue drainQueue]; + } + }]; + return self; } @@ -475,11 +483,6 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo #pragma mark - instance methods -- (void)handleAnyUnprocessedEnvelopesAsync -{ - [self.processingQueue drainQueue]; -} - - (void)enqueueEnvelopeData:(NSData *)envelopeData plaintextData:(NSData *_Nullable)plaintextData transaction:(YapDatabaseReadWriteTransaction *)transaction 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.h b/SignalServiceKit/src/Messages/OWSMessageReceiver.h index bff0571ba..b9c103090 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.h +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.h @@ -20,7 +20,6 @@ NS_ASSUME_NONNULL_BEGIN + (void)asyncRegisterDatabaseExtension:(OWSStorage *)storage; - (void)handleReceivedEnvelopeData:(NSData *)envelopeData; -- (void)handleAnyUnprocessedEnvelopesAsync; @end diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index 5ad0c8f94..4b484414d 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -248,8 +248,10 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin _finder = finder; _isDrainingQueue = NO; - [AppReadiness runNowOrWhenAppIsReady:^{ - [self drainQueue]; + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self drainQueue]; + } }]; return self; @@ -414,6 +416,12 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin _processingQueue = processingQueue; + [AppReadiness runNowOrWhenAppDidBecomeReady:^{ + if (CurrentAppContext().isMainApp) { + [self.processingQueue drainQueue]; + } + }]; + return self; } @@ -431,11 +439,6 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin #pragma mark - instance methods -- (void)handleAnyUnprocessedEnvelopesAsync -{ - [self.processingQueue drainQueue]; -} - - (void)handleReceivedEnvelopeData:(NSData *)envelopeData { if (envelopeData.length < 1) { 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/MessageSenderJobQueue.swift b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift index 755f6ecdb..3fc626876 100644 --- a/SignalServiceKit/src/Network/MessageSenderJobQueue.swift +++ b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift @@ -25,6 +25,15 @@ import Foundation @objc(SSKMessageSenderJobQueue) public class MessageSenderJobQueue: NSObject, JobQueue { + @objc + public override init() { + super.init() + + AppReadiness.runNowOrWhenAppWillBecomeReady { + self.setup() + } + } + // MARK: @objc(addMessage:transaction:) @@ -56,6 +65,8 @@ public class MessageSenderJobQueue: NSObject, JobQueue { } private func add(message: TSOutgoingMessage, removeMessageAfterSending: Bool, transaction: YapDatabaseReadWriteTransaction) { + assert(AppReadiness.isAppReady()) + let jobRecord: SSKMessageSenderJobRecord do { jobRecord = try SSKMessageSenderJobRecord(message: message, removeMessageAfterSending: false, label: self.jobRecordLabel) 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..f07ee3741 100755 --- a/SignalServiceKit/src/Util/AppReadiness.h +++ b/SignalServiceKit/src/Util/AppReadiness.h @@ -21,7 +21,15 @@ 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(_:)); +// +// * The "will become ready" blocks are called before the "did become ready" blocks. +// * The "will become ready" blocks should be used for internal setup of components +// so that they are ready to interact with other components of the system. +// * The "did become ready" blocks should be used for any work that should be done +// on app launch, especially work that uses other components. +// * We should usually use "did become ready" blocks since they are safer. ++ (void)runNowOrWhenAppWillBecomeReady:(AppReadyBlock)block NS_SWIFT_NAME(runNowOrWhenAppWillBecomeReady(_:)); ++ (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..fb90398d6 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,21 +51,20 @@ 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); if (CurrentAppContext().isRunningTests) { - // We don't need to an any "on app ready" work - // in the tests. + // We don't need to do any "on app ready" work in the tests. return; } @@ -72,7 +73,32 @@ 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 do any "on app ready" work in the tests. + return; + } + + if (self.isAppReady) { + block(); + return; + } + + [self.appDidBecomeReadyBlocks addObject:block]; } + (void)setAppIsReady @@ -97,10 +123,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/SignalServiceKit/src/Util/JobQueue.swift b/SignalServiceKit/src/Util/JobQueue.swift index 588688707..12851fdef 100644 --- a/SignalServiceKit/src/Util/JobQueue.swift +++ b/SignalServiceKit/src/Util/JobQueue.swift @@ -88,7 +88,7 @@ public protocol JobQueue: DurableOperationDelegate { public extension JobQueue { - // MARK: Depenencies + // MARK: Dependencies var dbConnection: YapDatabaseConnection { return SSKEnvironment.shared.primaryStorage.dbReadWriteConnection @@ -106,10 +106,15 @@ public extension JobQueue { func add(jobRecord: JobRecordType, transaction: YapDatabaseReadWriteTransaction) { assert(jobRecord.status == .ready) + jobRecord.save(with: transaction) transaction.addCompletionQueue(.global()) { - self.workStep() + AppReadiness.runNowOrWhenAppDidBecomeReady { + DispatchQueue.global().async { + self.workStep() + } + } } } @@ -283,7 +288,7 @@ public class JobRecordFinder: NSObject, Finder { func allRecords(label: String, status: SSKJobRecordStatus, transaction: YapDatabaseReadTransaction) -> [SSKJobRecord] { var result: [SSKJobRecord] = [] - self.enumerateJobRecords(label: label, status: status, transaction: transaction) { jobRecord, stopPointer in + self.enumerateJobRecords(label: label, status: status, transaction: transaction) { jobRecord, _ in result.append(jobRecord) } return result @@ -293,7 +298,7 @@ public class JobRecordFinder: NSObject, Finder { let queryFormat = String(format: "WHERE %@ = ? AND %@ = ? ORDER BY %@", JobRecordField.status.rawValue, JobRecordField.label.rawValue, JobRecordField.sortId.rawValue) let query = YapDatabaseQuery(string: queryFormat, parameters: [status.rawValue, label]) - self.ext(transaction: transaction).enumerateKeysAndObjects(matching: query) { collection, key, object, stopPointer in + self.ext(transaction: transaction).enumerateKeysAndObjects(matching: query) { _, _, object, stopPointer in guard let jobRecord = object as? SSKJobRecord else { owsFailDebug("expecting jobRecord but found: \(object)") return diff --git a/SignalServiceKit/src/Util/TypingIndicators.swift b/SignalServiceKit/src/Util/TypingIndicators.swift index 898248d13..b608eb821 100644 --- a/SignalServiceKit/src/Util/TypingIndicators.swift +++ b/SignalServiceKit/src/Util/TypingIndicators.swift @@ -56,7 +56,7 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators { public override init() { super.init() - AppReadiness.runNowOrWhenAppIsReady { + AppReadiness.runNowOrWhenAppWillBecomeReady { self.setup() } } diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 7dbe23962..3d0581de0 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -262,9 +262,6 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed AppVersion.sharedInstance().saeLaunchDidComplete() - Environment.shared.contactsManager.setup() - Environment.shared.contactsManager.startObserving() - ensureRootViewController() // We don't need to use OWSMessageReceiver in the SAE. @@ -402,7 +399,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()