I have a custom User
class which stores the phone number of the user.
我有一个自定义用户类,用于存储用户的电话号码。
class User {
let phoneNumber: String
}
How do I get the corresponding contact from the users contact book?
如何从用户联系簿获取相应的联系人?
I tried the following but it seems like this works just for the contacts name because I'm always getting nil
:
我尝试了以下但似乎这只适用于联系人名称,因为我总是得到零:
let predicate = CNContact.predicateForContactsMatchingName(userInstance.phoneNumber)
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactPhoneNumbersKey]
// Is already permitted
try! CNContactStore().unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch).first // This returns nil
I've searched in the docs but I didn't find a proper solution.
我在文档中搜索过但我找不到合适的解决方案。
3 个解决方案
#1
4
let contactStroe = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
contactStroe.requestAccessForEntityType(.Contacts, completionHandler: { (granted, error) -> Void in
if granted {
let predicate = CNContact.predicateForContactsInContainerWithIdentifier(contactStroe.defaultContainerIdentifier())
var contacts: [CNContact]! = []
do {
contacts = try contactStroe.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)// [CNContact]
}catch {
}
for contact in contacts {
var phoneStr = ""
var nameStr = ""
var number: CNPhoneNumber!
if contact.phoneNumbers.count > 0 {
number = contact.phoneNumbers[0].value as! CNPhoneNumber
phoneStr = number.stringValue.stringByReplacingOccurrencesOfString("-", withString: "")
}
nameStr = contact.familyName + contact.givenName
if !nameStr.isEmpty && !phoneStr.isEmpty {
let friend = YFriendsModel()
friend.name = nameStr
friend.phone = phoneStr
self.friendArr.append(friend)
}
}
})
this is my way, you can have a test
这是我的方式,你可以进行测试
#2
2
You can't.
This is a stupid solution as a huge workaround.
作为一个巨大的解决方案,这是一个愚蠢的解决方案。
- Read each contact
- Normalize the phone number (not the easiest thing to do!)
- Cache contacts into a
[String : Contact]
阅读每个联系人
规范化电话号码(不是最简单的事情!)
将联系人缓存到[String:Contact]
Then you can lookup contacts with contacts[phone_number]?
然后你可以查找联系人[phone_number]的联系人?
#3
0
Swift 3 A nice solution, taking care also of efficiency:
Swift 3一个很好的解决方案,也注重效率:
func getAllContacts() {
let status = CNContactStore.authorizationStatus(for: CNEntityType.contacts) as CNAuthorizationStatus
if status == CNAuthorizationStatus.denied {
self.showAccessContactsDeniedAlert()
return
}
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey] as [Any]
let request = CNContactFetchRequest(keysToFetch:keysToFetch as! [CNKeyDescriptor])
do {
try contactStore.enumerateContacts(with: request, usingBlock: { (contact:CNContact, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
print(contact)
for email in contact.emailAddresses {
var dict = [String:String]()
dict["name"] = contact.familyName + contact.givenName
dict["email"] = email.value
self.allContacts.add(dict)
}
})
} catch {
//catch
}
}
In this case I save name and email into a dict and I add it to a class variable called allContacts.
在这种情况下,我将名称和电子邮件保存到dict中,然后将其添加到名为allContacts的类变量中。
Note that a contact can have more than one email, so I create a dict for any email address in this case
请注意,联系人可以有多个电子邮件,因此我在这种情况下为任何电子邮件地址创建一个dict
#1
4
let contactStroe = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey]
contactStroe.requestAccessForEntityType(.Contacts, completionHandler: { (granted, error) -> Void in
if granted {
let predicate = CNContact.predicateForContactsInContainerWithIdentifier(contactStroe.defaultContainerIdentifier())
var contacts: [CNContact]! = []
do {
contacts = try contactStroe.unifiedContactsMatchingPredicate(predicate, keysToFetch: keysToFetch)// [CNContact]
}catch {
}
for contact in contacts {
var phoneStr = ""
var nameStr = ""
var number: CNPhoneNumber!
if contact.phoneNumbers.count > 0 {
number = contact.phoneNumbers[0].value as! CNPhoneNumber
phoneStr = number.stringValue.stringByReplacingOccurrencesOfString("-", withString: "")
}
nameStr = contact.familyName + contact.givenName
if !nameStr.isEmpty && !phoneStr.isEmpty {
let friend = YFriendsModel()
friend.name = nameStr
friend.phone = phoneStr
self.friendArr.append(friend)
}
}
})
this is my way, you can have a test
这是我的方式,你可以进行测试
#2
2
You can't.
This is a stupid solution as a huge workaround.
作为一个巨大的解决方案,这是一个愚蠢的解决方案。
- Read each contact
- Normalize the phone number (not the easiest thing to do!)
- Cache contacts into a
[String : Contact]
阅读每个联系人
规范化电话号码(不是最简单的事情!)
将联系人缓存到[String:Contact]
Then you can lookup contacts with contacts[phone_number]?
然后你可以查找联系人[phone_number]的联系人?
#3
0
Swift 3 A nice solution, taking care also of efficiency:
Swift 3一个很好的解决方案,也注重效率:
func getAllContacts() {
let status = CNContactStore.authorizationStatus(for: CNEntityType.contacts) as CNAuthorizationStatus
if status == CNAuthorizationStatus.denied {
self.showAccessContactsDeniedAlert()
return
}
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactEmailAddressesKey,
CNContactPhoneNumbersKey,
CNContactImageDataAvailableKey,
CNContactThumbnailImageDataKey] as [Any]
let request = CNContactFetchRequest(keysToFetch:keysToFetch as! [CNKeyDescriptor])
do {
try contactStore.enumerateContacts(with: request, usingBlock: { (contact:CNContact, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
print(contact)
for email in contact.emailAddresses {
var dict = [String:String]()
dict["name"] = contact.familyName + contact.givenName
dict["email"] = email.value
self.allContacts.add(dict)
}
})
} catch {
//catch
}
}
In this case I save name and email into a dict and I add it to a class variable called allContacts.
在这种情况下,我将名称和电子邮件保存到dict中,然后将其添加到名为allContacts的类变量中。
Note that a contact can have more than one email, so I create a dict for any email address in this case
请注意,联系人可以有多个电子邮件,因此我在这种情况下为任何电子邮件地址创建一个dict