From 01cf2fc1bddfe96bc5bbc6f81028396283afa5db Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 29 May 2018 16:05:36 -0400 Subject: [PATCH 1/2] Clear the contacts cache if access to the system contacts is revoked. --- SignalMessaging/contacts/OWSContactsManager.m | 12 +++++++++++- SignalMessaging/contacts/SystemContactsFetcher.swift | 12 ++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index d7f453127..2cc9e739e 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -134,7 +134,7 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification return self.systemContactsFetcher.supportsContactEditing; } -#pragma mark SystemContactsFetcherDelegate +#pragma mark - SystemContactsFetcherDelegate - (void)systemContactsFetcher:(SystemContactsFetcher *)systemsContactsFetcher updatedContacts:(NSArray *)contacts @@ -152,6 +152,16 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification [self updateWithContacts:contacts shouldClearStaleCache:shouldClearStaleCache]; } +- (void)systemContactsFetcher:(SystemContactsFetcher *)systemContactsFetcher + hasAuthorizationStatus:(enum ContactStoreAuthorizationStatus)authorizationStatus +{ + if (authorizationStatus == ContactStoreAuthorizationStatusRestricted + || authorizationStatus == ContactStoreAuthorizationStatusDenied) { + // Clear the contacts cache if access to the system contacts is revoked. + [self updateWithContacts:@[] shouldClearStaleCache:YES]; + } +} + #pragma mark - Intersection - (void)intersectContactsWithCompletion:(void (^)(NSError *_Nullable error))completionBlock diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index 1e82fe352..48f07893d 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -109,7 +109,8 @@ class ContactsFrameworkContactStoreAdaptee: ContactStoreAdaptee { } } -public enum ContactStoreAuthorizationStatus { +@objc +public enum ContactStoreAuthorizationStatus: UInt { case notDetermined, restricted, denied, @@ -118,6 +119,7 @@ public enum ContactStoreAuthorizationStatus { @objc public protocol SystemContactsFetcherDelegate: class { func systemContactsFetcher(_ systemContactsFetcher: SystemContactsFetcher, updatedContacts contacts: [Contact], isUserRequested: Bool) + func systemContactsFetcher(_ systemContactsFetcher: SystemContactsFetcher, hasAuthorizationStatus authorizationStatus: ContactStoreAuthorizationStatus) } @objc @@ -212,12 +214,13 @@ public class SystemContactsFetcher: NSObject { self.contactStoreAdapter.requestAccess { (granted, error) in if let error = error { Logger.error("\(self.TAG) error fetching contacts: \(error)") + Logger.flush() completion(error) return } guard granted else { - // This case should have been caught be the error guard a few lines up. + // This case should have been caught by the error guard a few lines up. owsFail("\(self.TAG) declined contact access.") completion(nil) return @@ -231,6 +234,7 @@ public class SystemContactsFetcher: NSObject { self.updateContacts(completion: completion) case .denied, .restricted: Logger.debug("\(TAG) contacts were \(self.authorizationStatus)") + self.delegate?.systemContactsFetcher(self, hasAuthorizationStatus: authorizationStatus) completion(nil) } } @@ -239,6 +243,7 @@ public class SystemContactsFetcher: NSObject { public func fetchOnceIfAlreadyAuthorized() { SwiftAssertIsOnMainThread(#function) guard authorizationStatus == .authorized else { + self.delegate?.systemContactsFetcher(self, hasAuthorizationStatus: authorizationStatus) return } guard !systemContactsHaveBeenRequestedAtLeastOnce else { @@ -253,6 +258,7 @@ public class SystemContactsFetcher: NSObject { SwiftAssertIsOnMainThread(#function) guard authorizationStatus == .authorized else { owsFail("should have already requested contact access") + self.delegate?.systemContactsFetcher(self, hasAuthorizationStatus: authorizationStatus) return } @@ -279,6 +285,8 @@ public class SystemContactsFetcher: NSObject { let completion: (Error?) -> Void = { error in DispatchMainThreadSafe({ completionParam?(error) + + assert(backgroundTask != nil) backgroundTask = nil }) } From 5e166c238ffdef87186444cde84c6a2f5e1114ba Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 30 May 2018 15:33:00 -0400 Subject: [PATCH 2/2] Respond to CR. --- SignalMessaging/contacts/SystemContactsFetcher.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index 48f07893d..672938ac5 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -259,6 +259,7 @@ public class SystemContactsFetcher: NSObject { guard authorizationStatus == .authorized else { owsFail("should have already requested contact access") self.delegate?.systemContactsFetcher(self, hasAuthorizationStatus: authorizationStatus) + completion(nil) return }