尝试在EKEventStore中保存事件会导致应用程序崩溃

时间:2015-07-21 21:15:38

标签: ios eventkit ekeventstore

我的应用中有一个非常奇怪的错误。尝试使用saveEvent保存活动会导致应用以3种方式之一继续:

  • 一切都得到正确保存而没有问题
  • 应用崩溃时出现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)")
}

如果calendarstartDateendDate的值无效,我会收到一个没有崩溃的描述性错误,但此处它会在self.eventStore!.saveEvent()崩溃。任何帮助表示赞赏!

修改 事实证明这是由于对self.eventStore.reset()的无关呼叫。

1 个答案:

答案 0 :(得分: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
}

}