Задача: взять контакты пользователя из устройства и вывести их в виде таблицы. Оказалось, это довольно просто, достаточно вставить одну встроенную в Foundation библиотеку и написать один метод.
Сначала импортируем библиотеку:
import UIKit
import Contacts
После чего создаём модель для контакта. Имя, фамилия и номер телефона - этого достаточно:
struct FetchedContact {
let givenName: String
let familyName: String
let phoneNumber: String
}
В ViewController создаём массив:
private var contacts: [FetchedContact] = []
Добавим метод fetchContacts(для запроса контактов. Сначала он просит доступ к контактам, после чего, если доступ дан (if granted {) он делает запрос к списку контактов (я оставил ключевые слова для имён, фамилий и телефонов, хотя последний не использовал), затем добавляет их в массив, и там же этот массив сортирует по алфавиту. После этого в главном треде происходит обновление таблицы (всё это время таблица пустая, и наверное, при большом списке контактов, заполнение массива и его сортировка могут занять некоторое время, в этом случае стоит добавить индикатор активности).
func fetchContacts() {
let store = CNContactStore()
store.requestAccess(for: .contacts) { (granted, error) in
if let error = error {
print(“Failed to request access:”, error)
return
}
guard granted else {
print(“Access denied”)
return
}
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
do {
try store.enumerateContacts(with: request, usingBlock: { (contact, _) in
self.contacts.append(FetchedContact(givenName: contact.givenName,
familyName: contact.familyName,
phoneNumber: contact.phoneNumbers.first?.value.stringValue ?? “”))
self.contacts.sort { $0.givenName < $1.givenName }
})
} catch let error {
print(“Failed to enumerate contact:”, error)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
Не забываем его вызвать:
override func viewDidLoad() {
super.viewDidLoad()
fetchContacts()
}
Вызов функции - чуть ли не самое важное при её написании
Для работы таблицы добавляем расширение с функциями таблицы:
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = contacts[indexPath.row].givenName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
print(contacts[indexPath.row])
}
}
При нажатии на ячейку в консоль выводится имя-фамилия-номер контакта.
Ещё одна вещь, которую нужно сделать: в файле Info.plist добавляем строчку
Key | Type | Value |
---|---|---|
Privacy - Contacts Usage Description | String | Please grant access to your contacts to invite friends |
Готово!