/* Copyright (C) 2015 Apple Inc. All Rights Reserved. See LICENSE.txt for this sample’s licensing information Abstract: This file shows an example of implementing the OperationCondition protocol. */ import EventKit /// A condition for verifying access to the user's calendar. struct CalendarCondition: OperationCondition { static let name = "Calendar" static let entityTypeKey = "EKEntityType" static let isMutuallyExclusive = false let entityType: EKEntityType init(entityType: EKEntityType) { self.entityType = entityType } func dependencyForOperation(operation: EarthquakeOperation) -> Operation? { return CalendarPermissionOperation(entityType: entityType) } func evaluateForOperation(operation: EarthquakeOperation, completion: (OperationConditionResult) -> Void) { switch EKEventStore.authorizationStatus(for: entityType) { case .authorized: completion(.Satisfied) default: // We are not authorized to access entities of this type. let error = NSError(code: .ConditionFailed, userInfo: [ OperationConditionKey: type(of: self).name, type(of: self).entityTypeKey: entityType.rawValue, ]) completion(.Failed(error)) } } } /** `EKEventStore` takes a while to initialize, so we should create one and then keep it around for future use, instead of creating a new one every time a `CalendarPermissionOperation` runs. */ private let SharedEventStore = EKEventStore() /** A private `EarthquakeOperation` that will request access to the user's Calendar/Reminders, if it has not already been granted. */ private class CalendarPermissionOperation: EarthquakeOperation { let entityType: EKEntityType init(entityType: EKEntityType) { self.entityType = entityType super.init() addCondition(condition: AlertPresentation()) } override func execute() { let status = EKEventStore.authorizationStatus(for: entityType) switch status { case .notDetermined: DispatchQueue.main.async { SharedEventStore.requestAccess(to: self.entityType) { granted, error in self.finish() } } default: finish() } } }