简体   繁体   中英

How to check contact source in CNContact swift?

In Contact apps there's group like "iCloud", "yahoo", "gmail". In swift, is it possible to fetch contact from gmail source only?

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
    }

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, ie iCloud/Gmail.

Please see more details here: How do we know which CNContainer represents iCloud?

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM