iOS 9中不推荐使用AddressBook框架的大部分内容。在新的Contacts Framework文档中,仅显示了如何获取与匹配的记录NSPredicate
,但是如果我想要所有记录该怎么办?
Answers:
其他两个答案仅会使用加载来自容器的触点defaultContainerIdentifier
。在用户具有多个容器(即同时用于存储联系人的Exchange和iCloud帐户)的情况下,这只会从配置为默认帐户的帐户加载联系人。因此,它不会按照问题作者的要求加载所有联系人。
相反,您可能要做的就是获取所有容器并对其进行迭代以从每个容器中提取所有联系人。以下代码段是如何在其中一个应用程序(在Swift中)中执行此操作的示例:
lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containersMatchingPredicate(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.predicateForContactsInContainerWithIdentifier(container.identifier)
do {
let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
results.appendContentsOf(containerResults)
} catch {
print("Error fetching results for container")
}
}
return results
}()
目标C:
//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 {
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
Contact *newContact = [[Contact alloc] init];
newContact.firstName = contact.givenName;
newContact.lastName = contact.familyName;
UIImage *image = [UIImage imageWithData:contact.imageData];
newContact.image = image;
for (CNLabeledValue *label in contact.phoneNumbers) {
NSString *phone = [label.value stringValue];
if ([phone length] > 0) {
[contact.phones addObject:phone];
}
}
}
}
}
}];
同样,要获取所有联系人,您可以使用enumerateContactsWithFetchRequest
方法:
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];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
NSError *error;
BOOL success = [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) {
if (error) {
NSLog(@"error fetching contacts %@", error);
} else {
// copy data to my custom Contact class.
Contact *newContact = [[Contact alloc] init];
newContact.firstName = contact.givenName;
newContact.lastName = contact.familyName;
// etc.
}
}];
}
}];
如果要按名称过滤联系人,可以使用以下方法:
对象:
// keys from example above
NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:[CNContact predicateForContactsMatchingName:@"John Appleseed"] keysToFetch:keys error:&error];
斯威夫特3:
let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey])
使用Swift和Contacts框架获取所有联系人,包括姓名和电话号码
import Contacts
let store = CNContactStore()
store.requestAccessForEntityType(.Contacts, completionHandler: {
granted, error in
guard granted else {
let alert = UIAlertController(title: "Can't access contact", message: "Please go to Settings -> MyApp to enable contact permission", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
return
}
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keysToFetch)
var cnContacts = [CNContact]()
do {
try store.enumerateContactsWithFetchRequest(request){
(contact, cursor) -> Void in
cnContacts.append(contact)
}
} catch let error {
NSLog("Fetch contact error: \(error)")
}
NSLog(">>>> Contact list:")
for contact in cnContacts {
let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName) ?? "No Name"
NSLog("\(fullName): \(contact.phoneNumbers.description)")
}
})
提取联系人操作速度很慢,因此您不应阻止主UI线程。不要CNContactFetchRequest
在后台线程。这就是为什么我将代码放入completionHandler中的原因。它在后台线程上运行。
苹果实际上建议使用CNContactStore的enumerateContactsWithFetchRequest来获取所有联系人,而不是UNITEDContactsMatchingPredicate。
以下是Obj-C的工作代码。
CNContactStore *store = [[CNContactStore alloc] init];
//keys with fetching properties
NSArray *keys = @[CNContactGivenNameKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
NSError *error;
[store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * __nonnull contact, BOOL * __nonnull stop) {
// access it this way -> contact.givenName; etc
}];
这是苹果推荐枚举功能的链接:https : //developer.apple.com/reference/contacts/cncontactstore/1403266-unifiedcontactsmatchingpredicate?language=objc#discussion
如果链接过期,这是苹果写的:
如果未找到匹配项,则此方法返回一个空数组(如果出现错误,则返回nil)。仅使用CNContact类谓词中的谓词。此方法不支持复合谓词。由于统一,返回的联系人可能具有与您指定的标识符不同的标识符。要获取所有联系人,请使用
enumerateContactsWithFetchRequest:error:usingBlock:
。
对于Swift 4
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: [CNContactGivenNameKey as CNKeyDescriptor, CNContactFamilyNameKey as CNKeyDescriptor, CNContactMiddleNameKey as CNKeyDescriptor, CNContactEmailAddressesKey as CNKeyDescriptor,CNContactPhoneNumbersKey as CNKeyDescriptor])
fetchRequest.sortOrder = CNContactSortOrder.userDefault
let store = CNContactStore()
do {
try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
print(contact.phoneNumbers.first?.value ?? "no")
results.append(contact)
})
}
catch let error as NSError {
print(error.localizedDescription)
}
较早版本 的sw var结果包含所有联系人
let contactStore = CNContactStore()
var results: [CNContact] = []
do {
try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest(keysToFetch: [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactMiddleNameKey, CNContactEmailAddressesKey,CNContactPhoneNumbersKey])) {
(contact, cursor) -> Void in
results.append(contact)
}
}
catch{
print("Handle the error please")
}
从iOS9中的通讯录框架获取全名,电子邮件ID,电话号码,个人资料图片和生日日期
#pragma mark
#pragma mark -- Getting Contacts From AddressBook
-(void)contactsDetailsFromAddressBook{
//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 = @[CNContactBirthdayKey,CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey, CNContactEmailAddressesKey];
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;
NSDateComponents *birthDayComponent;
NSMutableArray *contactNumbersArray;
NSString *birthDayStr;
NSMutableArray *emailArray;
NSString* email = @"";
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
birthDayComponent = contact.birthday;
if (birthDayComponent == nil) {
// NSLog(@"Component: %@",birthDayComponent);
birthDayStr = @"DOB not available";
}else{
birthDayComponent = contact.birthday;
NSInteger day = [birthDayComponent day];
NSInteger month = [birthDayComponent month];
NSInteger year = [birthDayComponent year];
// NSLog(@"Year: %ld, Month: %ld, Day: %ld",(long)year,(long)month,(long)day);
birthDayStr = [NSString stringWithFormat:@"%ld/%ld/%ld",(long)day,(long)month,(long)year];
}
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:@"placeholder.png"];
}
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
////Get all E-Mail addresses from contacts
for (CNLabeledValue *label in contact.emailAddresses) {
email = label.value;
if ([email length] > 0) {
[emailArray addObject:email];
}
}
//NSLog(@"EMAIL: %@",email);
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,@"fullName",profileImage,@"userImage",phone,@"PhoneNumbers",birthDayStr,@"BirthDay",email,@"userEmailId", nil];
// NSLog(@"Response: %@",personDict);
[self.contactsArray addObject:personDict];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableViewRef reloadData];
});
}
}
}];
}
在中swift 3 and Xcode 8
可以获取所有联系人列表
let keys = [CNContactGivenNameKey ,CNContactImageDataKey,CNContactPhoneNumbersKey]
var message: String!
//let request=CNContactFetchRequest(keysToFetch: keys)
let contactsStore = AppDelegate.AppDel.contactStore
// Get all the containers
var allContainers: [CNContainer] = []
do {
allContainers = try contactsStore.containers(matching: nil)
} catch {
print("Error fetching containers")
}
// 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 contactsStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keys as [CNKeyDescriptor])
self.results.append(contentsOf: containerResults)
self.tableView.reloadData()
message="\(self.results.count)"
} catch {
print("Error fetching results for container")
}
}
@rocolitis的答案很快!根据苹果公司的文档,他的答案是最正确的方法。
let contactStore = CNContactStore()
let keys = [CNContactPhoneNumbersKey, CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: keys)
try? contactStore.enumerateContacts(with: request) { (contact, error) in
// Do something with contact
}
您可能应该先检查对联系人的访问权限!
let authorization = CNContactStore.authorizationStatus(for: CNEntityType.contacts)
switch authorization {
case .authorized: break
case .denied: break
case .restricted: break
case .notDetermined: break
}
首先获取默认容器标识符,并使用谓词匹配的容器标识符
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let containerId = CNContactStore().defaultContainerIdentifier()
let predicate: NSPredicate = CNContact.predicateForContactsInContainerWithIdentifier(containerId)
let contacts = try CNContactStore().unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)
iOS 9中的CNContact
目标C
#import "ViewController.h"
#import <Contacts/Contacts.h>
@interface ViewController ()
{
NSMutableArray *arrayTableData;
}
@end
@implementation ViewController
-(void)viewDidLoad
{
[self fetchContactsandAuthorization];
}
//This method is for fetching contacts from iPhone.Also It asks authorization permission.
-(void)fetchContactsandAuthorization
{
// Request authorization to Contacts
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 = [[NSMutableArray alloc]init];
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];
[arrayTableData addObject:[NSString stringWithFormat:@"%@",[personDict objectForKey:@"fullName"]]];
NSLog(@"The contactsArray are - %@",arrayTableData);
}
dispatch_async(dispatch_get_main_queue(), ^{
[tableViewContactData reloadData];
});
}
}
}];
}
@end
输出是
The contactsArray are - (
"John Appleseed",
"Kate Bell",
"Anna Haro",
"Daniel Higgins",
"David Taylor",
"Hank Zakroff"
}
SWIFT 2
从iOS9中的联系人框架中获取全名,电子邮件ID,电话号码,个人资料图片
注意不带姓名的联系人也已处理。
第1步
import Contacts
第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)
}
更新1:
这是Swift 5
版本:
lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch: [CNKeyDescriptor] = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactPostalAddressesKey as CNKeyDescriptor,
CNContactEmailAddressesKey as CNKeyDescriptor,
CNContactPhoneNumbersKey as CNKeyDescriptor,
CNContactImageDataAvailableKey as CNKeyDescriptor,
CNContactThumbnailImageDataKey as CNKeyDescriptor]
// 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)
results.append(contentsOf: containerResults)
} catch {
print("Error fetching results for container")
}
}
return results
}()
原始答案:
这是flohei答案的Swift 3.0
版本
lazy var contacts: [CNContact] = {
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactPostalAddressesKey,
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
}()
希望这可以帮助!
我正在尝试此代码,它工作正常。我可以在swift3最新框架中使用联系人获取使用此代码的所有联系人详细信息:
let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as CNKeyDescriptor, CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName), CNContactPhoneNumbersKey as CNKeyDescriptor ,CNContactImageDataKey as CNKeyDescriptor,CNContactEmailAddressesKey as CNKeyDescriptor,CNContactBirthdayKey as CNKeyDescriptor])
do {
try self.store.enumerateContacts(with: requestForContacts) { contact, stop in
print("contact:\(contact)")
self.contacts.append(contact)
}
} catch {
print(error)
}
for contact in self.contacts {
print(contact)
let firstName = contact.givenName
nameArray.append(firstName)
print("first:\(firstName)")
let phoneNumber = (contact.phoneNumbers[0].value).value(forKey: "digits")
phoneNumberArray.append(phoneNumber as! String)
let emailAddress = contact.emailAddresses[0].value(forKey: "value")
emailAddressArray.append(emailAddress as! String)
}
科迪在Swift 3中的回应:
import Contacts
然后在使用的任何函数中:
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: {
granted, error in
guard granted else {
let alert = UIAlertController(title: "Can't access contact", message: "Please go to Settings -> MyApp to enable contact permission", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
return
}
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), CNContactPhoneNumbersKey] as [Any]
let request = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor])
var cnContacts = [CNContact]()
do {
try store.enumerateContacts(with: request){
(contact, cursor) -> Void in
cnContacts.append(contact)
}
} catch let error {
NSLog("Fetch contact error: \(error)")
}
print(">>>> Contact list:")
for contact in cnContacts {
let fullName = CNContactFormatter.string(from: contact, style: .fullName) ?? "No Name"
print("\(fullName): \(contact.phoneNumbers.description)")
}
})
现在不推荐使用iOS9中的ABAddressBookRef,因此要使用此框架从电话中获取所有联系人并添加此功能,您将获得联系人数组。
像这样在.h类中导入Contact框架
#import <Contacts/Contacts.h>
然后在.m文件中添加此方法
-(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];
});
}
}
}];
}
使用此方法调用contactsFromAddressBook函数
[self contactsFromAddressBook];
联系人权限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 {
}
}
只想分享这个版本的Swift 4
info.plist:
<key>NSContactsUsageDescription</key>
<string>$(PRODUCT_NAME) requires to access your contacts ...</string>
模块:
import Contacts
码:
func fetchContacts(completion: @escaping (_ result: [CNContact]) -> Void){
DispatchQueue.main.async {
var results = [CNContact]()
let keys = [CNContactGivenNameKey,CNContactFamilyNameKey,CNContactMiddleNameKey,CNContactEmailAddressesKey,CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
fetchRequest.sortOrder = .userDefault
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: {(grant,error) in
if grant{
do {
try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
results.append(contact)
})
}
catch let error {
print(error.localizedDescription)
}
completion(results)
}else{
print("Error \(error?.localizedDescription ?? "")")
}
})
}
}
用法:
fetchContacts(completion: {contacts in
contacts.forEach({print("Name: \($0.givenName), number: \($0.phoneNumbers.first?.value.stringValue ?? "nil")")})
您需要首先在info.plist中描述使用情况信息。我添加了一个检查,以确定用户已授予对联系人的访问权限,然后定义了键(需要提取的值)。如先前的回答之一所述,这是一个耗时的过程,因此我添加了DispatchQueue进行后台处理,并添加了完成处理程序以将contacts数组返回给调用方。
斯威夫特4.2。使用图片获取联系人号码
info.plist file data
<key>NSContactsUsageDescription</key>
<string>$(PRODUCT_NAME) requires to access your contacts ...</string>
//MARK:- Fetch All Contacts of Phone
func fetchContacts(completion: @escaping (_ result: [CNContact]) -> Void){
DispatchQueue.main.async {
var results = [CNContact]()
let keys = [CNContactGivenNameKey,CNContactFamilyNameKey,CNContactMiddleNameKey,CNContactEmailAddressesKey,CNContactPhoneNumbersKey,CNContactThumbnailImageDataKey] as [CNKeyDescriptor]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
fetchRequest.sortOrder = .userDefault
let store = CNContactStore()
store.requestAccess(for: .contacts, completionHandler: {(grant,error) in
if grant{
do {
try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
results.append(contact)
})
}
catch let error {
print(error.localizedDescription)
}
completion(results)
}else{
print("Error \(error?.localizedDescription ?? "")")
}
})
}
}
}
在Did Load方法中调用函数
var arrpic = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
fetchContacts(completion: {contacts in
contacts.forEach({print("Name: \($0.givenName), number: \($0.phoneNumbers.first?.value.stringValue ?? "nil")")
self.arrfname.append("\($0.givenName)")
self.arrlname.append("\($0.familyName)")
self.arrnumber.append("\($0.phoneNumbers.first?.value.stringValue ?? "nil")")
var img = UIImage()
if $0.thumbnailImageData != nil
{
img = UIImage.init(data: $0.thumbnailImageData!)!
self.arrpic.add(img)
}
else
{
self.arrpic.add("")
}
})
if contacts.count > 0
{
self.tablev.reloadData()
}
})
}
@flohei回答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
}()