我有一个简单的功能,用于请求访问以在日历中添加事件。
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 。
但问题是-您真的需要这个吗?您不能就这样保留它吗?如果否,请检查此方法并告诉我是否可行