Guia completo de Contacts para Swift com exemplos práticos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Contacts para Swift: guia completo com exemplos

1. O que é e para que serve

O framework Contacts (Contacts.framework) é a API oficial da Apple para gerenciar a agenda de contatos em dispositivos iOS, macOS, watchOS e tvOS. Ele substituiu o antigo AddressBook e oferece uma interface moderna e orientada a objetos para acessar os contatos do usuário. O principal objetivo é unificar o processo de leitura, criação, atualização e exclusão de contatos, além de gerenciar grupos de contatos.

Por que usar? Qualquer aplicativo que precise interagir com a agenda telefônica (mensageiros, sistemas CRM, apps de chamadas, redes sociais) deve utilizar o Contacts. O framework permite solicitar permissões de forma segura, carregar grandes volumes de dados com eficiência (através de carregamento paginado e predicados) e trabalhar com contatos unificados (quando uma mesma pessoa é mesclada de várias fontes, como iCloud e Google).

Diferente das soluções antigas, o Contacts tem suporte total ao Swift (incluindo async/await), utiliza o CNContactStore como ponto de entrada único e fornece objetos imutáveis para leitura e mutáveis para escrita, tornando o código mais seguro e previsível.

2. Instalação

O framework Contacts faz parte dos frameworks de sistema da Apple. Você não precisa instalá-lo via gerenciadores de pacotes (CocoaPods, SPM ou Carthage) — ele já está disponível no dispositivo. Basta importar o módulo no seu código.

Importante: Para trabalhar com contatos, é necessário adicionar a chave NSContactsUsageDescription no arquivo Info.plist do seu projeto. Sem isso, o aplicativo será encerrado ao tentar acessar o armazenamento.

Comando (não necessário, mas para clareza):

Como é um framework do sistema, não existem comandos pip, npm ou cargo. Basta adicionar o import no arquivo Swift:

import Contacts

3. Início rápido — exemplo mínimo funcional

Este exemplo solicita permissão para acessar os contatos e exibe no console os nomes de todos os contatos da agenda.

import Contacts
import UIKit

// 1. Cria uma instância do armazenamento
let store = CNContactStore()

// 2. Solicita permissão
store.requestAccess(for: .contacts) { granted, error in
    guard granted else {
        print("Acesso negado: \(error?.localizedDescription ?? "Erro desconhecido")")
        return
    }
    
    // 3. Cria a requisição de busca
    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]
    let request = CNContactFetchRequest(keysToFetch: keysToFetch)
    
    // 4. Executa a busca
    do {
        try store.enumerateContacts(with: request) { contact, stopPointer in
            print("Contato encontrado: \(contact.givenName) \(contact.familyName)")
        }
    } catch {
        print("Erro ao obter contatos: \(error.localizedDescription)")
    }
}

4. Principais métodos/funções/classes

4.1. CNContactStore

Assinatura: class CNContactStore : NSObject

O que faz: Classe central para acessar o banco de dados de contatos. Todas as operações (consultas, salvamento, exclusão) são realizadas através dela.

Exemplo:

let store = CNContactStore()
// Em seguida, use store para todas as operações

4.2. requestAccess(for:completionHandler:)

Assinatura: func requestAccess(for entityType: CNEntityType, completionHandler: @escaping (Bool, Error?) -> Void)

O que faz: Solicita ao usuário permissão para acessar contatos. O parâmetro entityType deve ser .contacts. O completion handler retorna um booleano indicando se a permissão foi concedida e um possível erro.

Exemplo:

store.requestAccess(for: .contacts) { granted, error in
    if granted {
        print("Permissão concedida!")
    } else {
        print("Permissão negada: \(error?.localizedDescription ?? "")")
    }
}

4.3. enumerateContacts(with:using:)

Assinatura: func enumerateContacts(with fetchRequest: CNContactFetchRequest, using block: (CNContact, UnsafeMutablePointer) -> Void) throws

O que faz: Itera sobre todos os contatos que correspondem ao fetch request. O bloco é chamado para cada contato encontrado. Você pode interromper a iteração definindo stopPointer.pointee = true.

Exemplo:

let request = CNContactFetchRequest(keysToFetch: [CNContactGivenNameKey])
try store.enumerateContacts(with: request) { contact, stop in
    print(contact.givenName)
    if contact.givenName == "João" {
        stop.pointee = true // Para a iteração
    }
}

4.4. unifiedContacts(matching:keysToFetch:)

Assinatura: func unifiedContacts(matching predicate: NSPredicate, keysToFetch keys: [CNKeyDescriptor]) throws -> [CNContact]

O que faz: Retorna contatos unificados que correspondem a um predicado. Útil para buscar contatos específicos por identificador ou por outros critérios.

Exemplo:

let predicate = CNContact.predicateForContacts(matchingName: "Maria")
let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: [CNContactGivenNameKey, CNContactFamilyNameKey])
for contact in contacts {
    print("\(contact.givenName) \(contact.familyName)")
}

5. Considerações finais

O framework Contacts é essencial para qualquer aplicativo iOS que precise interagir com a agenda do usuário. Com ele, você pode ler, criar, atualizar e excluir contatos de forma segura e eficiente. Lembre-se sempre de solicitar permissão antes de acessar os dados e de tratar possíveis erros, como permissão negada ou falhas de busca.

Recommendations