Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the history-related Contacts framework class in iOS 13?

New in iOS 13 are a bunch of history-related classes such as CNChangeHistoryEvent and CNChangeHistoryFetchRequest. There's no documentation and they are not mentioned in any WWDC 2019 video that I can find. What are they for and how do I use them?

like image 477
matt Avatar asked Oct 12 '19 19:10

matt


1 Answers

The API is supposed to run in a way where you can pass in a 'token' to the change history request, and it'll give you the contacts (or groups) that were added/deleted/updated since that token.

So far, I've only been able to 'run' the history fetch request, like this:

    CNChangeHistoryFetchRequest *fetchHistory = [[CNChangeHistoryFetchRequest alloc] init];
    fetchHistory.startingToken = [[NSUserDefaults standardUserDefaults] dataForKey:@"CNContactChangeHistoryToken"];

    NSError *error = nil;

    CNContactStore *store = [[CNContactStore alloc] init];
    CNFetchResult *fetchResult = [store enumeratorForChangeHistoryFetchRequest:fetchHistory error:&error];

    NSEnumerator *enumerator = [fetchResult value];
    id object;

    while ((object = [enumerator nextObject])) {
        // do something with object
        NSLog(@"change history enumerator object = %@", object);
        CNChangeHistoryEvent *historyEvent = (CNChangeHistoryEvent *) object;
        if ([historyEvent isKindOfClass:[CNChangeHistoryDropEverythingEvent class]]) {
            NSLog(@"change history - DROP EVERYTHING!");
            [historyEvent acceptEventVisitor: self];
        } else {
            if ([historyEvent isKindOfClass:[CNChangeHistoryAddContactEvent class]]) {
                CNChangeHistoryAddContactEvent *addContactEvent = (CNChangeHistoryAddContactEvent *) object;
                NSLog(@"change history - AddContact event container %@ - %@", addContactEvent.containerIdentifier, addContactEvent.contact);
            } else if ([historyEvent isKindOfClass:[CNChangeHistoryUpdateContactEvent class]]) {
                CNChangeHistoryUpdateContactEvent *updateContactEvent = (CNChangeHistoryUpdateContactEvent *) object;
                NSLog(@"change history - UpdateContact event - %@", updateContactEvent.contact);
            } else if ([historyEvent isKindOfClass:[CNChangeHistoryDeleteContactEvent class]]) {
                CNChangeHistoryDeleteContactEvent *deleteContactEvent = (CNChangeHistoryDeleteContactEvent *) object;
                NSLog(@"change history - DeleteContact event - %@", deleteContactEvent.contactIdentifier);
            }
        }
    }

The enumerate runs and it's always the 'CNChangeHistoryDropEverythingEvent' event, followed by 'Add Contact' and 'Add Group' events for the entire contacts list. This is because I can't find a way to fetch the current token anywhere. The 'fetchResult' object should have a currentHistoryToken but it is always nil; so is the CNContactStore's currentHistoryToken object. So I'm not sure where to get that from, so I can pass it into the startingToken next time.

like image 51
Z S Avatar answered Oct 12 '22 23:10

Z S