问题
In Contact apps there's group like "iCloud", "yahoo", "gmail". In swift, is it possible to fetch contact from gmail source only?
回答1:
Tested code. Hope it will solve 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
}
回答2:
iCloud/yahoo/gmail etc are CNContainer. Gmail/iCloud is of type CNContainerTypeCardDAV. So first you need to fetch all contacts, and then filter the array based on the CNContainerType of that contact. But unfortunately, we cannot identify which CardDav is it, i.e iCloud/Gmail.
Please see more details here: How do we know which CNContainer represents iCloud?
回答3:
You can achieve this by looking at Contacts framework runtime headers here: https://github.com/JaviSoto/iOS10-Runtime-Headers/tree/master/Frameworks/Contacts.framework
You can call them by performSelector
message. It's a bit messy, but works.
Generally what you have to do is 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 it's all about general usage of CNContainers. Hope it will help.
PS. It works on iOS 10, for future versions you should check for Contacts.framework runtime changes.
PPS. I didn't check on swift, but should work either.
Sorry for my english. Good luck :)
来源:https://stackoverflow.com/questions/38825805/how-to-check-contact-source-in-cncontact-swift