Most part of AddressBook framework is deprecated in iOS 9. In the new Contacts Framework documentation only shows how to fetch records matches a NSPredicate
, bu
If you want to get ALL fields of a contact with known identifier:
let contact = unifiedContact(withIdentifier: identifier, keysToFetch: [CNContactVCardSerialization.descriptorForRequiredKeys()])
This gives you an access to ALL fields, such as adresses, phone numbers, full name, etc.
To retrieve fullName then:
let fullname = CNContactFormatter.string(from: contact, style: .fullName)
@flohei answer in Swift-4
var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey] as [Any]
// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containers(matching: nil)
} catch {
print("Error fetching containers")
}
var results: [CNContact] = []
// Iterate all containers and append their contacts to our results array
for container in allContainers {
let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
do {
let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])
results.append(contentsOf: containerResults)
} catch {
print("Error fetching results for container")
}
}
return results
}()
get default container identifier first and use predicate matching container identifier
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let containerId = CNContactStore().defaultContainerIdentifier()
let predicate: NSPredicate = CNContact.predicateForContactsInContainerWithIdentifier(containerId)
let contacts = try CNContactStore().unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)
SWIFT 2
Fetch Full Name, Email Id, Phone Number, Profile Picture from Contacts Framework in iOS9
NOTE Contacts without name has also been handled.
Step 1
import Contacts
Step 2
func fetchContacts(completion: (result: NSMutableArray) -> Void )
{
let finalArrayForContacts = NSMutableArray()
let contactsArray = NSMutableArray()
let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey, CNContactFormatter.descriptorForRequiredKeysForStyle(CNContactFormatterStyle.FullName), CNContactPhoneNumbersKey ,CNContactThumbnailImageDataKey])
do{
try contactStore.enumerateContactsWithFetchRequest(requestForContacts) { (contactStore : CNContact, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
contactsArray.addObject(contactStore)
}
}
catch {
}
if contactsArray.count > 0 {
let formatter = CNContactFormatter()
for contactTemp in contactsArray
{
let contactNew = contactTemp as! CNContact
//Contact Name
var stringFromContact = formatter.stringFromContact(contactNew)
if stringFromContact == nil {
stringFromContact = "Unnamed"
}
var imageData = NSData?()
if contactNew.thumbnailImageData != nil{
imageData = contactNew.thumbnailImageData!
}else{
// imageData = nil
}
var tempArray : NSArray = NSArray()
if (contactNew.phoneNumbers).count > 0 {
tempArray = ((contactNew.phoneNumbers as? NSArray)?.valueForKey("value").valueForKey("digits")) as! NSArray
for i in 0 ..< tempArray.count
{
let newDict = NSMutableDictionary()
let phoneNumber : String = (tempArray.objectAtIndex(i)) as! String
if phoneNumber.characters.count > 0 {
var test = false
if phoneNumber.hasPrefix("+")
{
test = true
}
var resultString : String = (phoneNumber.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
if test == true
{
resultString = "+\(resultString)"
}
newDict.setValue(resultString, forKey: "contact_phone")
newDict.setValue(stringFromContact, forKey: "contact_name")
newDict.setValue("0", forKey: "contact_select")
newDict.setValue(imageData, forKey: "contact_image")
finalArrayForContacts.addObject(newDict)
}
}
}else{
// no number saved
}
}
}else {
print("No Contacts Found")
}
completion(result: finalArrayForContacts)
}
Right now in iOS9 ABAddressBookRef is deprecated so to fetch all contact from phone use this framework and add this function you will get array of contact.
import Contact framework in .h class like this
#import <Contacts/Contacts.h>
then add this method in .m file
-(void)contactsFromAddressBook{
//ios 9+
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(@"error fetching contacts %@", error);
} else {
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
UIImage *profileImage;
NSMutableArray *contactNumbersArray;
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:@"%@",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:@"%@",lastName];
}
else{
fullName=[NSString stringWithFormat:@"%@ %@",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:@"person-icon.png"];
}
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,@"fullName",profileImage,@"userImage",phone,@"PhoneNumbers", nil];
[MutableArray__Contact addObject:personDict];
}
dispatch_async(dispatch_get_main_queue(), ^
{
NSLog(@"%@",ar_Contact);
//[self.tableViewRef reloadData];
});
}
}
}];
}
for using this method call contactsFromAddressBook function
[self contactsFromAddressBook];
Permissions for Contacts iOS 9 SWIFT 2
let status : CNAuthorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts)
if status == CNAuthorizationStatus.NotDetermined{
contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (temp: Bool, error : NSError?) -> Void in
//call contacts fetching function
})
}else if status == CNAuthorizationStatus.Authorized {
//call contacts fetching function
})
}
else if status == CNAuthorizationStatus.Denied {
}
}