简体   繁体   中英

IOS contact postal address in Xamarin.Forms

I am writing a C# app in a Xamarin.Forms project that displays a contact name, and street address. I am having trouble pulling the address from the CNContact and assigning the contacts address to a string.

Its going to be something obvious, but i'm stuck!

    public List<Contact> GetContacts()
    {
        contactList = new List<Contact>();

        var store = new Contacts.CNContactStore();

        var ContainerId = new CNContactStore().DefaultContainerIdentifier;
        var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId);

        var fetchKeys = new NSString[] { CNContactKey.Identifier, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.Birthday, CNContactKey.PostalAddresses, CNContactKey.ImageData };

        NSError error;

        var IPhoneContacts = store.GetUnifiedContacts(predicate, fetchKeys, out error);

        foreach(var c in IPhoneContacts)
        {
            var contact = new Contact();

            contact.FirstName = c.GivenName;
            contact.FamilyName = c.FamilyName;

            if(c.PostalAddresses.Length !=0)
            {
                contact.StreetAddress = CNPostalAddressFormatter.GetStringFrom(c.PostalAddresses, CNPostalAddressFormatterStyle.MailingAddress);
            };

            contactList.Add(contact);
        }

        return contactList;
    }

Fetching Existing Contacts in iOS:

First , you need to add follow permission in Info.plist :

<key>NSContactsUsageDescription</key>  
<string>This app requires contacts access to function properly.</string>

在此处输入图像描述

Second , you can create a model contains of needs contact info as follow:

public class ContactModel
{
    public IList PhoneNumbers { get; set; }
    public string GivenName { get; set; }
    public string FamilyName { get; set; }
}

Third , create a func to fetch info:

public List<ContactModel> ReadContacts()
{
    var response = new List<ContactModel>();
    try
    {
        //We can specify the properties that we need to fetch from contacts  
        var keysToFetch = new[] {
    CNContactKey.PhoneNumbers, CNContactKey.GivenName, CNContactKey.FamilyName,CNContactKey.PostalAddresses,CNContactKey.PhoneNumbers
};
        //Get the collections of containers  
        var containerId = new CNContactStore().DefaultContainerIdentifier;
        //Fetch the contacts from containers  
        using (var predicate = CNContact.GetPredicateForContactsInContainer(containerId))
        {
            CNContact[] contactList;
            using (var store = new CNContactStore())
            {
                contactList = store.GetUnifiedContacts(predicate, keysToFetch, out
                    var error);
            }
            //Assign the contact details to our view model objects  
            response.AddRange(from item in contactList
                                where item?.EmailAddresses != null
                                select new ContactModel
                                {
                                    PhoneNumbers = item.PhoneNumbers,
                                    PostalAddresses = CNPostalAddressFormatter.GetStringFrom(item.PostalAddresses[0].Value, CNPostalAddressFormatterStyle.MailingAddress),
                                    GivenName = item.GivenName,
                                    FamilyName = item.FamilyName
                                });
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
    return response;
}

Fourth , invoke func:

List<ContactModel> contacts = ReadContacts();
ContactModel contactVm;
for (int i = 0; i < contacts.Count; i++)
{
    contactVm = contacts[i];
    Console.WriteLine("Contact is : " + contactVm.FamilyName);
    Console.WriteLine("Contact is : " + contactVm.GivenName);
    Console.WriteLine("Contact is : " + contactVm.PostalAddresses);
}

...
Contact is : Taylor
Contact is : David
Contact is : 1747 Steuart Street
Tiburon CA 94920
USA

Fifth , the screenshot as follow:

在此处输入图像描述

===================================Udate=====================================

Your code should be modified as follow:

public List<Contact> GetContacts()
{
    contactList = new List<Contact>();

    var store = new Contacts.CNContactStore();

    var ContainerId = new CNContactStore().DefaultContainerIdentifier;
    var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId);

    var fetchKeys = new NSString[] { CNContactKey.Identifier, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.Birthday, CNContactKey.PostalAddresses, CNContactKey.ImageData };

    NSError error;

    var IPhoneContacts = store.GetUnifiedContacts(predicate, fetchKeys, out error);

    foreach(var c in IPhoneContacts)
    {
        var contact = new Contact();

        contact.FirstName = c.GivenName;
        contact.FamilyName = c.FamilyName;

        if(c.PostalAddresses.Length !=0)
        {
            contact.StreetAddress = CNPostalAddressFormatter.GetStringFrom(c.PostalAddresses[0].Value, CNPostalAddressFormatterStyle.MailingAddress);
        };

        contactList.Add(contact);
    }

    return contactList;
}

The property postalAddress of Method CNPostalAddressFormatter.GetStringFrom is a type of object( Contacts.CNPostalAddress ), however c.PostalAddresses is a type of Array.

public static string GetStringFrom (Contacts.CNPostalAddress postalAddress, Contacts.CNPostalAddressFormatterStyle style);

在此处输入图像描述

The problem is that CNPostalAddressFormatter.GetStringFrom() method expects a single CNPostalAddress object as a parameter but you're passing all addresses of a single contact since the PostalAddresses property is an array of CNLabeledValue<ValueType> objects.

What you should do is iterate over all addresses, or perhaps just take the first one by default. Really depends on what you want to achieve.

For example, this would get the first CNPostalAddress :

contact.StreetAddress = CNPostalAddressFormatter.GetStringFrom(c.PostalAddresses[0].Value, CNPostalAddressFormatterStyle.MailingAddress);

Also, if you want to know the label of the address (Home, Work etc), you can get it like this:

c.PostalAddresses[0].Label

Then the actual CNPostalAddress object is again this:

c.PostalAddresses[0].Value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM