Never request contacts permission if app is in the background.

pull/1/head
Matthew Chen 8 years ago
parent 05fc966afd
commit 5c90bc72df

@ -109,6 +109,7 @@
#import <SignalServiceKit/TSStorageManager+Calling.h> #import <SignalServiceKit/TSStorageManager+Calling.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h> #import <SignalServiceKit/TSStorageManager+SessionStore.h>
#import <SignalServiceKit/TSThread.h> #import <SignalServiceKit/TSThread.h>
#import <SignalServiceKit/Threading.h>
#import <WebRTC/RTCAudioSession.h> #import <WebRTC/RTCAudioSession.h>
#import <WebRTC/RTCCameraPreviewView.h> #import <WebRTC/RTCCameraPreviewView.h>
#import <YYImage/YYImage.h> #import <YYImage/YYImage.h>

@ -373,32 +373,40 @@ class SystemContactsFetcher: NSObject {
* *
* @param completion completion handler is called on main thread. * @param completion completion handler is called on main thread.
*/ */
public func requestOnce(completion: ((Error?) -> Void)?) { public func requestOnce(completion completionParam: ((Error?) -> Void)?) {
AssertIsOnMainThread() AssertIsOnMainThread()
// Ensure completion is invoked on main thread.
let completion = { error in
DispatchMainThreadSafe({
completionParam?(error)
})
}
guard !systemContactsHaveBeenRequestedAtLeastOnce else { guard !systemContactsHaveBeenRequestedAtLeastOnce else {
completion?(nil) completion(nil)
return return
} }
setupObservationIfNecessary() setupObservationIfNecessary()
switch authorizationStatus { switch authorizationStatus {
case .notDetermined: case .notDetermined:
if UIApplication.shared.applicationState == .background {
Logger.error("\(self.TAG) do not request contacts permission when app is in background")
completion(nil)
return
}
self.contactStoreAdapter.requestAccess { (granted, error) in self.contactStoreAdapter.requestAccess { (granted, error) in
if let error = error { if let error = error {
Logger.error("\(self.TAG) error fetching contacts: \(error)") Logger.error("\(self.TAG) error fetching contacts: \(error)")
DispatchQueue.main.async { completion(error)
completion?(error)
}
return return
} }
guard granted else { guard granted else {
// This case should have been caught be the error guard a few lines up. // This case should have been caught be the error guard a few lines up.
owsFail("\(self.TAG) declined contact access.") owsFail("\(self.TAG) declined contact access.")
DispatchQueue.main.async { completion(nil)
completion?(nil)
}
return return
} }
@ -410,9 +418,7 @@ class SystemContactsFetcher: NSObject {
self.updateContacts(completion: completion) self.updateContacts(completion: completion)
case .denied, .restricted: case .denied, .restricted:
Logger.debug("\(TAG) contacts were \(self.authorizationStatus)") Logger.debug("\(TAG) contacts were \(self.authorizationStatus)")
DispatchQueue.main.async { completion(nil)
completion?(nil)
}
} }
} }
@ -437,9 +443,16 @@ class SystemContactsFetcher: NSObject {
updateContacts(completion: nil, alwaysNotify: true) updateContacts(completion: nil, alwaysNotify: true)
} }
private func updateContacts(completion: ((Error?) -> Void)?, alwaysNotify: Bool = false) { private func updateContacts(completion completionParam: ((Error?) -> Void)?, alwaysNotify: Bool = false) {
AssertIsOnMainThread() AssertIsOnMainThread()
// Ensure completion is invoked on main thread.
let completion = { error in
DispatchMainThreadSafe({
completionParam?(error)
})
}
systemContactsHaveBeenRequestedAtLeastOnce = true systemContactsHaveBeenRequestedAtLeastOnce = true
setupObservationIfNecessary() setupObservationIfNecessary()
@ -452,13 +465,13 @@ class SystemContactsFetcher: NSObject {
case .success(let result): case .success(let result):
fetchedContacts = result fetchedContacts = result
case .error(let error): case .error(let error):
completion?(error) completion(error)
return return
} }
guard let contacts = fetchedContacts else { guard let contacts = fetchedContacts else {
owsFail("\(self.TAG) contacts was unexpectedly not set.") owsFail("\(self.TAG) contacts was unexpectedly not set.")
completion?(nil) completion(nil)
} }
let contactsHash = HashableArray(contacts).hashValue let contactsHash = HashableArray(contacts).hashValue
@ -494,7 +507,7 @@ class SystemContactsFetcher: NSObject {
guard shouldNotifyDelegate else { guard shouldNotifyDelegate else {
Logger.info("\(self.TAG) no reason to notify delegate.") Logger.info("\(self.TAG) no reason to notify delegate.")
completion?(nil) completion(nil)
return return
} }
@ -503,7 +516,7 @@ class SystemContactsFetcher: NSObject {
self.lastContactUpdateHash = contactsHash self.lastContactUpdateHash = contactsHash
self.delegate?.systemContactsFetcher(self, updatedContacts: contacts) self.delegate?.systemContactsFetcher(self, updatedContacts: contacts)
completion?(nil) completion(nil)
} }
} }
} }

@ -4,7 +4,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
typedef void (^SimpleBlock)(); typedef void (^SimpleBlock)(void);
// The block is executed immediately if called from the // The block is executed immediately if called from the
// main thread; otherwise it is disptached async to the // main thread; otherwise it is disptached async to the

Loading…
Cancel
Save