Contacts Framework CNFetchResult

Anyone ever use CNFetchResult successfully? I find nothing on the internet, on stackoverflow, and in Apple Developer Forums.

The only thing I have found is Apple Documentation for it. It says CNFetchResult is a Generic Class. What exactly does that mean. I found an explanation that gives its definition, but the rest of the explanation is very long winded.

  • What do you want to achieve?

  • I want to convert this code in the answer to this stackoverflow post. I got as far as the line that creates an instance of CNFetchResult -- the fifth line not counting the spaces. I didn't know how to translate that to Swift.

  • @ShinehahGnolaum, you should better show the original code and your code which represents what you have done till now. With some concrete code shown, more readers would try to solve it.

Replies

I finally came back to this question.

Again, I'm trying to duplicate the Objective-C code on this post on stackoverflow to Swift.

Here's the Objective-C code from the post:


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

        }

    }

}


Here's my Swift code, as far as I got:


public func tryChangeHistoryFetchRequest() {

    

    let fetchHistory = CNChangeHistoryFetchRequest()

    

    let store = CNContactStore()

    

    print("*****")

    

    let fetchResult: CNFetchResult<NSEnumerator<CNChangeHistoryEvent>> = fetchHistory

        

}



// Enumerate through each visit function and check if I get anything back from fetch request.

class ChangeHistoryEventVisitor: NSEnumerator, CNChangeHistoryEventVisitor {



    override func nextObject() -> Any? {

        

        let changeHistoryDropEverythingEvent = CNChangeHistoryDropEverythingEvent()

        

        return {}

        

    }

    

    func visit(_ event: CNChangeHistoryDropEverythingEvent) {

        

        print("CNChangeHistoryDropEverythingEvent")

        

    }



    func visit(_ event: CNChangeHistoryAddContactEvent) {

        

    }



    func visit(_ event: CNChangeHistoryUpdateContactEvent) {

        

    }



    func visit(_ event: CNChangeHistoryDeleteContactEvent) {

        

    }





}



public func tryChangeHistoryEventVisitor() {

    

    print("*****")

    

    let changeHistoryEventVisitor = ChangeHistoryEventVisitor()



    print("*****")

    

    let changeHistoryDropEverythingEvent = CNChangeHistoryDropEverythingEvent()

    

    changeHistoryEventVisitor.visit(changeHistoryDropEverythingEvent)



}



class ChangeHistoryAddContactEvent: CNChangeHistoryAddContactEvent {

    

}



class CNChangeHistoryFetchResult: CNFetchResult<NSEnumerator<CNChangeHistoryEvent>> {

    

}

If anyone is interested,

I found this webpage: https://mackuba.eu/2019/12/03/new-stuff-from-wwdc-2019/#comment1

I asked this question:

Could you be specific about where during WWDC 2019 they said something about CNChangeHistoryFetchRequest and CNChangeHistoryEvent for the Contacts Framework?

I got this answer:

@ShinehahGnolaum Hey! These lists are combined from the things mentioned in the talks, but also from looking through the documentation e.g. at https://developer.apple.com/ios/, release notes, and just simply API reference (I use this page http://codeworkshop.net/objc-diff/sdkdiffs/ to see what new classes/methods were added in some interesting places). So some things listed (a large part of them actually) might not have been mentioned anywhere in the talks and I've just found them elsewhere. It's not necessarily "things mentioned at WWDC", but "things released in the betas at WWDC". 

It looks like these two you've mentioned are things like that, because I don't see them anywhere in any talk notes or transcriptions. Which is unfortunate, because I see they still don't have a proper documentation… which is probably why you're asking. I think the only piece of information that can help you somewhat is the ObjC header CNChangeHistoryFetchRequest.h in the SDK - you can access it through the "Open Quickly" (Cmd+Shift+O) in Xcode. There are some code comments there that aren't rendered in the web documentation. Not much in CNChangeHistoryEvent.h though.