Skip to content

Extra event for OCKTask with all day duration #670

@zhang-bo-lilly

Description

@zhang-bo-lilly

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.

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

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

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions