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.