diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index bc8348e08..9be20ed8a 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -523,7 +523,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; // Avoid blocking app launch by putting all further possible DB access in async block dispatch_async(dispatch_get_main_queue(), ^{ [TSSocketManager requestSocketOpen]; - [[Environment getCurrent].contactsManager fetchSystemContactsIfAlreadyAuthorized]; + [[Environment getCurrent].contactsManager fetchSystemContactsOnceIfAlreadyAuthorized]; // This will fetch new messages, if we're using domain fronting. [[PushManager sharedManager] applicationDidBecomeActive]; diff --git a/Signal/src/ViewControllers/NewContactThreadViewController.m b/Signal/src/ViewControllers/NewContactThreadViewController.m index db580df2f..556a55945 100644 --- a/Signal/src/ViewControllers/NewContactThreadViewController.m +++ b/Signal/src/ViewControllers/NewContactThreadViewController.m @@ -146,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert([NSThread isMainThread]); - [self.contactsViewHelper.contactsManager fetchSystemContactsIfAlreadyAuthorizedAndIgnoreDebounce]; + [self.contactsViewHelper.contactsManager fetchSystemContactsIfAlreadyAuthorizedAndAlwaysNotify]; [refreshControl endRefreshing]; } diff --git a/Signal/src/contact/OWSContactsManager.h b/Signal/src/contact/OWSContactsManager.h index 76e4fa4a8..c10f8c2de 100644 --- a/Signal/src/contact/OWSContactsManager.h +++ b/Signal/src/contact/OWSContactsManager.h @@ -71,8 +71,10 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; // Ensure's the app has the latest contacts, but won't prompt the user for contact // access if they haven't granted it. -- (void)fetchSystemContactsIfAlreadyAuthorized; -- (void)fetchSystemContactsIfAlreadyAuthorizedAndIgnoreDebounce; +- (void)fetchSystemContactsOnceIfAlreadyAuthorized; +// This variant will fetch system contacts if contact access has already been granted, +// but not prompt for contact access. Also, it will always fire a notification. +- (void)fetchSystemContactsIfAlreadyAuthorizedAndAlwaysNotify; #pragma mark - Util diff --git a/Signal/src/contact/OWSContactsManager.m b/Signal/src/contact/OWSContactsManager.m index 0e3b279a7..3e4c3604a 100644 --- a/Signal/src/contact/OWSContactsManager.m +++ b/Signal/src/contact/OWSContactsManager.m @@ -93,15 +93,14 @@ NSString *const kTSStorageManager_lastKnownContactRecipientIds = @"lastKnownCont [self.systemContactsFetcher requestOnceWithCompletion:completion]; } - -- (void)fetchSystemContactsIfAlreadyAuthorized +- (void)fetchSystemContactsOnceIfAlreadyAuthorized { - [self.systemContactsFetcher fetchIfAlreadyAuthorizedWithIgnoreDebounce:NO]; + [self.systemContactsFetcher fetchOnceIfAlreadyAuthorized]; } -- (void)fetchSystemContactsIfAlreadyAuthorizedAndIgnoreDebounce +- (void)fetchSystemContactsIfAlreadyAuthorizedAndAlwaysNotify { - [self.systemContactsFetcher fetchIfAlreadyAuthorizedWithIgnoreDebounce:YES]; + [self.systemContactsFetcher fetchIfAlreadyAuthorizedAndAlwaysNotify]; } - (BOOL)isSystemContactsAuthorized diff --git a/Signal/src/contact/SystemContactsFetcher.swift b/Signal/src/contact/SystemContactsFetcher.swift index 947ed8611..b3d92aa9a 100644 --- a/Signal/src/contact/SystemContactsFetcher.swift +++ b/Signal/src/contact/SystemContactsFetcher.swift @@ -361,7 +361,7 @@ class SystemContactsFetcher: NSObject { hasSetupObservation = true self.contactStoreAdapter.startObservingChanges { [weak self] in DispatchQueue.main.async { - self?.updateContacts(completion: nil) + self?.updateContacts(completion: nil, alwaysNotify: false) } } } @@ -380,7 +380,6 @@ class SystemContactsFetcher: NSObject { completion?(nil) return } - systemContactsHaveBeenRequestedAtLeastOnce = true setupObservationIfNecessary() switch authorizationStatus { @@ -417,16 +416,28 @@ class SystemContactsFetcher: NSObject { } } - public func fetchIfAlreadyAuthorized(ignoreDebounce: Bool = false) { + public func fetchOnceIfAlreadyAuthorized() { AssertIsOnMainThread() guard authorizationStatus == .authorized else { return } + guard !systemContactsHaveBeenRequestedAtLeastOnce else { + return + } - updateContacts(completion: nil, ignoreDebounce:ignoreDebounce) + updateContacts(completion: nil, alwaysNotify:false) } - private func updateContacts(completion: ((Error?) -> Void)?, ignoreDebounce: Bool = false) { + public func fetchIfAlreadyAuthorizedAndAlwaysNotify() { + AssertIsOnMainThread() + guard authorizationStatus == .authorized else { + return + } + + updateContacts(completion: nil, alwaysNotify:true) + } + + private func updateContacts(completion: ((Error?) -> Void)?, alwaysNotify: Bool = false) { AssertIsOnMainThread() systemContactsHaveBeenRequestedAtLeastOnce = true @@ -434,8 +445,9 @@ class SystemContactsFetcher: NSObject { DispatchQueue.global().async { - var fetchedContacts: [Contact]? + Logger.info("\(self.TAG) fetching contacts") + var fetchedContacts: [Contact]? switch self.contactStoreAdapter.fetchContacts() { case .success(let result): fetchedContacts = result @@ -457,7 +469,7 @@ class SystemContactsFetcher: NSObject { if self.lastContactUpdateHash != contactsHash { Logger.info("\(self.TAG) contact hash changed. new contactsHash: \(contactsHash)") shouldNotifyDelegate = true - } else if ignoreDebounce { + } else if alwaysNotify { Logger.info("\(self.TAG) ignoring debounce.") shouldNotifyDelegate = true } else {