iosswiftcontactsios9.3

Contacts and Microphone request access does not work on iOS 9


I've been stuck on a bug since last Monday, so I'm asking for help now .. Contacts and Micriohpone request access does not work on iOS 9. I use this piece of code in order to request access to contacts :

let contactsStore = CNContactStore()

func requestAccess(completionHandler: @escaping (Permission) -> ()) {
    self.contactsStore.requestAccess(for: .contacts, completionHandler: { (granted, error) in
        if granted {
            completionHandler(.granted)
        } else {
            completionHandler(.denied)
        }
    })
}

This function is called, no problem with that, the problem is it always return .denied and an error set with "Access denied", even though no alert has been shown to the user. The same with microphone.

The key 'Privacy - Contacts Usage Description' is present in my Info.plist

EDIT : I also know that when the user denied once the usage it is not shown anymore, but the other problem is that there is not "switch" in the settings section of the app. I tried to restore the device (Working on simulator as I don't have a real iOS 9 device), but still the same behaviour.

This code works perfeclty on iOS 10 and iOS 11. But no chance on iOS 9

If you could help me on this issue that would be awesome.

Thanks !


Solution

  • I tried this on 9.3 in the simplest way imaginable, and I did get a prompt:

    import UIKit
    import Contacts
    
    class ViewController: UIViewController {
    
        let contactsStore = CNContactStore()
    
        override func viewDidAppear(_ animated: Bool) {
            DispatchQueue.main.async {
    
                self.requestAccess(completionHandler: { (permission) in
                    print("The user said \(permission)")
                })
    
            }
        }
    
        func requestAccess(completionHandler: @escaping (Permission) -> ()) {
            self.contactsStore.requestAccess(for: .contacts, completionHandler: { (granted, error) in
                if granted {
                    completionHandler(.granted)
                } else {
                    completionHandler(.denied)
                }
            })
        }
    }
    
    enum Permission {
        case granted
        case denied
    }
    

    Settings -> Privacy -> Contacts

    This works fine. I think the issue is that you already denied it.

    The only solutions are:

    1. Change the bundle id, which will make your app act as a different one
    2. Reset your device/simulator (easier if a simulator of course)
    3. Change the privacy setting from Off to On

    For end users, I've seen the UI prompt the user to change the setting if they see "denied".

    You can do that like this:

    self.requestAccess(completionHandler: { (permission) in
                    print("The user said \(permission)")
    
                    if ( permission == .denied ) {
                        let urlStr = UIApplicationOpenSettingsURLString
    
                        if let url = URL(string:urlStr) {
                            UIApplication.shared.openURL(url)
                        }
                    }
    
                })