简体   繁体   中英

How to return the EKEvent.identifier right after saving it to the EKEventStore?

I want to write a method, that takes a event object, wich has a name and a date parameters. The function requests access / checks access to the event store, creates an EKEvent with the parameters, saves it to the store and then returns the eventidentifier as a String.

So far I have trouble because the eventStore.requestAccess(To:) methods closure escapes, and the string is returned befor the EKEvent object actually is created and saved to the store.

My method sits in the code of my EventHelper class, that is the abstraction layer between my EventStore and Apples EKEventStore.

import EventKit

struct Event {
    var name: String
        var date: Date
    var id: String?
}

class EventHelper {

    // MARK: Properties
    var store: EKEventStore!

    // MARK: Methods
    func createCalendarEvent(for event: Event) -> String? {
        // Prepare a place to store the eventIdentifier
        var identifier : String?

        // Get acces to the eventstore
        store.requestAccess(to: .event) { (granted, error) in

            if (granted) && (error == nil) {

                    print("Calendar event creation.")
                    print("granted: \(granted)")
                    print("error: \(String(describing: error))")

                    // Create a new event kit event
                    let newEvent = EKEvent(eventStore: self.store)
                    newEvent.title = event.name
                    newEvent.startDate = event.date

                    // Create a timeinterval for the end date
                    let twoHourTimeInterval = TimeInterval(exactly: 7200)
                    newEvent.endDate = event.date.addingTimeInterval(twoHourTimeInterval!)


                    // choose the calender the event should be assinged to
                    newEvent.calendar = self.store.defaultCalendarForNewEvents

                    // try to save the new event in the event store
                    do {
                        try self.store.save(newEvent, span: .thisEvent, commit: true)
                        identifier = newEvent.eventIdentifier
                        print("Saved event with ID: \(String(describing: newEvent.eventIdentifier))")
                     // The event gets created and the ID is printed to the console but at a time when the whole function already has returned (nil)
                    } catch let error as NSError {
                        print("Failed to save event with error: \(error)")
                    }
            }
            else {
                print("Failed to save event with error \(String(describing: error)) or access not granted")
            }
        }
        print("new Event: \(String(describing: identifier))")
        return identifier
    }
}

I found a solution!

Instead of using the .requestAccess(to:completion:) for the event creation. I only use it when I explicitly need to ask for access to the EKEventStore. And to check that I switch on .authorizationStatus(for:)

Here comes the code:

import EventKit

class EventHelper {

    // MARK: Properties
    var store: EKEventStore!


    // MARK: Methods
    /*
     This thing I got from here     https://stackoverflow.com/questions/28379603/how-to-add-an-event-in-the-device-calendar-using-swift more or less
     */
    func createCalendarEvent(for event: Event) -> String? {
        // Act base upon the current authorisation status
        switch EKEventStore.authorizationStatus(for: .event) {
        case EKAuthorizationStatus.notDetermined:
            // Ask for permission
            requestAuthorisationToCalendar()

            // And try again
            return try createCalendarEvent(for: event)

        case EKAuthorizationStatus.denied:
            print("Access to the Event Store was denied.")

        case EKAuthorizationStatus.restricted:
            print("Access to the Event Store was restricted.")

        case EKAuthorizationStatus.authorized:
            // Create a new event
            let newEvent = EKEvent(eventStore: store)
            newEvent.title = event.name
            newEvent.startDate = event.date

            // Create a timeinterval for the end date
            let twoHourTimeInterval = TimeInterval(exactly: 7200)
            newEvent.endDate =     event.date.addingTimeInterval(twoHourTimeInterval!)

            // choose the calender the event should be assinged to
            newEvent.calendar = self.store.defaultCalendarForNewEvents

            // try to save the new event in the event store
            do {
            try self.store.save(newEvent, span: .thisEvent, commit: true)
            print("Saved event with ID: \(String(describing: newEvent.eventIdentifier))")
                return newEvent.eventIdentifier
            } catch let error as NSError {
                print("Failed to save event with error: \(error)")
                return nil
            }
        }
    }

    // MARK: Privat Methods
    private func requestAuthorisationToCalendar() {
        store.requestAccess(to: .event) { (granted, error)  in
            if (granted) && (error == nil) {
                DispatchQueue.main.async {
                    print("User has granted access to calendar")
                }
            } else {
                DispatchQueue.main.async {
                    print("User has denied access to calendar")
                }
            }    
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM