> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contactsmanager.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Contacts Search

> Searching for contacts with the ContactsManager SDK

# Contact Search via API

The ContactsManager SDK provides powerful contact search capabilities through its API layer. This section explains the available search endpoints and their usage.

### Comprehensive Search

The `searchContacts` method provides full-featured search functionality with pagination support:

<CodeGroup>
  ```swift Swift theme={null}
  // Perform a comprehensive search with pagination
  let (contacts, totalCount) = try await ContactSearchService.shared.searchContacts(
      query: "john",
      searchFields: [.name, .email, .phone],
      offset: 0,
      limit: 50
  )
  ```

  ```kotlin Kotlin theme={null}
  // Get search service instance
  val searchService = ContactSearchService.getInstance(context)

  // Perform a comprehensive search with pagination
  val result = searchService.searchContacts(
      query = "john",
      fieldType = SearchFieldType.ALL,  // or specific fields like SearchFieldType.NAME
      offset = 0,
      limit = 50
  )

  result.onSuccess { searchResult ->
      val contacts = searchResult.contacts
      val totalCount = searchResult.totalCount
      // Handle search results
  }.onFailure { error ->
      // Handle error
  }
  ```

  ```objc Objective-C theme={null}
  // Get search service via contact service
  CMContactSearchService *searchService = [[CMContactService sharedInstance] searchService];

  // Perform a comprehensive search with pagination
  NSError *error = nil;
  NSArray<CMContact *> *contacts = [searchService searchContactsWithQuery:@"john"
                                                           searchFields:CMSearchFieldTypeAll
                                                                offset:0
                                                                 limit:50
                                                                 error:&error];

  if (error) {
      // Handle error
  } else {
      // Handle search results
  }

  // Or using completion handler
  [searchService searchContactsWithQuery:@"john"
                             fieldType:CMSearchFieldTypeAll
                                offset:0
                                 limit:50
                            completion:^(NSArray<CMContact *> *contacts,
                                       NSInteger totalCount,
                                       NSError *_Nullable error) {
      if (error) {
          // Handle error
      } else {
          // Handle search results and total count
      }
  }];
  ```

  ```jsx React Native theme={null}
  // Perform a comprehensive search with pagination
  const { contacts, totalCount } = await searchContacts({
      query: "john",
      searchFields: ["name", "email", "phone"],
      offset: 0,
      limit: 50
  });
  ```
</CodeGroup>

### Quick Search

For real-time search-as-you-type scenarios, use the optimized `quickSearch` method:

<CodeGroup>
  ```swift Swift theme={null}
  // Quick search optimized for UI interactions
  let results = try await ContactSearchService.shared.quickSearch("jo")
  ```

  ```kotlin Kotlin theme={null}
  // Quick search optimized for UI interactions
  val searchService = ContactSearchService.getInstance(context)
  val result = searchService.quickSearch("jo")

  result.onSuccess { contacts ->
      // Handle quick search results
  }.onFailure { error ->
      // Handle error
  }
  ```

  ```objc Objective-C theme={null}
  // Quick search optimized for UI interactions
  CMContactSearchService *searchService = [[CMContactService sharedInstance] searchService];

  // Using direct method
  NSError *error = nil;
  NSArray<CMContact *> *results = [searchService quickSearchWithQuery:@"jo"
                                                              error:&error];

  // Or using completion handler
  [searchService quickSearchWithQuery:@"jo"
                         completion:^(NSArray<CMContact *> *contacts,
                                    NSError *_Nullable error) {
      if (error) {
          // Handle error
      } else {
          // Handle quick search results
      }
  }];
  ```

  ```jsx React Native theme={null}
  // Quick search optimized for UI interactions
  const results = await quickSearch("jo");
  ```
</CodeGroup>

### Field-Specific Search

You can target specific contact fields in your search:

<CodeGroup>
  ```swift Swift theme={null}
  // Search in specific fields
  let (contacts, total) = try await ContactSearchService.shared.searchContacts(
      query: "developer",
      searchFields: [.organization, .jobTitle]
  )
  ```

  ```kotlin Kotlin theme={null}
  // Search in specific fields
  val searchService = ContactSearchService.getInstance(context)
  val result = searchService.searchContacts(
      query = "developer",
      fieldType = SearchFieldType.ORGANIZATION,  // Search in organization field
      offset = 0,
      limit = 20
  )

  result.onSuccess { searchResult ->
      // Handle search results
  }.onFailure { error ->
      // Handle error
  }
  ```

  ```objc Objective-C theme={null}
  // Search in specific fields
  CMContactSearchService *searchService = [[CMContactService sharedInstance] searchService];

  // Using direct method
  NSError *error = nil;
  NSArray<CMContact *> *contacts = [searchService searchContactsWithQuery:@"developer"
                                                           searchFields:CMSearchFieldTypeOrganization
                                                                offset:0
                                                                 limit:20
                                                                 error:&error];

  // Or using completion handler
  [searchService searchContactsWithQuery:@"developer"
                             fieldType:CMSearchFieldTypeOrganization
                                offset:0
                                 limit:20
                            completion:^(NSArray<CMContact *> *contacts,
                                       NSInteger totalCount,
                                       NSError *_Nullable error) {
      if (error) {
          // Handle error
      } else {
          // Handle search results
      }
  }];
  ```

  ```jsx React Native theme={null}
  // Search in specific fields
  const { contacts, total } = await searchContacts({
      query: "developer",
      searchFields: ["organization", "jobTitle"]
  });
  ```
</CodeGroup>

The following fields can be included in search operations:

* `name`: First, middle, last name, nickname
* `email`: Email addresses
* `phone`: Phone numbers
* `address`: Physical addresses
* `organization`: Company name and department
* `notes`: Contact notes and additional information

# Contact Search UI

The ContactsManager SDK provides a built-in search and select UI that you can easily integrate into your app.

### Using the Contact Picker

<Tabs>
  <Tab title="Swift">
    ### Installation

    The contact picker is included in the ContactsManager SDK for iOS. No additional installation is required.

    ### Configuration

    Configure the picker using `ContactSelectionOptions`:

    ```swift theme={null}
    let options = ContactSelectionOptions(
        selectionMode: .multiple,  // .single or .multiple
        fieldType: .any,          // .phone, .email, .notes, or .any
        maxSelectionCount: 5      // Optional limit for multiple selection
    )
    ```

    ### Usage

    Present the contact picker from your view controller:

    ```swift theme={null}
    ContactsManagerUI.getInstance().searchContacts(
        from: viewController,
        options: options
    ) { result in
        switch result {
        case .success(let contacts):
            // Handle selected contacts
            print("Selected \(contacts.count) contacts")
        case .failure(let error):
            // Handle error
            print("Error: \(error.localizedDescription)")
        }
    }
    ```

    ### Features

    * Beautiful native UI following iOS design guidelines
    * Real-time search across all contact fields
    * Support for single or multiple selection
    * Field-type filtering (phone, email, etc.)
    * Selection limit enforcement
    * Customizable appearance
    * Automatic permission handling
  </Tab>

  <Tab title="Kotlin">
    ### Installation

    The contact picker is included in the ContactsManager SDK for Android. No additional installation is required.

    ### Configuration

    Configure the picker using `ContactSelectionOptions`:

    ```kotlin theme={null}
    val options = ContactSelectionOptions(
        selectionMode = SelectionMode.MULTIPLE,  // SINGLE or MULTIPLE
        fieldType = FieldType.ANY,              // PHONE, EMAIL, NOTES, or ANY
        maxSelectionCount = 5                   // Optional limit for multiple selection
    )
    ```

    ### Usage

    Launch the contact picker from your activity or fragment:

    ```kotlin theme={null}
    ContactsManagerUI.getInstance().searchContacts(
        activity = this,
        options = options
    ) { result ->
        result.onSuccess { contacts ->
            // Handle selected contacts
            println("Selected ${contacts.size} contacts")
        }.onFailure { error ->
            // Handle error
            println("Error: ${error.message}")
        }
    }
    ```

    ### Features

    * Material Design UI following Android guidelines
    * Real-time search functionality
    * Single/multiple selection support
    * Field-type filtering
    * Selection limit enforcement
    * Customizable theming
    * Runtime permission handling
  </Tab>

  <Tab title="Objective-C">
    ### Installation

    The contact picker is included in the ContactsManager SDK. No additional installation required.

    ### Configuration

    ```objc theme={null}
    CMContactSelectionOptions *options = [[CMContactSelectionOptions alloc] 
        initWithSelectionMode:CMSelectionModeMultiple
        fieldType:CMFieldTypeAny
        maxSelectionCount:@5];
    ```

    ### Usage

    ```objc theme={null}
    [[CMContactsManagerUI getInstance] 
        searchContactsFromViewController:self
        options:options
        completion:^(NSArray<CMContact *> *contacts, NSError *error) {
            if (error) {
                NSLog(@"Error: %@", error.localizedDescription);
                return;
            }
            
            NSLog(@"Selected %lu contacts", contacts.count);
        }];
    ```

    ### Features

    * Native iOS UI components
    * Real-time contact search
    * Single/multiple selection support
    * Field filtering capabilities
    * Selection limit enforcement
    * Permission handling
  </Tab>

  <Tab title="React Native">
    ### Installation

    ```bash theme={null}
    npm install @contactsmanager/rn
    # or
    yarn add @contactsmanager/rn
    ```

    ### Configuration

    Configure the picker using options object:

    ```javascript theme={null}
    const options = {
        selectionMode: 'multiple',  // 'single' or 'multiple'
        fieldType: 'any',          // 'phone', 'email', 'notes', or 'any'
        maxSelectionCount: 5       // Optional limit for multiple selection
    };
    ```

    ### Usage

    Show the contact picker in your React Native app:

    ```jsx theme={null}
    import { ContactPicker } from '@contactsmanager/rn';

    try {
        const contacts = await ContactPicker.show(options);
        console.log(`Selected ${contacts.length} contacts`);
    } catch (error) {
        console.error('Error:', error);
    }
    ```

    ### Features

    * Platform-native UI (iOS and Android)
    * Real-time search functionality
    * Support for single/multiple selection
    * Field-type filtering
    * Selection limit enforcement
    * Automatic permission handling
    * Customizable styling
  </Tab>
</Tabs>

### Contact Selection Options

The `ContactSelectionOptions` struct/object allows you to configure:

* `selectionMode`: Single or multiple contact selection
* `fieldType`: Filter contacts by field type (phone, email, any)
* `maxSelectionCount`: Maximum number of contacts that can be selected

# Thread Safety

<Tabs>
  <Tab title="Swift">
    ### Overview

    The Contact model in Swift is built on SwiftData and has important thread safety considerations that must be followed carefully.

    ### Key Thread Safety Rules

    * Contact objects must be accessed on the thread where they were created
    * Search methods return Contact objects that are bound to the main thread
    * Any modifications to Contact objects must be performed on the main thread
    * Background operations should use `@MainActor` or dispatch to the main thread for Contact updates

    ### Best Practices

    * Always use `@MainActor` where accessing Contact objects
  </Tab>

  <Tab title="Kotlin">
    ### Overview

    The Contact model in Kotlin is designed to be thread-safe and coroutine-friendly.

    ### Key Thread Safety Rules

    * All search operations are suspension functions and are safe to call from any coroutine context
    * Results are returned on the caller's coroutine context
    * Contact objects are immutable and thread-safe
    * UI updates should be performed on the main thread

    ### Best Practices

    * Use coroutines for asynchronous operations
    * Use `withContext(Dispatchers.Main)` for UI updates
    * Handle search results using the Kotlin Result type
    * Use structured concurrency with coroutine scopes
  </Tab>

  <Tab title="Objective-C">
    ### Overview

    The Contact model in Objective-C follows standard Cocoa threading patterns.

    ### Key Thread Safety Rules

    * Search operations can be performed on any thread
    * Completion handlers are called on the same thread as the operation
    * UI updates must be performed on the main thread
    * Contact objects are thread-safe for reading

    ### Best Practices

    * Use completion handlers for asynchronous operations
    * Dispatch UI updates to the main queue
    * Use atomic properties for thread safety
    * Follow Apple's threading guidelines
  </Tab>

  <Tab title="React Native">
    ### Overview

    The Contact model in React Native bridges native implementations and follows React Native's threading model.

    ### Key Thread Safety Rules

    * All operations are asynchronous and return Promises
    * Bridge calls are automatically queued and thread-safe
    * UI updates are handled on the main thread
    * Contact objects are immutable

    ### Best Practices

    * Use async/await for clean asynchronous code
    * Handle Promise rejections appropriately
    * Update UI state using React hooks
    * Follow React Native's performance guidelines
  </Tab>
</Tabs>
