SDK iOS oficial da Dito para integração com a plataforma de CRM e Marketing Automation
Sobre • Features • Requirements • Installation • Quick Start • API Reference • Push Notifications • Troubleshooting
O DitoSDK é a biblioteca oficial da Dito para aplicações iOS, permitindo que você integre complemente seu app com a plataforma de CRM e Marketing Automation da Dito.
Com o DitoSDK você pode:
- 🔐 Identificar usuários e sincronizar seus dados com a plataforma
- 📊 Rastrear eventos e comportamentos dos usuários
- 🔔 Gerenciar notificações push via Firebase Cloud Messaging
- 🔗 Processar deeplinks de notificações
- 💾 Gerenciar dados offline automaticamente
- 🔒 Converter emails para SHA1 facilmente
A versão 2.0.0 do DitoSDK introduz mudanças que podem quebrar integrações existentes. Leia atentamente e siga os passos de migração abaixo para evitar quebras no seu app (para mais detalhes leia o guia de migração):
-
API de registro de dispositivo: os métodos que aceitavam
tokenTypeforam removidos/deprecados.- Antes:
Dito.registerDevice(token: fcmToken, tokenType: .firebase) - Agora:
Dito.registerDevice(token: fcmToken) - Ação: Remova o parâmetro
tokenTypeem todas as chamadasregisterDeviceeunregisterDevice.
- Antes:
-
Ordem de inicialização do Firebase (iOS 18): é obrigatório configurar o Firebase e definir o token APNS antes de solicitar o token FCM para evitar o erro "APNS device token not set before retrieving FCM Token".
- Ação: No
AppDelegate, chameFirebaseApp.configure()primeiro, depoisMessaging.messaging().delegate = self, e em seguidaDito.configure(). EmdidRegisterForRemoteNotificationsWithDeviceTokenatribuaMessaging.messaging().apnsToken = deviceTokenantes de chamarMessaging.messaging().token { ... }.
- Ação: No
-
CoreData (iOS 16+): várias APIs internas foram alteradas para garantir thread-safety e executar operações em background.
- Ação: Não acesse diretamente contexts do CoreData em background fora das APIs públicas do SDK; verifique chamadas customizadas que manipulam o
viewContext.
- Ação: Não acesse diretamente contexts do CoreData em background fora das APIs públicas do SDK; verifique chamadas customizadas que manipulam o
Checklist rápido de migração:
- Atualize o Podfile para usar DitoSDK 2.0.0+ e rode
pod update DitoSDK. - Remova qualquer uso de
tokenTypenas chamadasregisterDevice/unregisterDevice. - Ajuste a ordem de inicialização no
AppDelegateconforme descrito acima. - Verifique
Info.plist(chavesApiKey,ApiSecret,CFBundleVersion) e oGoogleService-Info.plist. - Rode os testes de compilação e verifique logs de token APNS/FCM.
Consulte MIGRATION_GUIDE.md para instruções completas e exemplos de código.
- ✅ Identificação de Usuários - Sincronize dados completos do usuário com a plataforma Dito
- ✅ Tracking de Eventos - Rastreie eventos personalizados e comportamentos
- ✅ Push Notifications - Integração completa com Firebase Cloud Messaging (FCM)
- ✅ Notificações em Background - Capture notificações mesmo com app em background
- ✅ Deeplink Handling - Processe deeplinks de notificações automaticamente
- ✅ Offline Management - Gerenciamento automático de operações offline
- ✅ SHA1 Conversion - Utilitário para hash de emails
- ✅ Thread-Safe - Compatível com iOS 16+ (CoreData thread-safety)
- ✅ Firebase Integration - Integração nativa com Firebase
- ✅ Suporte a iOS 16+ - Funciona em versões antigas de iOS
| Requisito | Versão Mínima |
|---|---|
| iOS | 16.0+ |
| Xcode | 14.0+ |
| Swift | 5.5+ |
| Firebase iOS SDK | 9.0+ |
| CocoaPods | 1.11.0+ |
pod 'DitoSDK', :git => 'https://github.com/ditointernet/dito_ios.git', :branch => 'v2.0.0'import DitoSDK
import FirebaseAnalytics
import FirebaseCore
import FirebaseMessaging
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
var fcmToken: String?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication
.LaunchOptionsKey: Any]?
) -> Bool {
// ⚠️ ORDEM IMPORTANTE para iOS 18+
// Configure Firebase PRIMEIRO
FirebaseApp.configure()
// Define o delegate do Firebase Messaging para tratar token e mensagens
Messaging.messaging().delegate = self
// Inicializa o Dito SDK (configurações internas do SDK)
Dito.configure()
// Configura o centro de notificações e registra o app para receber push
UNUserNotificationCenter.current().delegate = self
registerForPushNotifications(application: application)
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
// IMPORTANTE: setar o token APNS no Firebase Messaging ANTES de solicitar o token FCM
Messaging.messaging().apnsToken = deviceToken
Messaging.messaging().token { [weak self] fcmToken, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let fcmToken = fcmToken {
self?.fcmToken = fcmToken
print("FCM registration token: \(fcmToken)")
}
}
}
// MARK: Background remote notification (silent / content-available)
// Este método é chamado quando uma notificação silenciosa é recebida
// mesmo que o app esteja em background ou encerrado
// é necessário ter o "Remote notifications" habilitado em Background Modes e "Background fetch" ativado
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
let callNotificationRead: (String) -> Void = { token in
// Garantir que o evento de leitura seja disparado mesmo em background
Dito.notificationRead(with: userInfo, token: token)
// Notifica o Firebase Messaging sobre a mensagem recebida
Messaging.messaging().appDidReceiveMessage(userInfo)
// Chama o completion handler indicando que novos dados foram processados
completionHandler(.newData)
}
if let token = self.fcmToken {
callNotificationRead(token)
} else {
// Fallback: tentar obter o token se ainda não estiver armazenado
Messaging.messaging().token { [weak self] token, error in
if let token = token {
self?.fcmToken = token
callNotificationRead(token)
} else {
print("FCM token indisponível em background: \(error?.localizedDescription ?? "erro desconhecido")")
completionHandler(.noData)
}
}
}
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void
) {
let userInfo = notification.request.content.userInfo
// Notifica o Firebase Messaging sobre a mensagem recebida
Messaging.messaging().appDidReceiveMessage(userInfo)
// Exibe a notificação mesmo quando o app está em primeiro plano
completionHandler([[.banner, .list, .sound, .badge]])
}
private func registerForPushNotifications(application: UIApplication) {
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions
) { granted, error in
if let error = error {
print(
"Error requesting notification authorization: \(error.localizedDescription)"
)
return
}
guard granted else {
print("Notification authorization not granted")
return
}
print("Autorização de notificações concedida")
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
if let token = fcmToken {
Dito.notificationRead(with: userInfo, token: token)
} else {
print("Warning: FCM token not available for notificationRead")
}
// Notifica o Dito SDK sobre o clique na notificação
Dito.notificationClick(with: userInfo)
// Notifica o Firebase Messaging sobre a interação com a notificação
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler()
}
}📚 Documentação Firebase: Firebase Cloud Messaging for iOS
- ✅ Firebase configurado (
GoogleService-Info.plistadicionado) - ✅ Permissões solicitadas (
requestAuthorization) - ✅
registerForRemoteNotifications()chamado - ✅ Token FCM registrado (
Dito.registerDevice(token:)) - ✅
Messaging.messaging().delegate = selfconfigurado - ✅ Capabilities: Push Notifications habilitada
- ✅ Certificates APNs válidos no Firebase Console
- ✅ App não tem notificações desabilitadas em Settings
Documentação Firebase: Troubleshoot FCM for iOS
Causa: Ordem incorreta de inicialização.
Solução: Siga esta ordem EXATA no AppDelegate:
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 1️⃣ Firebase PRIMEIRO
FirebaseApp.configure()
// 2️⃣ Messaging delegate SEGUNDO
Messaging.messaging().delegate = self
// 3️⃣ Dito por último
Dito.configure()
// 4️⃣ Notificações
UNUserNotificationCenter.current().delegate = self
return true
}Importante: No didRegisterForRemoteNotificationsWithDeviceToken, defina o APNS token ANTES de qualquer operação FCM:
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
// ⚠️ SEMPRE PRIMEIRO
Messaging.messaging().apnsToken = deviceToken
// Depois pedir o token FCM
Messaging.messaging().token { token, error in
if let token = token {
Dito.registerDevice(token: token)
}
}
}Causa: willPresent não mostra notificações por padrão.
Solução: Configure completionHandler com opções visuais:
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void
) {
// Mostra com banner, lista e som
if #available(iOS 14.0, *) {
completionHandler([[.banner, .list, .sound, .badge]])
} else {
completionHandler(.alert)
}
}Checklist:
- ✅
apiKeyeapiSecretcorretos no Info.plist - ✅ Usuário identificado ANTES de rastrear:
Dito.identify(id:data:) - ✅ Conexão com internet (ou aguardar sincronização offline)
// ❌ ERRADO - evento antes da identificação
Dito.track(event: event)
Dito.identify(id: userId, data: userData)
// ✅ CORRETO - identifique primeiro
Dito.identify(id: userId, data: userData)
Dito.track(event: event)Causa: Violações de thread-safety ao acessar context de threads background.
Solução: O DitoSDK já é otimizado para iOS 16+. Se tiver problemas:
// Certifique-se que não está acessando viewContext de thread background
// O DitoSDK usa performBackgroundTask automaticamente- 🌐 Website Dito
- 📚 Documentação Dito
- 🔥 Firebase iOS Documentation
- 🔔 Firebase Cloud Messaging iOS
- 📱 Apple User Notifications
O projeto inclui um exemplo completo em SampleApplication/ com:
- ✅ Configuração completa do Firebase
- ✅ Implementação de todos os delegates
- ✅ Identificação de usuários
- ✅ Rastreamento de eventos
- ✅ Gerenciamento de notificações
- ✅ Tratamento de deeplinks
Para executar:
cd /caminho/para/dito_ios
pod install
open DitoSDK.xcworkspace
# Selecione o scheme "Sample" e execute (⌘R)- 🐛 Issues: GitHub Issues
DitoSDK está disponível sob a licença MIT. Veja LICENSE para mais informações.
Dito Team - Dito CRM
Feito com ❤️ pela equipe Dito