jonaszmclaren
jonaszmclaren

Reputation: 2489

CNContact for Mac OS X 10.11

from OS X 10.11 and iOS 9.0 Apple provided this framework Contacts:

https://developer.apple.com/library/prerelease/mac/documentation/Contacts/Reference/Contacts_Framework/index.html#//apple_ref/doc/uid/TP40015328

and I would like to access contacts from Mac, but I cannot do anything, because the app does not have access to contacts:

switch CNContactStore.authorizationStatusForEntityType(.Contacts) {
    case .Authorized:
        print("Authorized")
        NSUserDefaults.standardUserDefaults().setBool(true, forKey: "contactsAllowed")
    case .Denied:
        print("Denied")
        NSUserDefaults.standardUserDefaults().setBool(false, forKey: "contactsAllowed")
    case .NotDetermined:
        print("Not Determined")
    case .Restricted:
        print("Restricted")
    }

The app never prompts to allow access to contacts, neither can I select it in System Preferences (it does not show up).

Has anyone any idea how to acccess them on Mac (on iOS it works well)?

Upvotes: 3

Views: 796

Answers (2)

iphaaw
iphaaw

Reputation: 7204

Are you trying this from the playground? This won't work.

Try this method in your project:

func getContactImage(name:String) -> NSImage?
{
    let store = CNContactStore()
    do
    {
        let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName(name), keysToFetch:[CNContactImageDataKey])
        if contacts.count > 0
        {
            if let image = contact[0].imageData
            {
                return NSImage.init(data: image)
            }
        }
    }
    catch
    {
    }

    return nil
}

Anyway your question led me on the path to find a way to get the contacts image, so thanks for that.

Upvotes: 1

Marek H
Marek H

Reputation: 5576

Any call to instance of CNContactStore should trigger request. If not try

  1. Reboot (actually this helped me; I was granted access)
  2. Turn on sandboxing
  3. Resetprivacy settings "sudo tccutil reset AddressBook"
  4. Call it on main thread

Instance of CNContactStore call:

[[CNContactStore alloc] init];

Privacy

Users can grant or deny access to contact data on a per-application basis. Any call to CNContactStore will block the application while the user is being asked to grant or deny access. Note that the user is prompted only the first time access is requested; any subsequent CNContactStore calls use the existing permissions. To avoid having your app’s UI main thread block for this access, you can use either the asynchronous method [CNContactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:] or dispatch your CNContactStore usage to a background thread.

Upvotes: 2

Related Questions