I need to create multiple calendar events for Unit Test in Xcode. The call needs to be async, because of the access rights request:
eventStore.requestAccess(to: EKEntityType.event, completion: {
granted, error in
//create events
})
This is done in setUp()
in a loop to create multiple events. The problem is that not all the completion blocks are done when the test starts running. I have implemented the waitForExpectations()
method, to make it wait till the counter meets the requirements. But I get the following error message:
Stall on main thread
Here is the relevant code - setUp:
override func setUp()
{
super.setUp()
if let filepath = Bundle.main.path(forResource: "MasterCalendar", ofType: "csv") {
do {
let expectationCreation = expectation(description: "create events expectation")
let contents = try String(contentsOfFile: filepath)
//print(contents)
let testDataArray = importTestDataArrayFrom(file: contents)
createTestEvents(testDataArray: testDataArray)
{ (eventsArray) in
self.testEvents = eventsArray
print("finished creating events")
expectationCreation.fulfill()
}
waitForExpectations(timeout: 10.0) { (error) in
if error != nil {
XCTFail((error?.localizedDescription)!)
}
}
} catch {
print("contents could not be loaded")
}
} else {
print("example.txt not found!")
}
}
Create events:
func createTestEvents(testDataArray: [TestData], completion: @escaping (_ eventArray: [EKEvent]) -> Void) -> Void
{
let eventStore = EKEventStore()
var testEvents = [EKEvent]()
var index = 0
for testDataEvent in testDataArray
{
eventStore.requestAccess(to: EKEntityType.event, completion: {
granted, error in
if (granted) && (error == nil) {
print("===GRATNED, CREATING EVENT-", index)
index += 1
let event = EKEvent.init(eventStore: eventStore)
event.title = testDataEvent.combinedFields
event.startDate = Date()
event.endDate = Date()
event.isAllDay = false
var attendees = [EKParticipant]()
for i in 0 ..< 5 {
if let attendee = self.createParticipant(email: "test\(i)@email.com") {
attendees.append(attendee)
}
}
event.setValue(attendees, forKey: "attendees")
try! eventStore.save(event, span: .thisEvent)
let meetingObj = Parser.parse(calendarEvent: event)
testDataEvent.meeting = meetingObj
testEvents.append(event)
if(testEvents.count == testDataArray.count){
completion (testEvents)
}
}
})
}
}