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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With