How to check contact source in CNContact swift?

In the "Contacts" application there is a group of "iCloud", "yahoo", "gmail". Quickly, is it possible to get a contact only from a gmail source?

+7
ios swift swift3 google-contacts cncontact
source share
4 answers

iCloud / yahoo / gmail etc. CNContainer. Gmail / iCloud is of type CNContainerTypeCardDAV. So first you need to get all the contacts, and then filter the array based on the CNContainerType of that contact. But, unfortunately, we can’t determine which CardDav it is, ie iCloud / Gmail.

See here for more details. How do I know which CNContainer iCloud represents?

0
source share

You can achieve this by looking at the Contact framework runtime headers: https://github.com/JaviSoto/iOS10-Runtime-Headers/tree/master/Frameworks/Contacts.framework

You can call them the message performSelector . It is a bit dirty, but it works.

Typically, you need to do the following:

 CNContactStore* store = [CNContactStore new]; // fetch accounts that sync contacts with your device (array of CNAccount) // since CNAccount class isn't available by default, we treat it as NSObject for our puproses NSArray* accounts = [store performSelector:@selector(accountsMatchingPredicate:error:) withObject:nil withObject:nil]; // you can iterate through this array, I just use first one for this example NSObject* account = [accounts firstObject]; // get identifier of the account for NSPredicate we use next NSString* accountId = [account performSelector:@selector(identifier)]; // Display name of the account (aka Yahoo, Gmail etc.) NSString* accountName = [account performSelector:@selector(_cnui_displayName)]; // NSPredicate that help us to get corresponding CNContainer NSPredicate* containerPredicate = [[CNContainer class] performSelector:@selector(predicateForContainersInAccountWithIdentifier:) withObject:accountId]; // Fetching CNContainer CNContainer* container = [[store containersMatchingPredicate:containerPredicate error:nil] firstObject]; 

After that, all about the general use of CNContainers. Hope this helps.

PS. It works on iOS 10, for future versions you should check the Contacts.framework runtime changes.

SFC. I did not check quickly, but should work and.

Sorry for my English. Good luck :)

0
source share

Tested code. Hope this solves your problem ...

  func getAppropriateName(for container: CNContainer?) -> String? { var name = "" if (container?.name == "Card") || container?.name == nil { name = "iCloud" } else if (container?.name == "Address Book") { name = "Google" } else if (container?.name == "Contacts") { name = "Yahoo" } else { name = "Facebook" } return name } 
0
source share

If the container name is nil, the actual name in iOS 12.1 may be "IPHONE" and not "iCloud." But there are also no guarantees.

0
source share

All Articles