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

ny6fqffe  于 2023-02-28  发布在  Swift
关注(0)|答案(7)|浏览(199)

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

j91ykkif

j91ykkif1#

注意:如果您的应用因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.而崩溃,您需要将NSCalendarsUsageDescription添加到您的info.plist。可以按照here示例操作。
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

wbgh16ku

wbgh16ku2#

与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())

如果你愿意,你可以把这个方法放在一个utiliy类中,并把它定义为“static”。

oxalkeyp

oxalkeyp3#

你需要在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")
    }
}
e3bfsja2

e3bfsja24#

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

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”的错误:调用中的参数标签不正确(具有“:span:error:”,应为“:span:commit:”)。
我试着将“error”改为“commit”,但它给了我一个编译器错误,说它期望一个Bool而不是nil。这似乎是一个与swift语法中的更新有关的问题。
编辑:我最终跟随了this tutorial,并且能够让它工作。
1.首先,请求访问日历的权限,然后(如果授予了该权限)调用一个函数来添加事件。

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

1.在上面的代码片段中调用以添加事件的函数:

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

cgfeq70w5#

这在iOS 11.2 Xcode 9.2上确实很慢,所以我修改了Luca Davanzo的答案,使用队列(工作速度快得多):

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?)
                }
            })
        }
    }
polhcujo

polhcujo6#

与位置和警报相同

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

xdyibdwo7#

不使用完成处理程序的异步/等待:

func addCalendarEvent(eventTitle: String, startDate: Date, endDate: Date) {
    Task {
        do {
            let eventStore = EKEventStore()
            let requestResult: Bool = try await eventStore.requestAccess(to: .event)
            guard requestResult else {
                debugPrint("Couldn't not create a calendar event. Calendar access denied.")
                return
            }
            let event = EKEvent(eventStore: eventStore)
            event.title = eventTitle
            event.startDate = startDate
            event.endDate = endDate
            event.calendar = eventStore.defaultCalendarForNewEvents
            try eventStore.save(event, span: .thisEvent)
        } catch {
            debugPrint("Couldn't not create a calendar event. Error: \(error.localizedDescription)")
            return
        }
    }
}

相关问题