7

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)
                }
            }
        })
    }
}
Async-
  • 3,140
  • 4
  • 27
  • 49

0 Answers0