加载联系人时警告“不应在主线程上调用此方法”

问题描述 投票:0回答:0

以下代码成功加载并显示列表中的所有联系人。我的问题是我收到紫色警告

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

我做错了什么?

警告图片

swift swiftui contacts
© www.soinside.com 2019 - 2024. All rights reserved.