Моя цель - отображать данные, извлеченные из базы данных области, в табличном представлении, которое я ранее асинхронно добавлял при каждом запуске приложения.
Проблема заключается в том, что при первом запуске приложения табличное представление не показать все данные, извлеченные из базы данных области, но если я потяну их, чтобы обновить sh, отобразятся данные.
Вот что я делаю в следующем коде:
- Я получаю данные (контакты) из структуры контактов Apple и передать их через закрывающий метод, где I:
- Добавить их в базу данных области
- извлечь контакты и сохранить их в массив источника данных (setDataSource )
- создать заголовки разделов для табличного представления
До сих пор я сделал отладку и заметил, что проблема может быть с многопоточностью и параллелизмом, то есть при первом запуске данные добавляются в область асинхронно, поэтому, когда я выбираю контакты, ничего не получается.
Сказать, что я не смог Пока что я обнаружил вышеупомянутую проблему, потому что я не знаю, как это сделать. Я учусь кодировать с использованием потоков и параллелизма, а также использовать область.
Я также видел некоторые сообщения, но ни в одной из них не было схожей проблемы.
Я был бы очень благодарен за ваша помощь. Спасибо!
Контроллер табличного представления:
override func viewDidLoad() {
super.viewDidLoad()
populateTableView() // TODO: Contacts don't show up on first launch of the app after installation.
}
func populateTableView() {
contactManager.populateDataSource(for: self)
tableView.reloadData()
}
Менеджер контактов Класс:
let store = CNContactStore()
let dataBase = DataBase()
var contactsDataSource = [[Contact]]()
var sectionTitles = [String]()
var deletedContactsDataSource = [[Contact]]()
var sectionTitlesForDeletedContactsTable = [String]()
func fetchUserContacts(completion: @escaping ContactsFetchingResult) {
print("Attempting to fetch contacts today...")
store.requestAccess(for: .contacts) { (granted, error) in
if let errorToCatch = error {
print("Failed to request access: ", errorToCatch)
} else if granted {
print("Access granted")
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactThumbnailImageDataKey, CNContactImageDataAvailableKey, CNContactIdentifierKey, CNContactOrganizationNameKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
do {
try self.store.enumerateContacts(with: request, usingBlock: { (contact, stopPointerIfYouWantToStopEnumerating) in
completion(contact, nil)
})
} catch {
completion(nil, error)
}
} else {
print("Access denied")
}
}
}
func populateDataSource(for viewController: UIViewController?) {
fetchUserContacts { (result, error) in
if let errorToCatch = error {
guard let vc = viewController else { return }
UITableViewController.Alert.showFetchingErrorAlert(on: vc, message: errorToCatch.localizedDescription)
} else if let contact = result {
self.dataBase.insert(each: Contact(contact: contact, wasDeleted: false))
self.setDataSource()
self.setSectionTitles()
}
}
}
func setDataSource(from searchTerm: String = "") {
//Not deleted contacts
if !searching {
contactsDataSource = formatResults(from: dataBase.fetchContacts(), using: sectionTitles)
} else {
setDataSourceForFilteredContacts(from: searchTerm)
}
//Deleted contacts
deletedContactsDataSource = formatResults(from: dataBase.fetchDeletedContacts(), using: sectionTitlesForDeletedContactsTable)
}
func setSectionTitles() {
sectionTitles = generateSectionTitles(from: dataBase.fetchContacts())
sectionTitlesForDeletedContactsTable = generateSectionTitles(from: dataBase.fetchDeletedContacts())
}
База данных:
func insert(each contact: Contact) {
let realm = try! Realm()
try! realm.write {
realm.add(contact, update: .modified)
}
}
func fetchContacts() -> Results<Contact> {
let realm = try! Realm()
return realm.objects(Contact.self).filter("wasDeleted = false").sorted(byKeyPath: "firstName", ascending: true)
}