Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何模拟EKEventStore_Ios_Swift_Unit Testing_Mocking - Fatal编程技术网

Ios 如何模拟EKEventStore

Ios 如何模拟EKEventStore,ios,swift,unit-testing,mocking,Ios,Swift,Unit Testing,Mocking,我有一个简单的函数,用于请求访问以在日历中添加事件 typealias BoolCallback = (Bool) -> () class SimpleCalendar { let store: EKEventStore init(store: EKEventStore = EKEventStore()) { self.store = store } /// Request access to EventKit API for Cal

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

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对象以获取
store.calendars

谢谢


我换了

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


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

init(store: EKEventStore = EKEventStore()) {/*code*/}
这样,您就可以传递自己的模拟对象

重写类方法有什么问题?我现在不能查,但假设可能的话

不管怎样,另一个选项是模拟,您可以使用所有正在使用的方法创建协议-EventStoreProtocol。我认为这些方法必须在EKEventStore中,这样您就可以使用扩展轻松地采用它:

extension EKEventStore: EventStoreProtocol {}
然后,不要将EKEventStore传递给构造函数,而是传递给那里EventStoreProtocol

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

对于类方法,不要使用EKEventStore.authorizationStatus使用类型(of:store)。authorizationStatus

关于你的问题,我能想到的唯一一件事是:

extension EKEventStore {
   func eventAuthorizationStatus() -> EKAuthorizationStatus {
      return EKEventStore.authorizationStatus(for: .event)
   }
}
然后在子类中重写此方法。因为EKEventStoreNSObject,所以它应该可以工作(但我不确定)。通过这种方式而不是使用类型(of:store).authorizationStatus您可以调用此方法


但问题是,你真的需要这个吗?你就不能保持原样吗?如果没有,请检查此方法并告诉我,如果它有效

谢谢,这适用于'doesCalendarExist'函数,但您知道如何模拟类方法'EKEventStore.authorizationStatus'谢谢,我将再次解释类方法的问题。如您所见,我在代码中调用“EKEventStore.authorizationStatus”,这是一个类方法,因此我无法使用DI@ilan,我认为您可以-由于您的实例将是另一个类,您必须从该实例访问该类并调用其方法。因此,代替EKEventStore.authorizationStatus put type(of:store)。authorizationStatus我不理解代码部分,您可以将其添加到您的答案中吗?可能您可以编写更详细的说明:)请检查新的更新
extension EKEventStore {
   func eventAuthorizationStatus() -> EKAuthorizationStatus {
      return EKEventStore.authorizationStatus(for: .event)
   }
}