我有一个简单的功能,用于请求访问以在日历中添加事件。

typealias BoolCallback = (Bool) -> ()

class SimpleCalendar {

    let store: EKEventStore

    init(store: EKEventStore = EKEventStore()) {
        self.store = store
    }

    /// Request access to EventKit API for Calendar intergration
    ///
    /// - Parameter callback: returns if access was recived or denied
    func requestAccess(callback: @escaping BoolCallback) {

        let status = EKEventStore.authorizationStatus(for: .event)

        switch status {
        case .authorized:
            callback(true)
            //        case .notDetermined: //should ask for access
        //        case .denied, .restricted: //should open a ask permission view
        default:
            store.requestAccess(to: .event) { accessGranted, _ in

                DispatchQueue.main.async {
                    callback(accessGranted)
                }
            }
        }


    }
}

有没有一种方法可以模拟EKEventStore来获取状态?

我还有一个简单的功能,可以检查日历是否存在。
func doesCalendarExist(name: String) -> Bool {
    let calendars = store.calendars(for: .event)

    if calendars.contains(where: { $0.title == name }) {
        return true
    }

    return false
}

有没有一种方法可以模拟商店对象以获取store.calendars
谢谢

我换了
let status = EKEventStore.authorizationStatus(for: .event)


let status = type(of: store).authorizationStatus(for: .event)

最佳答案

我想您可以在这里使用DI。不用在 SimpleCalendar 内创建存储变量的责任,您可以使用 store参数为它创建构造函数:EKEventStore 并将其传递到那里:

init(store: EKEventStore = EKEventStore()) {/*code*/}

这样,您可以传递自己的模拟对象。

覆盖类方法有什么问题?我现在无法检查,但想可能。

无论如何,其他选项都是模拟的,您可以使用所有正在使用的方法- EventStoreProtocol 创建协议。我认为这些方法必须在 EKEventStore 中,因此您可以使用扩展名轻松采用它:
extension EKEventStore: EventStoreProtocol {}

然后,不要将 EKEventStore 传递给构造函数,而是将 EventStoreProtocol 传递给构造函数。

模拟对象不是子类,而只是对该协议进行确认的类,实现所有必需的方法

对于类方法,请使用类型(of:store).authorizationStatus 代替 EKEventStore.authorizationStatus

关于您的问题,我唯一能想到的就是下一个:
extension EKEventStore {
   func eventAuthorizationStatus() -> EKAuthorizationStatus {
      return EKEventStore.authorizationStatus(for: .event)
   }
}

然后在子类中重写此方法。因为 EKEventStore NSObject ,所以它应该可以工作(但我不确定)。这样,您可以调用此方法,而不是使用类型(of:商店).authorizationStatus

但问题是-您真的需要这个吗?您不能就这样保留它吗?如果否,请检查此方法并告诉我是否可行

10-07 16:40