I need to fetch contacts at application launch and store them with Core Data.
For fetching I have following method:
static var fetchAllContacts: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
// Run this in the background async
// Get access to the Contacts store
let store = CNContactStore()
// Specify which data keys we want to fetch
let keys = [CNContactGivenNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
DispatchQueue.global(qos: .background).async {
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
DispatchQueue.main.async {
// Call method to fetch all contacts
do {
try store.enumerateContacts( //This method should not be called on the main thread as it may lead to UI unresponsiveness.
with: fetchRequest,
usingBlock: { contact, _ in
// Do something with the contact
let newItem = Item(context: viewContext)
newItem.id = UUID()
newItem.timestamp = Date()
newItem.givenName = contact.givenName
do {
try viewContext.save()
} catch {
/*
Replace this implementation with code to handle the error appropriately.
fatalError() causes the application to generate a crash log and terminate.
You should not use this function in a shipping application,
although it may be useful during development.
*/
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
)
} catch {
// If there was an error, handle it here
print("Error")
}
}
}
return result
}()
However with Xcode 14 I have alert that asks to separate threads.
try store.enumerateContacts( //This method should not be called on the main thread as it may lead to UI unresponsiveness.
How may I move store.enumerateContacts
out of the main thread so that it will fix an alert.