Im trying to fetch a users contacts. Everything works well, except for the fact that when user clicks on button to allow us to access contacts, the contacts gets printed in console, but the segue to the other viewcontroller uses alot of time, and my console output is going like crazy saying:
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread
with a list of stacks...
After reading about the error on StackOverflow, i found out i needed a DispatchQueue.main.async(). However i cant really get where to put it? Can someone explain it to me?
This is the code for the action outlet, when the button is pressed, and where the error occurs:
@IBAction func didTapFindContacts(_ sender: Any) {
fetchContacts()
}
func fetchContacts() {
contactStore.requestAccess(for: .contacts) { (success, error) in
if let error = error {
print("failed to request access:", error)
return
}
if success {
self.performSegue(withIdentifier: "inviteFriends", sender: nil)
let contactStore = CNContactStore()
let keys = [CNContactGivenNameKey,
CNContactPhoneNumbersKey,
CNContactFamilyNameKey] as [Any]
let request = CNContactFetchRequest(keysToFetch: keys as! [CNKeyDescriptor])
do {
try contactStore.enumerateContacts(with: request){ (contact, stop) in
// Array containing all unified contacts from everywhere
let name = contact.givenName
let familyName = contact.familyName
let number = contact.phoneNumbers.first?.value.stringValue
let contactsAppend = ContactStruct(givenName: name, familyName: familyName, number: number!)
self.contacts.append(contactsAppend)
print(name)
}
} catch {
print("unable to fetch contacts")
}
}
//go to other page
}
}
All code that relates to UI needs to run on main thread. In your case it's a segue
DispatchQueue.main.async { [weak self] in
self?.performSegue(withIdentifier: "inviteFriends", sender: nil)
}