Skip to content

Instantly share code, notes, and snippets.

@rbresjer
Created March 1, 2018 11:01
Show Gist options
  • Save rbresjer/4e971c0650e63a53bd81056e962c121b to your computer and use it in GitHub Desktop.
Save rbresjer/4e971c0650e63a53bd81056e962c121b to your computer and use it in GitHub Desktop.
Example of EventKit/Calendar permission crash
/*
How to reproduce crash:
1. Toggle switch on, Calendar authorization is requested, grant authorization
2. Switch to the Settings app, disable Calendar authorization
3. The app crashes
Or:
1. Toggle switch on, Calendar authorization is requested, reject authorization
2. Toggle the switch on again, an alert is shown that you should authorize in the Settings app
3. Go to the Settings app, enable Calendar authorization
4. The app crashes
*/
class ViewController: UIViewController {
@IBOutlet weak var calendarSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
let status = EKEventStore.authorizationStatus(for: .event)
calendarSwitch.isOn = status == .authorized
calendarSwitch.addTarget(self, action: #selector(didToggleSwitch), for: .touchUpInside)
}
@objc func didToggleSwitch() {
guard calendarSwitch.isOn else { return }
switch EKEventStore.authorizationStatus(for: .event) {
case .authorized:
print("Is already authorized")
case .denied, .restricted:
print("Is not authorized")
calendarSwitch.isOn = false
showSettingsAlert()
case .notDetermined:
requestPermission()
}
}
func showSettingsAlert() {
let alert = UIAlertController(title: "Not authorized", message: "You need to enable calendar permissions in the Settings app.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Go to Settings", style: .default, handler: { _ in
self.openSettings()
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
func openSettings() {
let url = URL(string: UIApplicationOpenSettingsURLString)!
guard UIApplication.shared.canOpenURL(url) else { return }
UIApplication.shared.open(url, options: [:])
}
func requestPermission() {
let store = EKEventStore()
store.requestAccess(to: .event) { [weak self] (authorized, error) in
if authorized {
print("Got authorization")
} else {
print("Got no authorization")
DispatchQueue.main.async {
self?.calendarSwitch.isOn = false
}
}
if let error = error {
print("Got error: \(error)")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment