Reputation: 1764
I'm trying to save a contact to the contacts app by using this code directly without requesting any permission:
import Foundation
import UIKit
import Contacts
@available(iOS 9.0, *)
class OnCallEmpContact: UITableViewController {
var store: CNContactStore!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var phoneLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@IBOutlet weak var workPhoneLabel: UILabel!
var emp = employee()
var rank = ""
override func viewDidLoad() {
super.viewDidLoad()
self.nameLabel.text=self.emp.getFistName()+" "+emp.getLastName()
self.phoneLabel.text="0"+self.emp.getMobile()
self.emailLabel.text=self.emp.getEmail()
self.workPhoneLabel.text=self.emp.getPhone()
store = CNContactStore()
checkContactsAccess()
}
private func checkContactsAccess() {
switch CNContactStore.authorizationStatusForEntityType(.Contacts) {
// Update our UI if the user has granted access to their Contacts
case .Authorized:
self.accessGrantedForContacts()
// Prompt the user for access to Contacts if there is no definitive answer
case .NotDetermined :
self.requestContactsAccess()
// Display a message if the user has denied or restricted access to Contacts
case .Denied,
.Restricted:
let alert = UIAlertController(title: "Privacy Warning!",
message: "Permission was not granted for Contacts.",
preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
private func requestContactsAccess() {
store.requestAccessForEntityType(.Contacts) {granted, error in
if granted {
dispatch_async(dispatch_get_main_queue()) {
self.accessGrantedForContacts()
return
}
}
}
}
// This method is called when the user has granted access to their address book data.
private func accessGrantedForContacts() {
//Update UI for grated state.
//...
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0{
if rank == "0"{
return "Primary Employee"
}
else if rank == "1"{
return "Backup Employee"
}
}
return""
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true) // to stop highliting the selected cell
if indexPath.section==1 && indexPath.row==0{
self.saveContact()
}
}
func saveContact(){
do{
let contact = CNMutableContact()
contact.givenName = self.emp.getFistName()
contact.familyName = self.emp.getLastName()
contact.phoneNumbers = [CNLabeledValue(
label:CNLabelPhoneNumberiPhone,
value:CNPhoneNumber(stringValue:emp.getMobile())),
CNLabeledValue(
label:CNLabelPhoneNumberiPhone,
value:CNPhoneNumber(stringValue:emp.getPhone()))]
let workEmail = CNLabeledValue(label:CNLabelWork, value:emp.getEmail())
contact.emailAddresses = [workEmail]
let saveRequest = CNSaveRequest()
saveRequest.addContact(contact, toContainerWithIdentifier:nil)
try store.executeSaveRequest(saveRequest)
print("saved")
}
catch{
print("error")
}
}
}
I'm getting error at the last line try store.executeSaveRequest(saveRequest)
of method saveContact
Error :
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=CNErrorDomain Code=100 "Access Denied" UserInfo={NSLocalizedDescription=Access Denied, NSLocalizedFailureReason=This application has not been granted permission to access Contacts.
I found the above code at apple website but also I red this on Privacy section in the middle :
Any call to CNContactStore will block the application while the user is being asked to grant or deny access
But nothing show up asking for access to the contacts app .. should I write more code to do this ? How ?
Upvotes: 3
Views: 7128
Reputation: 86
This is the newest syntax from swift. Hope it helps !
let store = CNContactStore()
if CNContactStore.authorizationStatus(for: .contacts) == .notDetermined {
store.requestAccess(for: .contacts) {granted, error in
if granted {
print("PERMISSION GRANTED")
} else {
print("PERMISSION NOT GRANTED")
}
}
} else if CNContactStore.authorizationStatus(for: .contacts) == .authorized {
// If the user user has earlier provided the access, then add the contact
print("AUTHORIZED")
findContactsOnBackgroundThread { (contact) in
print("contacts : ",contact as Any)
}
} else {
// If the user user has NOT earlier provided the access, create an alert to tell the user to go to Settings app and allow access
print("NOT AUTHORIZED")
}
Upvotes: 0
Reputation: 47896
Maybe you have read Contacts Framework Reference. You should think such overall description can be easily inaccurate in details. Check the latest reference.
CNContactStore
has two methods related to authorization:
Privacy Access
You should write something like this in your app:
var store: CNContactStore!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
store = CNContactStore()
checkContactsAccess()
}
private func checkContactsAccess() {
switch CNContactStore.authorizationStatusForEntityType(.Contacts) {
// Update our UI if the user has granted access to their Contacts
case .Authorized:
self.accessGrantedForContacts()
// Prompt the user for access to Contacts if there is no definitive answer
case .NotDetermined :
self.requestContactsAccess()
// Display a message if the user has denied or restricted access to Contacts
case .Denied,
.Restricted:
let alert = UIAlertController(title: "Privacy Warning!",
message: "Permission was not granted for Contacts.",
preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
private func requestContactsAccess() {
store.requestAccessForEntityType(.Contacts) {granted, error in
if granted {
dispatch_async(dispatch_get_main_queue()) {
self.accessGrantedForContacts()
return
}
}
}
}
// This method is called when the user has granted access to their address book data.
private func accessGrantedForContacts() {
//Update UI for grated state.
//...
}
Upvotes: -1
Reputation: 2684
It's wrong! Use do
-catch
statement and you'll be OK.
do {
try store.executeSaveRequest(saveRequest)
} catch {}
Hope it helps.
Upvotes: 1