我的应用中有一个非常奇怪的错误。尝试使用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)")
}
如果calendar
,startDate
或endDate
的值无效,我会收到一个没有崩溃的描述性错误,但此处它会在self.eventStore!.saveEvent()
崩溃。任何帮助表示赞赏!
修改
事实证明这是由于对self.eventStore.reset()
的无关呼叫。
答案 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
}
}