-
-
Save hadanischal/09f2fe57a390b17f06bc3fd6da8a7615 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| import EventKit | |
| import EventKitUI | |
| typealias EventsCalendarManagerResponse = (_ result: ResultCustomError<Bool, CustomError>) -> Void | |
| class EventsCalendarManager: NSObject { | |
| var eventStore: EKEventStore! | |
| override init() { | |
| eventStore = EKEventStore() | |
| } | |
| // Request access to the Calendar | |
| private func requestAccess(completion: @escaping EKEventStoreRequestAccessCompletionHandler) { | |
| eventStore.requestAccess(to: EKEntityType.event) { (accessGranted, error) in | |
| completion(accessGranted, error) | |
| } | |
| } | |
| // Get Calendar auth status | |
| private func getAuthorizationStatus() -> EKAuthorizationStatus { | |
| return EKEventStore.authorizationStatus(for: EKEntityType.event) | |
| } | |
| // Check Calendar permissions auth status | |
| // Try to add an event to the calendar if authorized | |
| func addEventToCalendar(event: Event, completion : @escaping EventsCalendarManagerResponse) { | |
| let authStatus = getAuthorizationStatus() | |
| switch authStatus { | |
| case .authorized: | |
| self.addEvent(event: event, completion: { (result) in | |
| switch result { | |
| case .success: | |
| completion(.success(true)) | |
| case .failure(let error): | |
| completion(.failure(error)) | |
| } | |
| }) | |
| case .notDetermined: | |
| //Auth is not determined | |
| //We should request access to the calendar | |
| requestAccess { (accessGranted, error) in | |
| if accessGranted { | |
| self.addEvent(event: event, completion: { (result) in | |
| switch result { | |
| case .success: | |
| completion(.success(true)) | |
| case .failure(let error): | |
| completion(.failure(error)) | |
| } | |
| }) | |
| } else { | |
| // Auth denied, we should display a popup | |
| completion(.failure(.calendarAccessDeniedOrRestricted)) | |
| } | |
| } | |
| case .denied, .restricted: | |
| // Auth denied or restricted, we should display a popup | |
| completion(.failure(.calendarAccessDeniedOrRestricted)) | |
| } | |
| } | |
| // Generate an event which will be then added to the calendar | |
| private func generateEvent(event: Event) -> EKEvent { | |
| let newEvent = EKEvent(eventStore: eventStore) | |
| newEvent.calendar = eventStore.defaultCalendarForNewEvents | |
| newEvent.title = event.name | |
| newEvent.startDate = event.dateStart | |
| newEvent.endDate = event.dateEnd | |
| // Set default alarm minutes before event | |
| let alarm = EKAlarm(relativeOffset: TimeInterval(Configuration.addEventToCalendarAlarmMinutesBefore()*60)) | |
| newEvent.addAlarm(alarm) | |
| return newEvent | |
| } | |
| // Try to save an event to the calendar | |
| private func addEvent(event: Event, completion : @escaping EventsCalendarManagerResponse) { | |
| let eventToAdd = generateEvent(event: event) | |
| if !eventAlreadyExists(event: eventToAdd) { | |
| do { | |
| try eventStore.save(eventToAdd, span: .thisEvent) | |
| } catch { | |
| // Error while trying to create event in calendar | |
| completion(.failure(.eventNotAddedToCalendar)) | |
| } | |
| completion(.success(true)) | |
| } else { | |
| completion(.failure(.eventAlreadyExistsInCalendar)) | |
| } | |
| } | |
| // Check if the event was already added to the calendar | |
| private func eventAlreadyExists(event eventToAdd: EKEvent) -> Bool { | |
| let predicate = eventStore.predicateForEvents(withStart: eventToAdd.startDate, end: eventToAdd.endDate, calendars: nil) | |
| let existingEvents = eventStore.events(matching: predicate) | |
| let eventAlreadyExists = existingEvents.contains { (event) -> Bool in | |
| return eventToAdd.title == event.title && event.startDate == eventToAdd.startDate && event.endDate == eventToAdd.endDate | |
| } | |
| return eventAlreadyExists | |
| } | |
| // Show event kit ui to add event to calendar | |
| func presentCalendarModalToAddEvent(event: Event, completion : @escaping EventsCalendarManagerResponse) { | |
| let authStatus = getAuthorizationStatus() | |
| switch authStatus { | |
| case .authorized: | |
| presentEventCalendarDetailModal(event: event) | |
| completion(.success(true)) | |
| case .notDetermined: | |
| //Auth is not determined | |
| //We should request access to the calendar | |
| requestAccess { (accessGranted, error) in | |
| if accessGranted { | |
| self.presentEventCalendarDetailModal(event: event) | |
| completion(.success(true)) | |
| } else { | |
| // Auth denied, we should display a popup | |
| completion(.failure(.calendarAccessDeniedOrRestricted)) | |
| } | |
| } | |
| case .denied, .restricted: | |
| // Auth denied or restricted, we should display a popup | |
| completion(.failure(.calendarAccessDeniedOrRestricted)) | |
| } | |
| } | |
| // Present edit event calendar modal | |
| func presentEventCalendarDetailModal(event: Event) { | |
| let event = generateEvent(event: event) | |
| let eventModalVC = EKEventEditViewController() | |
| eventModalVC.event = event | |
| eventModalVC.eventStore = eventStore | |
| eventModalVC.editViewDelegate = self | |
| if let rootVC = UIApplication.shared.keyWindow?.rootViewController { | |
| rootVC.present(eventModalVC, animated: true, completion: nil) | |
| } | |
| } | |
| } | |
| // EKEventEditViewDelegate | |
| extension EventsCalendarManager: EKEventEditViewDelegate { | |
| func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) { | |
| controller.dismiss(animated: true, completion: nil) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment