简体   繁体   English

IOS 联系邮政地址 Xamarin.Forms

[英]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.我正在 Xamarin.Forms 项目中编写 C# 应用程序,该项目显示联系人姓名和街道地址。 I am having trouble pulling the address from the CNContact and assigning the contacts address to a string.我无法从 CNContact 中提取地址并将联系人地址分配给字符串。

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: 获取 iOS 中的现有联系人

First , you need to add follow permission in Info.plist :首先,您需要在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:其次,您可以创建一个 model 包含的需求联系信息如下:

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:、调用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===================================== ====================================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.方法CNPostalAddressFormatter.GetStringFrom的属性postalAddress是一种对象( Contacts.CNPostalAddress ),但是c.PostalAddresses是一种 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.问题是CNPostalAddressFormatter.GetStringFrom()方法需要一个CNPostalAddress object 作为参数,但您传递的是单个联系人的所有地址,因为PostalAddresses属性是一个CNLabeledValue<ValueType>对象的数组。

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 :例如,这将获得第一个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:此外,如果您想知道地址(家庭、工作等)的 label,您可以这样获取:

c.PostalAddresses[0].Label

Then the actual CNPostalAddress object is again this:那么实际的CNPostalAddress object 又是这样的:

c.PostalAddresses[0].Value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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