0

I am trying to add a simple add to contacts feature.

Just adding the variable

    let addressBookRef: ABAddressBook = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()

in an existing DetailViewController class and my project crashes:

fatal error: unexpectedly found nil while unwrapping an Optional value

Just outcommenting the addressBookRef and my project doesn't crash

Is it because i have the variable in a detailviewcontroller from my main view?

I am following this tutorial, http://www.raywenderlich.com/97936/address-book-tutorial-swift-ios

[EDIT] I also have

 @IBAction func addToContacts(sender: AnyObject) {
    let authorizationStatus = ABAddressBookGetAuthorizationStatus()

    switch authorizationStatus {
    case .Denied, .Restricted:
        //1
        print("Denied")
    case .Authorized:
        //2
        print("Authorized")
    case .NotDetermined:
        //3
        print("Not Determined")
        //promptForAddressBookRequestAccess(addContacts)
    }

    print("Add to contacts")
}

and when i outcomment the variable and just check what the case is i see "Denied" but i expect "Not Determined", why the denied??

[EDIT] WOW, that's a pain in the..... i have spent 1 hour to get the prompt and the one thing that work was: Delete App -> Restart iPhone -> set date/time 2 days ahead -> Restart iPhone -> compile App again

Other suggestions i didn't try: 1/ unique build number 2/ Settings --> General--> Reset--> Reset Location&Privacy

iOS resetting granting access to reminders

Community
  • 1
  • 1
alex
  • 4,804
  • 14
  • 51
  • 86

1 Answers1

1

It is because ABAddressBookCreateWithOptions is returning nil so calling takeRetainedValue() on it causes the error.

ABAddressBookCreateWithOptions will return nil is the user has not allowed you app to access contacts. You will need to use ABAddressBookGetAuthorizationStatus to determine if the app has permission before creating an address book.


Edit

It sounds like when the permissions alert was shown, disallow was pressed.

You need to open the Settings app, scroll down and tap on the name of your app, the change the switch next to "Contacts" to be on.

Craig Siemens
  • 12,942
  • 1
  • 34
  • 51
  • hmm, i do have this function, which is triggered by a button ` @IBAction func addToContacts(sender: AnyObject) { let authorizationStatus = ABAddressBookGetAuthorizationStatus() switch authorizationStatus { case .Denied, .Restricted: //1 print("Denied") case .Authorized: //2 print("Authorized") case .NotDetermined: //3 print("Not Determined") //promptForAddressBookRequestAccess(addContacts) } print("Add to contacts") }` – alex Jan 03 '16 at 05:15
  • hmmm ok my project doesn't crash but i don't see the prompt as i expected. (That why i set the switch to off). How can i mimic the situation so the prompt will appear?? Thanks so far – alex Jan 03 '16 at 05:30
  • iOS only shows the prompt to the user once. You might be able to delete app and reinstall it to get the prompt to appear again. – Craig Siemens Jan 03 '16 at 05:33
  • running my app on the simulator i see the prompt, but on my actual device (iphone 5s) it doesn't appear and crashes. 1/ I have deleted the app from my iphone 5s as you suggested and recompiled. 2/ frustrating thing is when i compile the tutorial app on my iphone that project works as expected – alex Jan 03 '16 at 05:40
  • [edit] too fast, the tutorial app also crashes as soon as i click denied and remove it from my iphone and rerun the tutorial app, somehow i can't seem to delete the original app setting?? – alex Jan 03 '16 at 05:47
  • FYI: i had to set the time in the future http://stackoverflow.com/questions/22687804/ios-resetting-granting-access-to-reminders/33940858#33940858 – alex Jan 03 '16 at 06:11