Skip to content

Instantly share code, notes, and snippets.

@brendanmckenzie
Last active October 19, 2016 03:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brendanmckenzie/85743e67ba1d652e23b51ad705c71ff6 to your computer and use it in GitHub Desktop.
Save brendanmckenzie/85743e67ba1d652e23b51ad705c71ff6 to your computer and use it in GitHub Desktop.
namespace App
{
public class Contact
{
public object Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AddressBook;
using Contacts;
using Foundation;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(App.iOS.ContactsService))]
namespace App.iOS
{
public class ContactsService : IContactsService
{
IEnumerable<Contact> ReadAddressBook_iOS9(CNContactStore contactStore)
{
var fetchKeys = new[] {
CNContactKey.GivenName,
CNContactKey.FamilyName,
CNContactKey.EmailAddresses,
CNContactKey.PhoneNumbers };
NSError error;
var containers = contactStore.GetContainers(null, out error);
return containers.Select(container =>
{
using (var pred = CNContact.GetPredicateForContactsInContainer(container.Identifier))
{
return contactStore.GetUnifiedContacts(pred, fetchKeys, out error)
.Select(ent => new Contact
{
FirstName = ent.GivenName,
LastName = ent.FamilyName,
Id = ent.Identifier,
Email = ent.EmailAddresses.FirstOrDefault()?.Value,
Phone = ent.PhoneNumbers.FirstOrDefault()?.Value?.ToString()
});
}
}).SelectMany(ent => ent).OrderBy(ent => ent.LastName).ThenBy(ent => ent.FirstName).ToList();
}
public void GetAllContacts_iOS9(Action<IEnumerable<Contact>> callback)
{
switch (CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts))
{
case CNAuthorizationStatus.NotDetermined:
using (var contactStore = new CNContactStore())
{
contactStore.RequestAccess(CNEntityType.Contacts, (granted, error) =>
{
if (granted)
{
callback(ReadAddressBook_iOS9(contactStore));
}
else
{
callback(Enumerable.Empty<Contact>());
}
});
}
break;
case CNAuthorizationStatus.Authorized:
using (var contactStore = new CNContactStore())
{
callback(ReadAddressBook_iOS9(contactStore));
}
break;
default:
callback(Enumerable.Empty<Contact>());
break;
}
}
IEnumerable<Contact> ReadAddressBook_iOS8(ABAddressBook addressBook)
{
return addressBook.GetPeople().Select(ent => new Contact
{
FirstName = ent.FirstName,
LastName = ent.LastName,
Id = ent.Id,
Email = ent.GetEmails().GetValues().FirstOrDefault(),
Phone = ent.GetPhones().GetValues().FirstOrDefault()
}).OrderBy(ent => ent.LastName).ThenBy(ent => ent.FirstName).ToList();
}
public void GetAllContacts_iOS8(Action<IEnumerable<Contact>> callback)
{
switch (ABAddressBook.GetAuthorizationStatus())
{
case ABAuthorizationStatus.NotDetermined:
using (var addressBook = new ABAddressBook())
{
addressBook.RequestAccess((granted, error) =>
{
if (granted)
{
callback(ReadAddressBook_iOS8(addressBook));
}
else
{
callback(Enumerable.Empty<Contact>());
}
});
}
break;
case ABAuthorizationStatus.Authorized:
using (var addressBook = new ABAddressBook())
{
callback(ReadAddressBook_iOS8(addressBook));
}
break;
default:
callback(Enumerable.Empty<Contact>());
break;
}
}
public Task<IEnumerable<Contact>> GetAllContacts()
{
return Task.Run(() =>
{
var tcs = new TaskCompletionSource<IEnumerable<Contact>>();
if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
{
GetAllContacts_iOS9((res) => tcs.SetResult(res));
}
else
{
GetAllContacts_iOS8((res) => tcs.SetResult(res));
}
return tcs.Task;
});
}
}
}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace App
{
public interface IContactsService
{
Task<IEnumerable<Contact>> GetAllContacts();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment