Syncing Contacts
Once contacts access is granted, contacts are synced from the device to the cloud automatically without any action required from you.
Automatic Sync
Contacts sync in small batches whenever the app is in the foreground. If Background Sync is enabled, contacts sync even when the app is not active. Even large contact books with 1000+ contacts sync in 60-90 seconds, depending on network conditions.
For subsequent app launches, only unsynced or modified contacts are synchronized, ensuring minimal network and battery usage.
The SDK automatically triggers sync when:
- The app becomes active
- Contact store changes are detected
- Contact access status changes from denied to granted
Sync Metrics and Tracking
You can track the progress and results of contact syncing operations using platform-specific callbacks.
import ContactsManager
// Set up a completion handler to receive sync metrics
ContactsService.shared.onContactsSynced = { metrics in
print("Sync completed with the following metrics:")
print("Total device contacts: \(metrics.totalDeviceContacts)")
print("New contacts added: \(metrics.newContacts)")
print("Updated contacts: \(metrics.updatedContacts)")
print("Unchanged contacts: \(metrics.unchangedContacts)")
print("Deleted contacts: \(metrics.deletedContacts)")
print("Total processed: \(metrics.totalProcessed)")
// Update your UI or notify the user about sync completion
DispatchQueue.main.async {
// Update UI elements
self.updateSyncStatusLabel(metrics: metrics)
}
}
// Example function to update UI
func updateSyncStatusLabel(metrics: SyncMetrics) {
let totalChanged = metrics.newContacts + metrics.updatedContacts + metrics.deletedContacts
if totalChanged > 0 {
syncStatusLabel.text = "Synced \(totalChanged) contact changes"
} else {
syncStatusLabel.text = "Contacts up to date"
}
}
SyncMetrics Structure
The SDK provides detailed metrics through the SyncMetrics
structure:
public struct SyncMetrics {
/// Total number of contacts found on device
public let totalDeviceContacts: Int
/// Number of new contacts added
public let newContacts: Int
/// Number of contacts that were updated
public let updatedContacts: Int
/// Number of contacts that were unchanged
public let unchangedContacts: Int
/// Number of contacts that were deleted
public let deletedContacts: Int
/// Total number of contacts processed
public let totalProcessed: Int
}
These metrics help you understand the scope and impact of each sync operation.
Force Sync
Sometimes you may need to force a complete resync of all contacts, regardless of their current sync status. This is useful when troubleshooting sync issues or ensuring data consistency after server-side changes.
Implementation
import ContactsManager
// Force resync all contacts
do {
let resyncedCount = try await ContactsService.shared.forceResyncAllContacts()
print("Successfully resynced \(resyncedCount) contacts")
} catch {
print("Force resync failed: \(error.localizedDescription)")
}
// You can also use the completion handler to track progress
ContactsService.shared.onContactsSynced = { metrics in
print("Force resync completed:")
print("Total contacts processed: \(metrics.totalProcessed)")
// All contacts will appear as "updated" since sync timestamps were reset
}
Important Notes
- Performance Impact: Force sync processes ALL contacts, which may take longer than regular sync
- Network Usage: This operation will re-upload all contact data
- Use Sparingly: Only use when necessary, as regular incremental sync is more efficient
User Logout
When users log out of your application, you should properly clean up the ContactsManager service to ensure user data privacy and prepare for the next user session.
When to Use Reset
- User Logout: When the current user signs out of your application
- Account Switching: When switching between different user accounts
Implementation
import ContactsManager
// Logout: Clean up ContactsManager when user logs out
do {
// This clears all local contact data and user session
try await ContactsService.shared.reset()
print("User logged out, ContactsManager cleaned up successfully")
} catch {
print("Logout cleanup failed: \(error.localizedDescription)")
}
// When a new user logs in, reinitialize with their credentials
do {
try await ContactsService.shared.initialize(
withToken: "new-user-token",
options: ContactsManagerOptions(
verboseLogging: false,
autoSyncEnabled: true
)
)
print("ContactsManager initialized for new user")
} catch {
print("Initialization failed: \(error.localizedDescription)")
}
What Logout Does
- Clears Local Database: Removes all stored contact data for privacy
- Resets Sync State: Clears all sync timestamps and metadata
- Unsubscribes Events: Stops all background listeners and observers
- Clears User Session: Removes stored user tokens and preferences
- Service State: Returns the service to uninitialized state
Best Practices
- Initial Sync: After getting contacts authorization, let the automatic sync happen without interruption
- Completion Indication: Use the sync metrics to show progress to users when syncing large contact lists
- Background Sync: For the best user experience, enable Background Sync to keep contacts up-to-date even when the app is not active