One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

CNContactViewController

View, create and edit contacts using the system Contacts UI.

One.iOS.CNContactViewController presents ContactsUI’s native contact card or editor inside a navigation controller. Set ios.infoPlist.NSContactsUsageDescription. The bound initializer forms are new CNContactViewController({ forContact }), { forUnknownContact }, and { forNewContact }. Pass undefined for an empty new contact.

import { One } from 'one'
const draft = new One.iOS.CNMutableContact()
draft.givenName = 'Ada'
draft.familyName = 'Lovelace'
const controller = new One.iOS.CNContactViewController({ forNewContact: draft })
controller.contactStore = new One.iOS.CNContactStore()
controller.delegate = {
contactViewController: async (sender, { didCompleteWith }) => {
// undefined means Cancel; otherwise this is the native saved CNContact.
await sender.dismiss()
},
}
await controller.present()

The delegate owns dismissal, as in ContactsUI. present() resolves after presentation, before Save or Cancel. Completion adapts the SDK’s labeled contactViewController(_:didCompleteWith:) method to a JavaScript result object. A nil contact becomes undefined. No saved contact is fabricated for cancellation, and completion is delivered at most once per presentation. Interactive sheet dismissal ends presentation ownership without synthesizing a Save or Cancel delegate result.

To display an existing contact, fetch the SDK’s required keys. The existing shared Contacts service can request permission or find identifiers; its plain records are not native CNContact objects.

await One.Contacts.requestPermission()
const store = new One.iOS.CNContactStore()
const contact = await store.unifiedContact({
withIdentifier: identifier,
keysToFetch: [One.iOS.CNContactViewController.descriptorForRequiredKeys()],
})
const viewer = new One.iOS.CNContactViewController({ forContact: contact })
viewer.contactStore = store
viewer.allowsEditing = false
await viewer.present()

CNContactStore.unifiedContact adapts Swift’s throwing fetch to a promise and labeled arguments to an options object. keysToFetch accepts SDK string keys and native key descriptors. The contact initializers reject incomplete fetches before ContactsUI can raise a missing-property exception. Store fetching uses native authorization, including limited contacts access. Use the existing One.Contacts.requestPermission() to request access.

CNContact results retain native contacts. The bound subset includes identifier, name and organization fields, isKeyAvailable, and mutableCopy. A mutable copy is independent and retains the SDK contact identifier. CNMutableContact uses SDK empty-string defaults. Reading or changing a field that was not fetched throws; changing an immutable contact requires mutableCopy() first. Phone numbers, addresses, images, dates and other contact properties are editable in the native UI but are not exposed by this CNContact subset.

The card preserves SDK defaults for its initializer mode. Use displayedPropertyKeys, alternateName, message, allowsEditing, allowsActions, shouldShowLinkedContacts, and highlightProperty to configure it. contactStore = undefined clears the SDK store. Parent groups and containers are not bound. The synchronous shouldPerformDefaultActionFor delegate method is not bound because JavaScript callbacks execute on a different thread from UIKit. Its native default remains in effect; allowsActions can disable actions.

Contact valuesTypeDescription
identifierstringNative contact identifier.
stringNative contact identifier.
namePrefixstringName prefix.
stringName prefix.
givenNamestringGiven name.
stringGiven name.
middleNamestringMiddle name.
stringMiddle name.
familyNamestringFamily name.
stringFamily name.
nameSuffixstringName suffix.
stringName suffix.
nicknamestringNickname.
stringNickname.
organizationNamestringOrganization name.
stringOrganization name.
jobTitlestringJob title.
stringJob title.
isKeyAvailable(key: string) => booleanWhether the SDK fetched the property.
(key: string) => booleanWhether the SDK fetched the property.
mutableCopy() => CNMutableContactValueIndependent native mutable copy.
() => CNMutableContactValueIndependent native mutable copy.
Mutable contact fieldsTypeDescription
namePrefixstringMutable name prefix.
stringMutable name prefix.
givenNamestringMutable given name.
stringMutable given name.
middleNamestringMutable middle name.
stringMutable middle name.
familyNamestringMutable family name.
stringMutable family name.
nameSuffixstringMutable name suffix.
stringMutable name suffix.
nicknamestringMutable nickname.
stringMutable nickname.
organizationNamestringMutable organization name.
stringMutable organization name.
jobTitlestringMutable job title.
stringMutable job title.
StoreTypeDescription
unifiedContact(options: CNContactFetchOptions) => Promise<CNContactValue>Fetches a native contact with the requested keys.
(options: CNContactFetchOptions) => Promise<CNContactValue>Fetches a native contact with the requested keys.
Fetch argumentsTypeDescription
withIdentifierstringStored contact identifier.
stringStored contact identifier.
keysToFetch(string | CNKeyDescriptor)[]SDK string keys and required-key descriptors.
(string | CNKeyDescriptor)[]SDK string keys and required-key descriptors.
ControllerTypeDescription
contactCNContactValueNative displayed contact, readonly.
CNContactValueNative displayed contact, readonly.
delegateCNContactViewControllerDelegate | nullReceives saved contact or cancellation.
CNContactViewControllerDelegate | nullReceives saved contact or cancellation.
contactStoreCNContactStoreValue | undefinedSDK store used for edits and additions.
CNContactStoreValue | undefinedSDK store used for edits and additions.
displayedPropertyKeysstring[] | undefinedVisible SDK property keys; undefined shows all.
string[] | undefinedVisible SDK property keys; undefined shows all.
alternateNamestring | undefinedDisplay name when no contact name exists.
string | undefinedDisplay name when no contact name exists.
messagestring | undefinedMessage displayed under the name.
string | undefinedMessage displayed under the name.
allowsEditingbooleanSDK editing permission for the card.
booleanSDK editing permission for the card.
allowsActionsbooleanWhether native contact actions appear.
booleanWhether native contact actions appear.
shouldShowLinkedContactsbooleanWhether linked contacts appear.
booleanWhether linked contacts appear.
highlightProperty(withKey: string, identifier?: string) => voidHighlights a property or labeled-value identifier.
(withKey: string, identifier?: string) => voidHighlights a property or labeled-value identifier.
present(animated?: boolean) => Promise<void>Presents native navigation and contact UI; animated defaults to true.
(animated?: boolean) => Promise<void>Presents native navigation and contact UI; animated defaults to true.
dismiss(animated?: boolean) => Promise<void>Dismisses the native UI; animated defaults to true.
(animated?: boolean) => Promise<void>Dismisses the native UI; animated defaults to true.

Sources: CNContactViewController, CNContactViewControllerDelegate. Generated Nitro ABI and the React Native fixture remain native CI acceptance gates. Permission denial, limited access, and known-contact editing require additional runtime acceptance; a transport-shim SDK probe does not satisfy them.

Edit this page on GitHub.