CNContactPickerViewController - how to implement two different CNContactPickerDelegate

40 Views Asked by At

Background:

CNContactPickerViewController's behavior has several modes, which is determined by the choice of functions in the delegate.

Problem: I want to have a view controller that used CNContactPickerViewController in two different ways, I can't set the delegate to self, I need to have two completely different delegates.

It seems like I should create two different classes, each with the purpose of containing the different delegate implementations.

I've already tried a couple alternative approaches, like creating two subclasses of CNContactPickerViewController (one for each delegate I want), and creating a separate classes that have the code all of the CNContactPickerViewController code for each feature, but all these approaches seem to flawed, or have problems.

I'm left with the feeling that trying to isolate only the delegate would be the best approach.

1

There are 1 best solutions below

3
On

You could create 2 subclasses of CNContactPickerViewController and then within your delegate methods decide what to do based on the class type. This way you don't have to create multiple delegate.


class FirstContactPickerViewController: CNContactPickerViewController {}
class SecondContactPickerViewController: CNContactPickerViewController {}

class ContactPickerDelegate: NSObject, CNContactPickerDelegate {
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        if picker is FirstContactPickerViewController {
            print("FIRST STUFF")
        } else if picker is SecondContactPickerViewController {
            print("SECOND STUFF")
        } else {
            print("UNKNOWN CONTACT PICKER")
        }
    }
}

You could also extend that by creating an enum for contact picker type for neater syntax. It is slightly less efficient code though.

Enum

enum ContactPickerType {
    case first
    case second
    
    init?(_ pickerVc: CNContactPickerViewController) {
        if pickerVc is FirstContactPickerViewController {
            self = .first
        } else if pickerVc is SecondContactPickerViewController {
            self = .second
        } else {
            return nil
        }
    }
}

Making your delegate method something like this

    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        guard let pickerType = ContactPickerType(picker) else {
            print("UNKNOWN CONTACT PICKER")
            return
        }
        
        switch pickerType {
        case .first:
            print("FIRST STUFF")
        case .second:
            print("SECOND STUFF")
        }
    }
}