Skip to content

Chaintech-Network/CMP-contact-manager

Repository files navigation

CMPContactsManager

Maven Central Kotlin Compose Multiplatform

badge-android badge-ios

CMPContactsManager Banner

Overview

ContactsManager is a comprehensive, cross-platform library designed to simplify access and management of contacts on Android and iOS devices. It provides a unified API for retrieving, normalizing, and displaying contact information including phone numbers and avatars, making it ideal for mobile applications built with Kotlin Multiplatform or native platforms.

Features

  • Retrieve contacts with names, phone numbers, email, Address and avatars.
  • Fetch phone numbers with or without Country code.
  • Support for Android and iOS platforms.
  • Contact Avatar view with fallback placeholder with Initials of the contact, customizable with backgroundColor,textColor and cornerRadius
  • Handles runtime permissions on Android and iOS.
  • Observe Live changes to contacts even when app is in the background
  • Save contacts option with native sheet
  • Cross-platform API for Kotlin Multiplatform projects.

Installation

Maven Central

Add the following dependency to your build.gradle or build.gradle.kts:

dependencies {
    implementation("network.chaintech:cmp-contact-manager:1.0.0")
}

Make sure to include Maven Central in your repositories:

repositories {
    mavenCentral()
}

USAGE

Permission Request

To get permission we are using CMPEasyPermission library which makes it really convenient and easy to get permission and it can also be used for many other permissions.

Check it out here 👉 https://github.com/Chaintech-Network/CMPEasyPermission

commonMain.dependencies {
    implementation("network.chaintech:cmp-easy-permission:1.0.3")
}

iOS

Info.plist

Add the following key to your Info.plist file to request access to contacts:

<key>NSContactsUsageDescription</key>
<string>This app requires access to contacts to display your contacts list.</string>

##Start by creating a ContactRepository object

val repository = createContactsRepository(componentActivity = componentActivity)

Fetch Contacts

Example: Ask Permission and Retrieve Contacts

 RequestPermission(
    permission = PermissionState.READ_CONTACTS,
    openSetting = true,
    isGranted = { isGranted ->
        permissionGranted = isGranted
        scope.launch {
            if (isGranted) {
                withContext(Dispatchers.Default) {
                    contacts = repository.getContacts()
                }
            }
        }
    },
    deniedDialogTitle = "App requires access to your contacts",
    deniedDialogDesc = "You can enable this permission in the settings",
)

Example: Observe live changes in Contacts

LaunchedEffect(repository, permissionGranted) {
    if (permissionGranted == true) {
        repository.observeContactsChanges {
            scope.launch(Dispatchers.Main) {
                val newContacts = try { repository.getContacts() } catch (e: Exception) { emptyList() }
                contacts = newContacts
            }
        }
    }
}

Save Contacts

//Opens the native save contact sheet
scope.launch {
repository.saveContact(context = componentActivity)
}

Native contacts sheet for saving contact with all native features

Contact Model

The Contact data class represents a contact with various properties and computed attributes for convenience.

Properties

  • id: String — Unique identifier of the contact.
  • displayName: String — Full name of the contact.
  • firstName: String — First name or Given Name of the contact.
  • lastName: String — Last name or Family Name of the contact.
  • phoneNumbers: List<String> — List of phone numbers in E.164 normalized format.
  • imageByteArray: ByteArray? — Raw avatar image data if available.
  • imageBitmap: Bitmap? — Platform-specific bitmap representation of the avatar (Android).
  • email: String? — Email address of the contact.
  • address: String? — Postal address of the contact.
  • birthday: String? — Birthday information.
  • company: String? — Company or organization the contact belongs to.

Computed Properties

  • initials: String — The uppercase initials derived from the displayName (up to 2 characters).
  • phoneNumbersWithoutCountryCode: List<String> — Phone numbers normalized by removing country codes, spaces, and dashes for easier comparison.

Avatar Usage

CMPContactsManager avatars

The ContactAvatarView composable is designed to display a contact's avatar image if available, or fallback to showing the contact's initials with a styled background.

Parameters

  • contact: The Contact object whose avatar or initials will be displayed.
  • size: The size (width and height) of the avatar view, typically specified using dp.
  • cornerRadius: The corner radius to apply to the avatar's background or image, allowing for rounded corners.
  • isRandomizedColor (optional): A Boolean flag indicating whether to use a randomly colored background with white initials when no avatar image is available. Defaults to false.

Example Usage in Kotlin Compose

ContactAvatarView(
    contact = contact,
    size = 48.dp,
    cornerRadius = 8.dp,
    isRandomizedColor = true
)

In this example, the avatar will display at 48 dp size with rounded corners of 8 dp. If the contact has an imageBitmap, it will be shown as the avatar. If imageBitmap is null, the view will display the contact's initials. Since isRandomizedColor is set to true, the background behind the initials will be a random color, and the initials will be rendered in white for better contrast. If isRandomizedColor is not specified or set to false, the fallback background will use a default color scheme. This approach ensures a visually consistent and appealing avatar display regardless of whether the contact has an image or not.

The library retrieves contact avatars when available. If no avatar is present, it provides a fallback option by displaying the initials of the contact's name. This ensures a consistent and visually appealing UI.

ContactAvatarView(contact = contact, size = 48.dp, cornerRadius = 8.dp)

Phone Number Options

Use if phone number is needed without country code and leading 0 is also to be stripped

contact.phoneNumbersWithoutCountryCode

otherwise use

contact.phoneNumbers

Cross-Platform Notes

  • The API is designed to be consistent across Android and iOS for Kotlin Multiplatform projects.
  • Platform-specific implementations handle permissions and access nuances.
  • Use the shared API for business logic and UI layer integration.
  • The library supports asynchronous calls on iOS and synchronous or coroutine-based calls on Android.

For more information and updates, visit the GitHub repository.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published