Попытка сохранить событие в EKEventStore приводит к сбою приложения.

У меня очень странная ошибка в моем приложении. Попытка сохранить событие с помощью saveEvent приводит к продолжению работы приложения одним из трех способов:

  • Все сохраняется корректно и без проблем
  • Приложение вылетает с ошибкой unrecognized selector sent to instance, где селектор-нарушитель – constraints:, а объект, которому оно отправляется, всегда отличается и довольно непредсказуем (это почти всегда закрытые классы SDK).
  • Приложение вылетает с ошибкой EXC_BAD_ACCESS

Пытаясь отладить это, я разделил приложение только на контроллер представления, в котором перечислены события, с кнопкой для добавления нового. В первый раз, когда я представляю контроллер представления для добавления события, все идет гладко, но во второй раз, когда я это делаю, выдает ошибку.

Вот код, который я использую:

self.event = EKEvent(eventStore: self.eventStore!)
self.event!.calendar = self.calendar!
self.event!.startDate = self.defaultStartDate()
self.event!.endDate = self.event!.startDate.dateByAddingTimeInterval(3600)
var error: NSError?
self.eventStore!.saveEvent(self.event!, span:EKSpanThisEvent, error: &error)
if let e = error {
    println("Saving error: \(error)")
}

Если значения для calendar, startDate или endDate недействительны, я получаю описательную ошибку без сбоя, но здесь происходит сбой на self.eventStore!.saveEvent(). Любая помощь приветствуется!

Изменить Оказывается, это произошло из-за постороннего вызова self.eventStore.reset().


person SaltyNuts    schedule 21.07.2015    source источник


Ответы (1)


После долгих поисков я нашел решение.
Вам нужно сохранить свои события в фоновом коде встраивания в блоке dispatch_async.

enum UWCalendarError: Int {
    case AlreadyExists 
    case Generic
    case NotGranted 
}

class Calendar {

static func saveEvent(title: String, startDate: NSDate, duration: NSTimeInterval, completion: (success: Bool, error: UWCalendarError?) -> Void) {

    if Calendar.isEventAlreadyScheduled(title, startDate: startDate, duration: duration) {
        completion(success: false, error: .AlreadyExists)
    } else {
        dispatch_async(dispatch_get_main_queue(),{
            let store = EKEventStore()
            store.requestAccessToEntityType(EKEntityTypeEvent) {(granted, error) in
                if !granted {
                    completion(success: false, error: .NotGranted)
                }
                var event = EKEvent(eventStore: store)
                event.title = title
                event.startDate = startDate
                event.endDate = event.startDate.dateByAddingTimeInterval(duration)
                event.calendar = store.defaultCalendarForNewEvents
                var err: NSError?
                store.saveEvent(event, span: EKSpanThisEvent, commit: true, error: &err)
                if err == nil {
                    completion(success: true, error: nil)
                } else {
                    completion(success: false, error: .Generic)
                }
            }
        })
    }
}

static func isEventAlreadyScheduled(title: String, startDate: NSDate, duration: NSTimeInterval) -> Bool {

    let endDate = startDate.dateByAddingTimeInterval(duration)
    let eventStore = EKEventStore()
    let predicate = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: nil)
    let events = eventStore.eventsMatchingPredicate(predicate)

    if events == nil {
        return false
    }

    for eventToCheck in events {
        if eventToCheck.title == title {
            return true
        }
    }

    return false
}

}
person Luca Davanzo    schedule 07.08.2015