授予联系人权限后,Tableview 不会重新加载
Tableview won't reload after contacts permission granted
我正在使用 Swift 4.2 和 Xcode 10.2.1。
在联系人权限请求出现并获得批准后,我需要帮助重新加载表格视图。目前,对话框显示在首次使用时请求权限,但在首次使用期间授予权限后,tableview 将不会重新加载。如果我关闭应用程序并重新打开,联系人会按预期显示(换句话说,当请求权限对话框不显示时它显示正常)。这是我的代码:
在ContactsViewController
的viewDidLoad
中:
// Load the contacts from the phone
ContactService.fetchContacts(completion: { (contacts) in
if contacts != nil {
self.deviceContacts = contacts!
self.tableView.reloadData()
}
})
在ContactService
中:
static func fetchContacts(completion: @escaping (_ contacts: [Contact]?) -> Void) {
var deviceContacts:[Contact] = [Contact]()
// Set up default storage for the contacts
let store = CNContactStore()
// Request access to the contacts if not already given.
store.requestAccess(for: .contacts) { (granted, error) in
if let error = error {
print("Failed to request access:", error)
completion (nil)
}
if granted {
print("Access granted.")
// Information to retrieve
let keys = [CNContactIdentifierKey, CNContactGivenNameKey, CNContactFamilyNameKey, CNContactNicknameKey, CNContactNameSuffixKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactImageDataKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
// Sort by last name
request.sortOrder = CNContactSortOrder.familyName
do {
try store.enumerateContacts(with: request
, usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in
// Got the contacts from the device, now format as a Contact and put them into our array
let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
deviceContacts.append(formattedContact)
})
} catch let error {
print("Failed to enumerate contacts:", error)
}
} else {
print ("Access denied.")
completion (nil)
}
}
completion(deviceContacts)
}
我尝试在 fetchContacts
的完成中将 dispatchGroup.enter()
和 .leave()
放入 if granted
和 .notify
中,但它没有用。
您需要更改 completion
的位置
try store.enumerateContacts(with: request
, usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in
// Got the contacts from the device, now format as a Contact and put them into our array
let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
deviceContacts.append(formattedContact)
})
completion(deviceContacts)
目前 store.requestAccess(for: .contacts) { (granted, error) in
不应该检索联系人,而且您在这里不需要调度组,因为它是 1 个异步任务,数量不多
requestAccess
的结果出现在后台线程中,因此请考虑
DispatchQueue.main.async {
self.tableView.reloadData()
}
我正在使用 Swift 4.2 和 Xcode 10.2.1。
在联系人权限请求出现并获得批准后,我需要帮助重新加载表格视图。目前,对话框显示在首次使用时请求权限,但在首次使用期间授予权限后,tableview 将不会重新加载。如果我关闭应用程序并重新打开,联系人会按预期显示(换句话说,当请求权限对话框不显示时它显示正常)。这是我的代码:
在ContactsViewController
的viewDidLoad
中:
// Load the contacts from the phone
ContactService.fetchContacts(completion: { (contacts) in
if contacts != nil {
self.deviceContacts = contacts!
self.tableView.reloadData()
}
})
在ContactService
中:
static func fetchContacts(completion: @escaping (_ contacts: [Contact]?) -> Void) {
var deviceContacts:[Contact] = [Contact]()
// Set up default storage for the contacts
let store = CNContactStore()
// Request access to the contacts if not already given.
store.requestAccess(for: .contacts) { (granted, error) in
if let error = error {
print("Failed to request access:", error)
completion (nil)
}
if granted {
print("Access granted.")
// Information to retrieve
let keys = [CNContactIdentifierKey, CNContactGivenNameKey, CNContactFamilyNameKey, CNContactNicknameKey, CNContactNameSuffixKey, CNContactOrganizationNameKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactImageDataKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
// Sort by last name
request.sortOrder = CNContactSortOrder.familyName
do {
try store.enumerateContacts(with: request
, usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in
// Got the contacts from the device, now format as a Contact and put them into our array
let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
deviceContacts.append(formattedContact)
})
} catch let error {
print("Failed to enumerate contacts:", error)
}
} else {
print ("Access denied.")
completion (nil)
}
}
completion(deviceContacts)
}
我尝试在 fetchContacts
的完成中将 dispatchGroup.enter()
和 .leave()
放入 if granted
和 .notify
中,但它没有用。
您需要更改 completion
try store.enumerateContacts(with: request
, usingBlock: { (contact, stopPointerifYouWantToStopEnumerating) in
// Got the contacts from the device, now format as a Contact and put them into our array
let formattedContact = Contact(contactDetails: contact, favoriteNumbers: [], opened: false)
deviceContacts.append(formattedContact)
})
completion(deviceContacts)
目前 store.requestAccess(for: .contacts) { (granted, error) in
不应该检索联系人,而且您在这里不需要调度组,因为它是 1 个异步任务,数量不多
requestAccess
的结果出现在后台线程中,因此请考虑
DispatchQueue.main.async {
self.tableView.reloadData()
}