Contacts for NativePHP Mobile#
Read, create & sync the device address book — straight from Laravel.#
A complete contacts API for your NativePHP mobile app. Query contacts with a fluent builder, create and update entries, manage groups, and handle iOS 18's new limited-access contact picker — all without writing a line of Swift or Kotlin.
Why this plugin?#
- 🔎 Fluent contact search —
Contacts::contacts()->search('John')->withPhoneNumber()->limit(50)->get(). - ✍️ Full CRUD — create, update and delete contacts and groups with typed data objects.
- 🆕 iOS 18 contact access picker — first-class support for Apple's new limited-access flow.
- 📡 Live events —
ContactCreated,ContactUpdated,ContactAccessUpdateddispatched straight into your Livewire components. - 📱 One API, both platforms — iOS Contacts framework and Android ContactsContract, unified.
Features at a glance#
| Feature | Android | iOS |
|---|---|---|
| Read / search contacts | ✅ | ✅ |
| Create / update / delete contacts | ✅ | ✅ |
| Groups | ✅ | ✅ |
| Limited-access contact picker | — | iOS 18+ |
| Real-time events | ✅ | ✅ |
Perfect for#
CRMs · Sales & outreach tools · Messaging & social apps · Dialer / VoIP · Event & conference apps · Field-service & delivery
Installation#
composer require srwiez/nativephp-mobile-contactsphp artisan vendor:publish --tag=nativephp-plugins-providerphp artisan native:plugin:register srwiez/nativephp-mobile-contacts
Usage#
use SRWieZ\NativePHP\Mobile\Contacts\Facades\Contacts;use SRWieZ\NativePHP\Mobile\Contacts\Data\ContactData;use SRWieZ\NativePHP\Mobile\Contacts\Data\PhoneNumber;use SRWieZ\NativePHP\Mobile\Contacts\Data\EmailAddress; // Request permission$result = Contacts::requestAccess(); // Query contacts$contacts = Contacts::contacts() ->search('John') ->withPhoneNumber() ->limit(50) ->get(); // Create a contact$contact = Contacts::createContact( ContactData::make() ->name('John', 'Doe') ->organization('Acme Inc') ->addPhone(PhoneNumber::mobile('+1234567890'))); // Update a contact$contact->update( ContactData::make()->jobTitle('Senior Developer')); // Delete a contact$contact->delete();
Updating Contacts: Merge Semantics#
updateContact() only touches the fields you pass — everything else is left
alone. Two consequences worth knowing:
- List fields replace, not append. Passing
phoneNumbersreplaces all of the contact's phone numbers with the ones you send. Same foremailAddresses,postalAddresses,urlAddresses,datesandrelations. - Clearing a field needs an explicit value. The fluent
ContactDatabuilder omits everything you did not set, so it can never clear a field. To clear one, pass a raw array with an explicit empty value:
// Remove all phone numbersContacts::updateContact($contactId, ['phoneNumbers' => []]); // Clear the nicknameContacts::updateContact($contactId, ['nickname' => '']);
Manage Contact Access#
Open the iOS 18+ contact access picker to let users manage which contacts your app can access in limited-access mode. The call is asynchronous — it returns immediately and dispatches a ContactAccessUpdated event when the user finishes.
use SRWieZ\NativePHP\Mobile\Contacts\Facades\Contacts; $success = Contacts::manageContactAccess(); // true if picker was presented
Platform behavior:
- iOS 18+ — Opens
contactAccessPicker, allowing the user to select multiple contacts in limited-access mode. - iOS < 18 — Returns
falsewith an error (Contact access picker requires iOS 18.0 or later). - Android — Not available (iOS-only feature).
JavaScript:
import { mobileContacts } from '../../vendor/srwiez/nativephp-mobile-contacts/resources/js/MobileContacts.js'; await mobileContacts.manageContactAccess();
Contact Notes (iOS Restriction)#
Apple locks the contact note field behind a special entitlement
(com.apple.developer.contacts.notes) that must be requested from Apple and is
rarely granted.
- Without the entitlement (the default): creating or updating a contact with
a note on iOS saves everything except the note, and the bridge response
includes a
warning. Reading a contact on iOS never returns its note. - With the entitlement: notes save and behave normally.
- Android: notes work with no restrictions.
Listening for Events#
use Native\Mobile\Attributes\OnNative;use SRWieZ\NativePHP\Mobile\Contacts\Events\ContactCreated;use SRWieZ\NativePHP\Mobile\Contacts\Events\ContactAccessUpdated; #[OnNative(ContactCreated::class)]public function handleContactCreated(string $contactId, ?int $timestamp = null){ // Contact was created} #[OnNative(ContactAccessUpdated::class)]public function handleContactAccessUpdated($identifiers, $contacts, $count, $timestamp){ // $identifiers — array of native contact IDs the user selected // $contacts — array of full contact data for each selected contact // $count — number of contacts updated // $timestamp — Unix timestamp of the selection}
Available Events#
| Event | Parameters |
|---|---|
ContactAccessGranted |
$status (PermissionStatus), $timestamp |
ContactAccessDenied |
$reason, $timestamp |
ContactCreated |
$contactId, $timestamp |
ContactUpdated |
$contactId, $timestamp |
ContactDeleted |
$contactId, $timestamp |
ContactAccessUpdated |
$identifiers, $contacts, $count, $timestamp |
GroupCreated |
$groupId, $name, $timestamp |
GroupDeleted |
$groupId, $timestamp |
All events live in the SRWieZ\NativePHP\Mobile\Contacts\Events namespace.
Version Support#
| Platform | Minimum Version |
|---|---|
| Android | 5.0 (API 21) |
| iOS | 18.0 |
Features requiring higher versions:
- iOS 18+:
manageContactAccess()contact access picker for limited-access mode
Support#
Bugs, questions, and feature requests should be reported at github.com/SRWieZ/nativephp-mobile-packages.