2

Since I switched to Mac OS Sierra and XCode 8, code that was using unifiedContactsMatchingPredicate:keysToFetch:error: or unifiedContactWithIdentifier:keysToFetch:error: no longer run correctly.

An error is returned : Error domain: CNErrorDomain code: 200 With a description saying the record does not exist, or the update of the record failed.

All codes were working fine with Mac OS 10.11 and XCode 7, read access to address book are granted and the CNContact I am looking for does exist.

I had the same behavior with iOS 10, which I solved by adding a NSContactsUsageDescription key in the plist file (that was optional before iOS 10, but no longer). I did the same in my mac OS plist file with no luck.

Any clue what's going on and where to search ?

EDIT : with some code :

I wrote 2 new projects, one in Objective-C, one in Swift. Both of them give the same result.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application

CNContactStore  *contactStore   = [[CNContactStore alloc] init] ;
NSPredicate     *predicate      = [CNContact predicateForContactsMatchingName:@"TEST_CONTACT"] ;
NSError         *error          = nil ;

NSArray         *keys           = @[
                                    CNContactGivenNameKey,
                                    CNContactFamilyNameKey
                                    ] ;

NSArray         *contacts       = [contactStore unifiedContactsMatchingPredicate:predicate
                                                                     keysToFetch:keys
                                                                           error:&error] ;
NSLog(@"%d contacts found : %@",[contacts count],contacts) ;

}

and

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application

    let contactStore    = CNContactStore()
    let predicate       = CNContact.predicateForContacts(matchingName: "TEST_CONTACT")


    let keys            = [CNContactGivenNameKey,CNContactFamilyNameKey]

    do
    {
        let contacts        = try contactStore.unifiedContacts(matching: predicate,
                                                               keysToFetch: keys as [CNKeyDescriptor])
        print(contacts)
    }
    catch
    {
        print("caught an error")
    }

}

Result shown in the console :

2016-09-27 17:19:48.797029 TestCNContact.swift[13675:3502046] [core] __42-[ACAccountStore accountsWithAccountType:]_block_invoke_2 (208) "Error returned from daemon: <private>"

2016-09-27 17:19:48.798105 TestCNContact.swift[13675:3502046] [core] __42-[ACAccountStore accountsWithAccountType:]_block_invoke_2 (208) "Error returned from daemon: " [] 2016-09-27 17:19:49.631876 TestCNContact.swift[13675:3502047] [error] warning: dynamic accessors failed to find @property implementation for 'uniqueId' for entity ABCDInfo while resolving selector 'uniqueId' on class 'ABCDInfo'. Did you remember to declare it @dynamic or @synthesized in the @implementation ? 2016-09-27 17:19:52.637627 TestCNContact.swift[13675:3502047] [error] warning: dynamic accessors failed to find @property implementation for 'serialNumber' for entity ABCDAddressBookSource while resolving selector 'serialNumber' on class 'ABCDAddressBookSource'. Did you remember to declare it @dynamic or @synthesized in the @implementation ? 2016-09-27 17:19:52.739108 TestCNContact.swift[13675:3502068] [error] warning: dynamic accessors failed to find @property implementation for 'uniqueId' for entity ABCDAddressBookSource while resolving selector 'uniqueId' on class 'ABCDAddressBookSource'. Did you remember to declare it @dynamic or @synthesized in the @implementation ?

AirXygène
  • 2,409
  • 15
  • 34
  • I know it won't help, but I am seeing those same console error messages on macOS... without any Xcode dev work I am doing. They just are there. – deitch Oct 12 '16 at 18:26
  • @deitch Thanks, I was feeling kind of alone... I didn't find any solution or work around, and my app is badly broken. I filled a radar. – AirXygène Oct 12 '16 at 18:31
  • I tweeted about it. These few procs - soagent, callservicesd, nsurlsession - bringing a Mac to ah alt have been around for at least 3 major releases of OS X/macOS. Really pathetic – deitch Oct 12 '16 at 19:59
  • Not sure to understand that. However, something must have changed with Sierra because my code was working and is suddenly not. There must be a way to get back access to the address book, it can't have been broken for the last 3 releases. – AirXygène Oct 12 '16 at 20:04
  • Also, I just checked that my App, compiled with XCode 8 is broken and generating all those warnings with mac OS 10.12, but is working fine with mac OS 10.11. So the problem is really with macOS 10.12 – AirXygène Oct 12 '16 at 21:27
  • Yeah, there have been many reports of those processes going haywire for several releases, but those particular `ABCDAddressBook*` messages are new to Sierra. – deitch Oct 13 '16 at 06:37
  • Were you able to trace from the messages back to your app? Maybe I could trace from these messages to whatever app is causing them for me? – deitch Oct 13 '16 at 06:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/125636/discussion-between-airxygene-and-deitch). – AirXygène Oct 13 '16 at 19:09
  • I moved this discussion to the chat. – AirXygène Oct 13 '16 at 19:14

2 Answers2

2

I found a solution !!!

Apple has answered my radar with the following statement : "Contacts now requires that anyone using it be codesigned with the uses-contacts entitlement."

So what I did is that I sandboxed my app, and granted the "Contacts access" entitlement. Everything works fine again.

enter image description here

It seems Apple will no longer accept non sandboxed app to access the Contacts (or location or calendar).

AirXygène
  • 2,409
  • 15
  • 34
2

I ran into the same problem, but sandboxing is not an option because we want to distribute our app via Sparkle.

In re-visting this, I re-read the statement: "Contacts now requires that anyone using it be codesigned with the uses-contacts entitlement.", and wondered what would happen if I had an entitlements file that had contacts listed, but sandbox set to false, and it worked.

<dict>
        <key>com.apple.security.app-sandbox</key>
        <false/>
        <key>com.apple.security.personal-information.addressbook</key>
        <true/>
        <key>com.apple.security.personal-information.calendars</key>
        <true/>
</dict>

I verified using Activity Monitor that my app was not sandboxed, but was still able to access the address book.

rjs
  • 41
  • 1
  • 1
  • I figured it was odd anyways that they required sandbox in the UI to enable addressbook in order to read contacts. This is a much better solution if you need freedom on OSX – Allison Mar 04 '17 at 06:09