以下代码成功加载并显示列表中的所有联系人。我的问题是我收到紫色警告
enumerateContacts(with:)
方法,请参见下图。
此方法不应在主线程上调用,因为它可能导致 UI 无响应。
struct ContactsView: View {
@State private var contacts:[CNContact] = []
@State private var restrictedAccess = true
@State private var restrictedAccessMessage = "Restricted Access!"
@State private var showLoadingContactsErrorAlert = false
var body: some View {
NavigationView {
VStack {
List {
ForEach(contacts, id:\.self) { contact in
VStack{
HStack{
Text("\(contact.givenName)")
Text("\(contact.familyName)")
.fontWeight(.bold)
Spacer()
}
HStack{
Text(contact.phoneNumbers.first?.value.stringValue ?? "")
Spacer()
}
}
.foregroundColor(.label)
}
}
.onAppear{
checkAccessToContacts()
}
}
}
}
func checkAccessToContacts(){
let authStatus = CNContactStore.authorizationStatus(for: .contacts)
switch authStatus {
case .restricted:
restrictedAccessMessage = "The app doesn't have access to your contacts, check parental controls and make sure you give the app access."
return
case .denied:
restrictedAccessMessage = "You previously denied this app to access contacts. To grant access, go into Settings"
return
case .notDetermined:
restrictedAccess = false
requestAccess()
case .authorized:
restrictedAccess = false
Task.init{
await fetchAllContacts()
}
default:
print("Not determined.")
requestAccess()
}
}
func requestAccess(){
CNContactStore().requestAccess(for: .contacts) { success, error in
if !success {
print("Not authorized to access contacts. Error = \(String(describing: error))")
showLoadingContactsErrorAlert = true
return
}
restrictedAccess = false
Task.init{
await fetchAllContacts()
}
}
}
func fetchAllContacts() async{
let store = CNContactStore()
let keys = [CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactFamilyNameKey] as [CNKeyDescriptor]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
do{
try store.enumerateContacts(with: fetchRequest, usingBlock: { contact, result in
// add all contacts to the contacts array
self.contacts.append(contact)
})
}catch let error{
print ("Error \(error)")
}
}
}
我尝试将
do
包裹在 DispatchQueue.global().async
内,但随后我收到其他警告 Main actor-isolated property 'contacts' can not be mutated from a non-isolated context; this is an error in Swift 6
在线 self.contacts.append(contact)
DispatchQueue.global().async {
do{
try store.enumerateContacts(with: fetchRequest, usingBlock: { contact, result in
// add all contacts to the contacts array
self.contacts.append(contact)
})
}catch let error{
print ("Error \(error)")
}
}