请求EventKit访问macOS SwiftUI

问题描述

我试图在SwiftUI MacOS应用中请求访问日历,但它立即拒绝了。

下面是一些可测试的代码,突出显示了我想要实现的目标。非常感谢。

根据我以前在MacOS上请求私人信息的经验,应该显示一条通知,而不是在iOS上弹出窗口。

我仍在尝试为SwiftUI设计EventKit,因此请原谅任何错误

struct ContentView: View {
    
    let eventStore = EKEventStore()
    
    var body: some View {
        
        Text("Test")
            .onAppear{
                checkCalendarauthorizationStatus()
            }
        
    }
    
    
    func checkCalendarauthorizationStatus() {

        
        switch EKEventStore.authorizationStatus(for: .event) {
        case .authorized:
            insertEvent(store: eventStore)
            case .denied:
                print("Access denied")
            case .notDetermined:
            // 3
                eventStore.requestAccess(to: .event,completion:
                  {(granted: Bool,error: Error?) -> Void in
                      if granted {
                        self.insertEvent(store: eventStore)
                      } else {
                            print("Access denied")
                      }
                })
            default:
                print("Case default")
        }
    }
    
    func insertEvent(store: EKEventStore) {
        // 1
        let calendars = store.calendars(for: .event)
            
        for calendar in calendars {
            // 2
            if calendar.title == "Calendar" {
                // 3
                let startDate = Date()
                // 2 hours
                let endDate = startDate.addingTimeInterval(2 * 60 * 60)
                    
                // 4
                let event = EKEvent(eventStore: store)
                event.calendar = calendar
                    
                event.title = "New Meeting"
                event.startDate = startDate
                event.endDate = endDate
                    
                // 5
                do {
                    try store.save(event,span: .thisEvent)
                }
                catch {
                   print("Error saving event in calendar")             }
                }
        }
    }
}

解决方法

您不应检查状态,而应按照记录直接通过EKEventStore()。requestAccess(...)请求访问

/**
    @method     requestAccessToEntityType:completion:
    @discussion Users are able to grant or deny access to event and reminder data on a per-app basis. To request access to
                event and/or reminder data,call -requestAccessToEntityType:completion:. This will not block the app while
                the user is being asked to grant or deny access.
 
                Until access has been granted for an entity type,the event store will not contain any calendars for that
                entity type,and any attempt to save will fail. The user will only be prompted the first time access is
                requested; any subsequent instantiations of EKEventStore will use the existing permissions. When the user
                taps to grant or deny access,the completion handler will be called on an arbitrary queue.
*/
@available(macOS 10.9,*)
open func requestAccess(to entityType: EKEntityType,completion: @escaping EKEventStoreRequestAccessCompletionHandler)

因此请使用以下

func checkCalendarAuthorizationStatus() {

    eventStore.requestAccess(to: .event,completion:
      {(granted: Bool,error: Error?) -> Void in
          if granted {
            self.insertEvent(store: eventStore)
          } else {
            print("Access denied")
          }
    })
}

并确保在NSCalendarsUsageDescription中添加了Info.plist描述。