|
|
@ -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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|