Jay Bhalani
Jay Bhalani

Reputation: 4171

How to Implement Limited Contact Picker in iOS 18 with CNContactPickerViewController?

I am currently using CNContactPickerViewController in my Swift app to allow users to select contacts. With the introduction of the new iOS 18 feature for Limited Contact Access, I want to modify my implementation so that only the contacts selected by the user in the Limited Contact Access permission screen are displayed.

Is there a way to show only the limited contacts in the CNContactPickerViewController once the user grants permission for Limited Contact Access in iOS 18? If so, what adjustments do I need to make in the Swift code to support this?

Here’s the current Swift code I’m using for the contact picker:

@IBAction func addContactBtnEvent(_ sender: Any) {
        PermissionsService.shared.requestContactsAccess { [weak self] isGranded in
            DispatchQueue.main.async {
                if isGranded {
                    if #available(iOS 18.0, *) {
                        if CNContactStore.authorizationStatus(for: .contacts) == .limited {
                            // Fetch limited access contacts
                        }
                    } else {
                        // Fallback on earlier versions
                        self?.presentContactPickerViewController()
                    }
                } else {
                    self?.showContactSettingsAlert()
                }
            }
        }
    }

func requestContactsAccess(completion: @escaping (_ granted: Bool) -> Void) {
        let contactStore = CNContactStore()
        let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
        switch authorizationStatus {
        case .authorized:
            completion(true)
        case .denied, .restricted:
            completion(false)
        case .limited:
            completion(true)
        case .notDetermined:
            contactStore.requestAccess(for: .contacts) { granted, error in
                if granted {
                    completion(true)
                } else {
                    completion(false)
                }
            }
        @unknown default:
            fatalError()
        }
    }

func presentContactPickerViewController() {
        let contactPicker = CNContactPickerViewController()
        contactPicker.delegate = self
        contactPicker.predicateForEnablingContact = NSPredicate(format: "%K.@count > 0", CNContactPhoneNumbersKey)
        self.present(contactPicker, animated: true, completion: nil)
    }

Upvotes: 0

Views: 655

Answers (1)

Paulw11
Paulw11

Reputation: 114984

CNContactPickerViewController and limited contact access are two related, but independent ways of allowing the user to limit an app's access to their contacts.

CNContactPickerViewController allows the app to provide one-time access to a selected contact. Your app doesn't need to request contact access permissions to use it.

Limited contact access provides your app with ongoing access to a selected set of contacts. This provides the user with more control than the "full contact access" permission which grants an app ongoing access to all current and future contacts; A much broader permission than the user may desire.

If you do need ongoing access to a set of contacts and want the user to select one of those contacts then you will need to build your own selection screen.

Upvotes: 1

Related Questions