How to add an event in the device calendar using swift?

前端 未结 6 1653
孤城傲影
孤城傲影 2020-12-07 17:27

I would be interested in knowing how to add a calendar event in the device, but using swift. I know there are some examples made in Objective-C, but at the moment nothing in

相关标签:
6条回答
  • 2020-12-07 18:01

    This was really slow on iOS 11.2 Xcode 9.2, so I modified Luca Davanzo's answer to use queues (works a lot faster):

    func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
            DispatchQueue.global(qos: .background).async { () -> Void in
                let eventStore = EKEventStore()
    
                eventStore.requestAccess(to: .event, completion: { (granted, error) in
                    if (granted) && (error == nil) {
                        let event = EKEvent(eventStore: eventStore)
                        event.title = title
                        event.startDate = startDate
                        event.endDate = endDate
                        event.notes = description
                        event.calendar = eventStore.defaultCalendarForNewEvents
                        do {
                            try eventStore.save(event, span: .thisEvent)
                        } catch let e as NSError {
                            completion?(false, e)
                            return
                        }
                        completion?(true, nil)
                    } else {
                        completion?(false, error as NSError?)
                    }
                })
            }
        }
    
    0 讨论(0)
  • 2020-12-07 18:06

    same with location and alert

       func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, location: String?, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
        DispatchQueue.global(qos: .background).async { () -> Void in
            let eventStore = EKEventStore()
    
            eventStore.requestAccess(to: .event, completion: { (granted, error) in
                if (granted) && (error == nil) {
                    let alarm = EKAlarm(relativeOffset: -3600.0)
                    let event = EKEvent(eventStore: eventStore)
                    event.title = title
                    event.startDate = startDate
                    event.endDate = endDate
                    event.notes = description
                    event.alarms = [alarm]
                    event.location = location
                    event.calendar = eventStore.defaultCalendarForNewEvents
                    do {
                        try eventStore.save(event, span: .thisEvent)
                    } catch let e as NSError {
                        completion?(false, e)
                        print ("\(#file) - \(#function) error: \(e.localizedDescription)")
                        return
                    }
                    completion?(true, nil)
                } else {
                    completion?(false, error as NSError?)
                    print ("\(#file) - \(#function) error: \(error)")
                }
            })
        }
    }
    
    0 讨论(0)
  • 2020-12-07 18:07

    Swift 3.0 compatible:

    func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
        let eventStore = EKEventStore()
    
        eventStore.requestAccess(to: .event, completion: { (granted, error) in
            if (granted) && (error == nil) {
                let event = EKEvent(eventStore: eventStore)
                event.title = title
                event.startDate = startDate
                event.endDate = endDate
                event.notes = description
                event.calendar = eventStore.defaultCalendarForNewEvents
                do {
                    try eventStore.save(event, span: .thisEvent)
                } catch let e as NSError {
                    completion?(false, e)
                    return
                }
                completion?(true, nil)
            } else {
                completion?(false, error as NSError?)
            }
        })
    }
    

    And also import EventKit

    So you can easily call this method from everywhere:

    addEventToCalendar(title: "Girlfriend birthday", description: "Remember or die!", startDate: NSDate(), endDate: NSDate())
    

    If you prefer, you can put this method inside an utiliy class and define it as 'static'.

    0 讨论(0)
  • 2020-12-07 18:15

    You need to add "Privacy - Calendars Usage Description" to info.plist. Following code works with latest version of xcode and swift 3.

    import EventKit
    class EventHelper
    {
        let appleEventStore = EKEventStore()
        var calendars: [EKCalendar]?
        func generateEvent() {
            let status = EKEventStore.authorizationStatus(for: EKEntityType.event)
    
            switch (status)
            {
            case EKAuthorizationStatus.notDetermined:
                // This happens on first-run
                requestAccessToCalendar()
            case EKAuthorizationStatus.authorized:
                // User has access
                print("User has access to calendar")
                self.addAppleEvents()
            case EKAuthorizationStatus.restricted, EKAuthorizationStatus.denied:
                // We need to help them give us permission
                noPermission()
            }
        }
        func noPermission()
        {
            print("User has to change settings...goto settings to view access")
        }
        func requestAccessToCalendar() {
            appleEventStore.requestAccess(to: .event, completion: { (granted, error) in
                if (granted) && (error == nil) {
                    DispatchQueue.main.async {
                        print("User has access to calendar")
                        self.addAppleEvents()
                    }
                } else {
                    DispatchQueue.main.async{
                        self.noPermission()
                    }
                }
            })
        }
        func addAppleEvents()
        {
            let event:EKEvent = EKEvent(eventStore: appleEventStore)
            event.title = "Test Event"
            event.startDate = NSDate() as Date
            event.endDate = NSDate() as Date
            event.notes = "This is a note"
            event.calendar = appleEventStore.defaultCalendarForNewEvents
    
            do {
                try appleEventStore.save(event, span: .thisEvent)
                print("events added with dates:")
            } catch let e as NSError {
                print(e.description)
                return
            }   
            print("Saved Event")
        }
    }
    
    0 讨论(0)
  • 2020-12-07 18:22

    I was able to adjust this and eliminate the compiler error mentioned in the comments to the answers above (and a few others), as follows:

     var eventStore : EKEventStore = EKEventStore()
    
        // 'EKEntityTypeReminder' or 'EKEntityTypeEvent'
    
        eventStore.requestAccessToEntityType(EKEntityType.Event, completion: {
            (granted, error) in
    
            if (granted) && (error == nil) {
                print("granted \(granted)")
                print("error \(error)")
    
                var event:EKEvent = EKEvent(eventStore: eventStore)
    
                event.title = "Test Title"
                event.startDate = NSDate()
                event.endDate = NSDate()
                event.notes = "This is a note"
                event.calendar = eventStore.defaultCalendarForNewEvents
    
                eventStore.saveEvent(event, span: EKSpan.ThisEvent, error: nil)
    
                print("Saved Event")
            } 
        })
    

    However, I still get the following error at the bottom regarding "EKSpan.ThisEvent" : Incorrect argument label in call (have ':span:error:', expected ':span:commit:').

    I tried changing "error" to "commit," but it gave me a compiler error saying it expected a Bool instead of nil. It seems like a problem having to do with updates in swift syntax.

    Edit: I ended up following this tutorial and was able to get it to work.

    1. First, ask permission to access the calendar and (if that permission is granted) call a function to add the event.

      var savedEventId : String = ""
      
      func requestAccessPermission() {
          let eventStore = EKEventStore()
      
          let startDate = NSDate()
          let endDate = startDate.dateByAddingTimeInterval(60 * 60) // Ends one hour later
      
          if (EKEventStore.authorizationStatusForEntityType(.Event) != EKAuthorizationStatus.Authorized) {
              eventStore.requestAccessToEntityType(.Event, completion: {
              granted, error in
                  self.createEvent(eventStore, title: "Test Title", startDate: startDate, endDate: endDate)
              })
          } else {
              createEvent(eventStore, title: "Test Title", startDate: startDate, endDate: endDate)
          }
      }
      
    2. The function that is called in the above code snippet to add the event:

      func createEvent(eventStore: EKEventStore, title: String, startDate: NSDate, endDate: NSDate) {
          let event = EKEvent(eventStore: eventStore)
          event.title = title
          event.startDate = startDate
          event.endDate = endDate
          event.calendar = eventStore.defaultCalendarForNewEvents
          do {
              try eventStore.saveEvent(event, span: .ThisEvent)
              savedEventId = event.eventIdentifier
          } catch {
              print("Error Saving")
          }
      }
      
    0 讨论(0)
  • 2020-12-07 18:28

    Note: If your app is crashing with This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCalendarsUsageDescription key with a string value explaining to the user how the app uses this data., you'll need to add NSCalendarsUsageDescription to your info.plist. Can follow the example here.

    Swift 5.0 Version

    import Foundation
    import EventKit
    
    let eventStore : EKEventStore = EKEventStore()
          
    // 'EKEntityTypeReminder' or 'EKEntityTypeEvent'
    
    eventStore.requestAccess(to: .event) { (granted, error) in
      
      if (granted) && (error == nil) {
          print("granted \(granted)")
          print("error \(error)")
          
          let event:EKEvent = EKEvent(eventStore: eventStore)
          
          event.title = "Test Title"
          event.startDate = Date()
          event.endDate = Date()
          event.notes = "This is a note"
          event.calendar = eventStore.defaultCalendarForNewEvents
          do {
              try eventStore.save(event, span: .thisEvent)
          } catch let error as NSError {
              print("failed to save event with error : \(error)")
          }
          print("Saved Event")
      }
      else{
      
          print("failed to save event with error : \(error) or access not granted")
      }
    }   
    

    Reference : https://gist.github.com/mchirico/d072c4e38bda61040f91

    0 讨论(0)
提交回复
热议问题