0

I have been using the ABPeoplePickerNavigationController in a project, written in MonoTouch, to pick a specific email address or phone number of a contact.

The code set a delegate, and in the delegate I implemented the ShouldContinue method, and retrieved the contact using the Handle property of all contacts. Unfortunately, it looks like something changed, or that I used undocumented features, or that I was simply lucky, because now when I'm in the process of updating the app for iPhone 5, the code no longer works.

Edit: Ok, my initial thoughts was that this was caused by changes in MonoTouch, since there has been quite a few updates since I last worked on this app. However, I now removed it from my device and downloaded the version I have on the app store, and it crashes in the same manner, null reference exception.

This means it is an iOS upgrade that made my code non-functional.

The goal of my code:

  1. Pick a person's specific email address, not just the person, but navigating into the details of the person, and selecting a specific email address or telephone number.

The below code deals with phone numbers only, the email code looks 95% similar.

Here is the code that constructs the picker:

var picker = new ABPeoplePickerNavigationController();
picker.Init();
picker.DisplayedProperties.Clear();
picker.DisplayedProperties.Add(ABPersonProperty.FirstName);
picker.DisplayedProperties.Add(ABPersonProperty.Phone);
var del = new PhonePickerDelegate();
picker.Delegate = del;

Here is the delegate class:

private class PhonePickerDelegate : ABPeoplePickerNavigationControllerDelegate
{
    public override bool ShouldContinue(ABPeoplePickerNavigationController peoplePicker, IntPtr selectedPerson, int propertyId, int identifier)
    {
        peoplePicker.DismissModalViewControllerAnimated(true);

        // THE NEXT LINE IS THE ONE THAT NO LONGER WORKS
        var contact = peoplePicker.AddressBook.SingleOrDefault(s => s.Handle == selectedPerson) as ABPerson;

        using (var phones = contact.GetPhones())
        {
            int index = phones.GetIndexForIdentifier(identifier);
            var phone = phones.GetValues()[index];
            var name = (contact.FirstName + " " + contact.MiddleName).Trim() + " " + contact.LastName;
            Selected(name + ": " + phone);
        }
        return false;
    }

    public override void Cancelled(ABPeoplePickerNavigationController peoplePicker)
    {
        peoplePicker.DismissModalViewControllerAnimated(true);
    }
}

Unfortunately this code no longer finds the correct contact, as none of the contacts has a Handle value that corresponds to the selectedPerson IntPtr value.

My questions are these:

  1. How can I fix the above code?
  2. Can I fix the above code?
  3. Is there some other class/method/delegate/event or whatnot I should be using instead?
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825

1 Answers1

0

You could do something like the following: Note that AppDelegate.navigation would be your current NavigationController


using MonoTouch.AddressBookUI;
using MonoTouch.AddressBook;

ABPeoplePickerNavigationController _contactController = new ABPeoplePickerNavigationController ();
            AppDelegate.navigation.PresentViewController (_contactController, true, null);

            _contactController.Cancelled += delegate {
                AppDelegate.navigation.DismissViewController (true, null);
                return;
            };

            _contactController.SelectPerson += delegate(object sender, ABPeoplePickerSelectPersonEventArgs e) {
                _importedContact = e.Person;
                AppDelegate.navigation.DismissViewController (true, delegate {
                    // What to do when you dismiss the picker here.
                });
            };

e.Person is only going to give you the whole contact. You would want to do something like:

e.Person.GetEmails().FirstOrDefault

Hope this helps

BRogers
  • 3,534
  • 4
  • 23
  • 32