如何使用swift在设备日历中添加事件?

如何使用swift在设备日历中添加事件?,swift,ekevent,ekeventstore,Swift,Ekevent,Ekeventstore,我想知道如何在设备中添加日历事件,但使用swift。我知道Objective-C中有一些例子,但目前swift中没有。非常感谢。注意:如果您的应用程序因而崩溃,则此应用程序已崩溃,因为它试图访问隐私敏感数据而没有使用说明。应用程序的Info.plist必须包含一个NSCalendarsUsageDescription密钥,该密钥带有一个向用户解释应用程序如何使用此数据的字符串值。,您需要将NSCalendarsUsageDescription添加到您的Info.plist中。我可以效仿 Swif

我想知道如何在设备中添加日历事件,但使用swift。我知道Objective-C中有一些例子,但目前swift中没有。非常感谢。

注意:如果您的应用程序因
而崩溃,则此应用程序已崩溃,因为它试图访问隐私敏感数据而没有使用说明。应用程序的Info.plist必须包含一个NSCalendarsUsageDescription密钥,该密钥带有一个向用户解释应用程序如何使用此数据的字符串值。
,您需要将
NSCalendarsUsageDescription
添加到您的Info.plist中。我可以效仿

Swift 5.0版

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")
  }
}   

参考:https://gist.github.com/mchirico/d072c4e38bda61040f91

我能够调整这一点,并消除上述答案(以及其他一些答案)注释中提到的编译器错误,如下所示:

 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")
        } 
    })
但是,我仍然在底部得到关于“EKSpan.ThisEvent”的以下错误:调用中的参数标签不正确(have':span:error:',expected':span:commit:')

我试着将“error”改为“commit”,但它给了我一个编译器错误,说它应该是Bool而不是nil。这似乎与swift语法中的更新有关

编辑:我最终跟随了,并且能够让它工作

  • 首先,请求访问日历的权限,然后(如果授予了该权限)调用一个函数来添加事件

    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)
        }
    }
    
  • 在上述代码段中调用以添加事件的函数:

    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")
        }
    }
    

  • Swift 3.0兼容版:

    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?)
            }
        })
    }
    
    还可以导入
    EventKit

    因此,您可以在任何地方轻松调用此方法:

    addEventToCalendar(title: "Girlfriend birthday", description: "Remember or die!", startDate: NSDate(), endDate: NSDate())
    
    如果愿意,可以将此方法放在Utility类中,并将其定义为“静态”。

    您需要将“隐私-日历使用说明”添加到info.plist。 以下代码适用于最新版本的xcode和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")
        }
    }
    

    在iOS 11.2 Xcode 9.2上,速度非常慢,因此我修改了Luca Davanzo的答案,使用队列(工作速度要快得多):


    与位置和警报相同

       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)")
                }
            })
        }
    }
    

    对于不知道您必须导入的用户:import EventKit才能使其正常工作。它给出错误“使用未解析标识符EKEntityTypeEvent”。我遗漏了什么吗?@Dashrath Use
    ekentitype.Event
    (Swift 2.0中的一些更改)而不是请参见
    Rujoota Shah
    ,其答案是它不适合您。您需要在info.plistSwift 2.0实现中添加“隐私-日历使用说明”:您需要添加“隐私-日历使用说明”在info.plist.中,感谢@ThetNaingMizo提供info.plist信息。我将进一步介绍,并将在info.plist Key:Privacy-Calendars用法描述值:$(PRODUCT_NAME)calendar events上添加完整条目请在此处添加一些说明。谢谢
       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)")
                }
            })
        }
    }