AddressBookフレームワークの大部分はiOS 9で非推奨になりました。新しい連絡先フレームワークでは、 documentation はNSPredicate
に一致するレコードを取得する方法のみを示しますが、必要な場合はallレコード?
他の両方の回答は、defaultContainerIdentifier
を使用してコンテナから連絡先をロードするだけです。ユーザーが複数のコンテナ(つまり、連絡先を保存するために使用されるExchangeとiCloudアカウント)を持っているシナリオでは、これはデフォルトとして設定されたアカウントからのみ連絡先をロードします。したがって、質問の作成者が要求したall連絡先は読み込まれません。
おそらく代わりにしたいのは、すべてのコンテナを取得し、それらを反復処理して、各コンテナからすべての連絡先を抽出することです。次のコードスニペットは、Swiftのアプリの1つでそれを行う方法の例です。
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
}()
Objective-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.
}
}];
}
}];
名前で連絡先をフィルタリングしたい場合、これを使用できます:
Obj-C:
// 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])
公式ドキュメントはこちら: https://developer.Apple.com/reference/contacts
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)")
}
})
連絡先の取得はslow操作であるため、メインUIスレッドをブロックしないでください。バックグラウンドスレッドでCNContactFetchRequest
を実行します。そのため、コードをcompletionHandlerに配置します。バックグラウンドスレッドで実行されます。
Appleは、実際には、CNContactStoreのenumerateContactsWithFetchRequestを使用して、すべての連絡先とNOTUnifiedContactsMatchingPredicateを取得することをお勧めします。
以下は、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
}];
Appleが列挙関数を推奨するリンクを次に示します。 https://developer.Apple.com/reference/contacts/cncontactstore/1403266-unifiedcontactsmatchingpredicate?language=objc#discussion
リンクの有効期限が切れた場合、Appleは次のように書きました。
一致するものが見つからない場合、このメソッドは空の配列(またはエラーの場合はnil)を返します。 CNContactクラスの述語からの述語のみを使用してください。複合述語は、このメソッドではサポートされていません。統一のため、返された連絡先は、指定したものとは異なる識別子を持つ場合があります。 すべての連絡先を取得するには、
enumerateContactsWithFetchRequest:error:usingBlock:
を使用します。
For 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)
}
旧バージョン for Swift 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")
}
}
Swiftでの@rocolitisの回答!彼の答えは、Appleのドキュメントによると、これを行う最も正しい方法です。
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"
}
スイフト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)
}
Swift 3のCodyの応答:
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)")
}
})
私はこのコードを試していますが、うまくいきます。連絡先を使用して、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)
}
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
}()
お役に立てれば!
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で使用情報を記述する必要があります。ユーザーが連絡先へのアクセスを許可し、キー(取得する必要がある値)を定義したかどうかを確認するチェックを追加しました。前の回答の1つで述べたように、それは時間がかかるプロセスなので、バックグラウンド処理のためにDispatchQueueを追加し、連絡先配列を呼び出し元に返すために完了ハンドラーを追加しました。
現在、iOS9 ABAddressBookRefは廃止されているため、電話からすべての連絡先を取得するには、このフレームワークを使用してこの関数を追加し、連絡先の配列を取得します。
このような.hクラスの連絡先フレームワークをインポートする
#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];
スウィフト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 ?? "")")
}
})
}
}
}
ロードされたメソッドでの関数呼び出し
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()
}
})
}
@ floheiSwift-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
}()