-
Notifications
You must be signed in to change notification settings - Fork 452
Description
Consider the following code snippet
let taskStartDate = Calendar.current.startOfDay(for: Date())
let taskEndDate = Calendar.current.date(byAdding: .day, value: 1, to: taskStartDate)
let taskScheduleElement = OCKScheduleElement(
start: taskStartDate,
end: taskEndDate,
interval: DateComponents(day: 1),
text: nil,
targetValues: [],
duration: .allDay
)
let taskSchedule = OCKSchedule(composing: [taskScheduleElement])
let allDayTask = OCKTask(
id: "allDayTask",
title: "All day task",
carePlanUUID: nil,
schedule: taskSchedule
)
When this task is added to the store, it could be fetched on two consecutive days (today and tomorrow). For the 2nd day particularly, the result
variable in the lines below have schedule element past the user specified time, but it won't be filtered out and therefore a task view controller can be created.
CareKit/CareKitStore/CareKitStore/CoreData/OCKStore+Tasks.swift
Lines 47 to 52 in 8ca7962
let filtered = result.map { | |
$0.filtered( | |
dateInterval: query.dateInterval, | |
excludeTasksWithNoEvents: query.excludesTasksWithNoEvents | |
) | |
} |
However, if the user taps the completion button for the 2nd day, the program will crash when attempts to unwrap a nil
value
CareKit/CareKitStore/CareKitStore/Structs/OCKSchedule.swift
Lines 60 to 62 in 8ca7962
public subscript(occurrence: Int) -> OCKScheduleEvent { | |
return event(forOccurrenceIndex: occurrence)! | |
} |
One can find the nil
value is set at line 176 below due to the >=
operation
CareKit/CareKitStore/CareKitStore/Structs/OCKScheduleElement.swift
Lines 175 to 180 in 8ca7962
for index in 0..<numberOfEvents { | |
if let endDate = end, currentDate >= endDate { continue } | |
events[index] = makeScheduleEvent(on: currentDate, for: currentOccurrence) | |
currentDate = Calendar.current.date(byAdding: interval, to: currentDate)! | |
currentOccurrence += 1 | |
} |
I understand that it is better to set the end time for the task schedule like this
let taskEndDate = Calendar.current.date(byAdding: DateComponents(day: 1, second: -1), to: taskStartDate)
and then the task will not be fetched on the 2nd day. However, I think there is some inconsistent treatments on the end date of the schedule. If at one place >=
operation is considered to eliminate the intersection of a single time point of duration 0, then the code should not create any event for the task in the other place.
I hope the code above is clear enough and easy to reproduce. Just in case, a toy example is available also at https://github.com/zhang-bo-lilly/TaskOccurenceIssue.git