Swift 4.0 Eventkit 无法正确获取日历和事件

Posted

技术标签:

【中文标题】Swift 4.0 Eventkit 无法正确获取日历和事件【英文标题】:Swift 4.0 Eventkit Cannot get calendars and events correctly 【发布时间】:2018-03-28 03:25:11 【问题描述】:

我正在尝试使用 Eventkit 访问 Mac 日历。 已成功请求访问权限,但我不断收到 nil 或日历或事件数组为空,即使我在本地日历、iCloud 日历和 Google 日历中的应用程序中有多个日历和许多事件。 我从以下代码得到的输出是: 在我的 Mac 上 [] []

    let sources = eventStore.sources
    for source in sources
        print(source.title)
        for calendar in source.calendars(for: .event)
            print(calendar.title)
        
    

    let calendars = eventStore.calendars(for: .event)
    let predicate = self.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil)
    let events = self.eventStore.events(matching: predicate)
    print(calendars)
    print(events)

如果我尝试从代码创建和保存日历,则会出现错误: Error Domain=EKErrorDomain Code=5 "当持久性不可用时尝试保存" UserInfo=NSLocalizedDescription=当持久性不可用时尝试保存

【问题讨论】:

来自文档:developer.apple.com/documentation/eventkit/ekerror/code/… 此错误代码“5”是内部错误。其次,“我从以下代码得到的输出是:在我的 Mac [] [] 上”你有 4 个打印语句,但在问题输出中只显示 2 个 @art-divin 第二个打印语句永远不会执行,因为没有日历。 【参考方案1】:

经过多次反复试验,我找到了答案。

您需要在您的权利文件中将 com.apple.security.personal-information.calendars 键设置为 YES,即使您的应用没有沙盒化。 Apple 的 EventKit 实现中存在一个错误,该错误会阻止您的应用访问如果它没有设置这个键,即使沙盒被禁用,日历也是如此。

【讨论】:

【参考方案2】:

我可能是错的,但是您在传递 nil 的谓词中缺少一个参数,因此基本上没有任何输出可以排序。尝试将您的代码更改为:

 let sources = eventStore.sources
    for source in sources
        print(source.title)
        for calendar in source.calendars(for: .event)
            print(calendar.title)
        
    

    let calendars = eventStore.calendars(for: .event)
    let predicate = self.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: calendars)  //change here
    let events = self.eventStore.events(matching: predicate)
    print(calendars)
    print(events)

【讨论】:

此更改是明智的,但此问题的根本原因是由于权限错误,调用 eventStore.calendars() 时未枚举日历(请参阅我的答案)。跨度> 感谢您的澄清。很好,您已经设法找到问题的根本原因。【参考方案3】:

试试这个方法

创建和获取日历

func getCalendar() -> EKCalendar? 
        let defaults = UserDefaults.standard
    
        if let id = defaults.string(forKey:"calendarID") 
            return eventStore.calendar(withIdentifier: id)
           else 
            let calendar = EKCalendar(for: .event, eventStore: eventStore)
    
               calendar.title = "Calendar Title"
               calendar.cgColor = UIColor.blue
               calendar.source = self.eventStore.defaultCalendarForNewEvents!.source
    
             do 
                 try eventStore.saveCalendar(calendar, commit: true)
                 defaults.set(calendar.calendarIdentifier, forKey: "calendarID")
    
                 print("Created calander")
                catch let error as NSError 
               print("failed to Create calendar with error : \(error)")
               
            
    
              return calendar
          
      

【讨论】:

以上是关于Swift 4.0 Eventkit 无法正确获取日历和事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在UICollectionView Swift 4.0中正确调整和扩展单元格的大小和居中

如何在 UICollectionView Swift 4.0 中正确调整大小和居中扩展单元格

在 swift 4.0 中从 firebase 快照字典中获取值时打开一个可选的 nil

自定义时区的 EventKit 问题

在 Swift 中从 EKEvent 获取日历颜色

Xcode 9:使用 Swift 3.1 编译的模块无法在 Swift 4.0 中导入