| 
 | 1 | +# Creating and displaying tasks for a patient  | 
 | 2 | + | 
 | 3 | +Create tasks and schedules for patients and display them using a synchronized view controller.  | 
 | 4 | + | 
 | 5 | +## Overview  | 
 | 6 | + | 
 | 7 | +When creating an app using CareKit, you can create tasks, such as taking medication or performing an exercise, for the user to complete. To create tasks for users, first create a store. This provides a place for your task data to persist. Then create both simple and complex task schedules so your users know when to perform their tasks. You can then present the scheduled tasks to the user.  | 
 | 8 | + | 
 | 9 | +### Create a store  | 
 | 10 | + | 
 | 11 | +Create a store for your data. You instantiate your store with a name. There’s no specific validation of this name, but it’s good practice to make it distinctive. Use the reverse-url format bundle identifier of your app with a unique name appended:  | 
 | 12 | + | 
 | 13 | +```swift  | 
 | 14 | +import CareKit  | 
 | 15 | +import CareKitStore  | 
 | 16 | + | 
 | 17 | +let storeName = "com.mycompany.myapp.nausea"  | 
 | 18 | +let store = OCKStore(name: storeName)   | 
 | 19 | +```  | 
 | 20 | + | 
 | 21 | +If you attempt to create a store with a name of an already-existing store, the `OCKStore` initializer returns the existing store.  | 
 | 22 | + | 
 | 23 | +### Create a schedule  | 
 | 24 | + | 
 | 25 | +When creating a task, provide a schedule so users know when they need to complete the task. For a task like taking a medication, the schedule specifies when the user should take that medication, such as 11:00 AM or after dinner.  | 
 | 26 | + | 
 | 27 | +You build schedules by defining times, offsets from known times, and ranges across times and dates that consists of at least one schedule element. A schedule element represents a defined moment or range of moments.  | 
 | 28 | + | 
 | 29 | +> Note: Calendar calculations are complex and depend on the user’s device settings for time zone and calendar. Use the provided Calendar API for the Date and DateComponents to simplify this.  | 
 | 30 | +
  | 
 | 31 | +Building a schedule takes a few simple steps. The code below shows how to create a schedule that occurs every day at 8:00 AM, starting on the current day. In the first line, Calendar returns the first moment of today’s date based on the user’s calendar. In the second line, add 8 hours to create a date object at 8:00 AM. Next, create a schedule element, using today’s date at 8:00 AM, then set it to occur daily. In the last line, create a schedule using the schedule element you created in the line before.  | 
 | 32 | + | 
 | 33 | +```swift  | 
 | 34 | +let startOfDay = Calendar.current.startOfDay(for: Date())  | 
 | 35 | +let atBreakfast = Calendar.current.date(byAdding: .hour, value: 8, to: startOfDay)!  | 
 | 36 | + | 
 | 37 | +let dailyAtBreakfast = OCKScheduleElement(start: atBreakfast, end: nil, interval: DateComponents(day: 1))  | 
 | 38 | + | 
 | 39 | +var schedule = OCKSchedule(composing: [dailyAtBreakfast])  | 
 | 40 | +```  | 
 | 41 | + | 
 | 42 | +Create your schedule using date objects initialized with the user’s calendar preference. There are a variety of calendars your user could be using, each with different properties and nuances. Creating dates with the user’s calendar preference ensures correct date calculations.  | 
 | 43 | + | 
 | 44 | +### Schedule multiple elements  | 
 | 45 | + | 
 | 46 | +If you need a schedule that’s more complex than listing once-a-day events, you can build it by working with multiple schedule elements. The code below expands on the previous code example by creating an additional schedule element that occurs every other day at 12:00 PM. Finally, it creates a schedule with the two schedule elements.  | 
 | 47 | + | 
 | 48 | +```swift  | 
 | 49 | +let startOfDay = Calendar.current.startOfDay(for: Date())  | 
 | 50 | +let atBreakfast = Calendar.current.date(byAdding: .hour, value: 8, to: startOfDay)!  | 
 | 51 | + | 
 | 52 | +let dailyAtBreakfast = OCKScheduleElement(start: atBreakfast, end: nil, interval: DateComponents(day: 1))  | 
 | 53 | + | 
 | 54 | +let atLunch = Calendar.current.date(byAdding: .hour, value: 12, to: startOfDay)!  | 
 | 55 | + | 
 | 56 | +let everyTwoDaysAtLunch = OCKScheduleElement(start: atLunch, end: nil, interval: DateComponents(day: 2))  | 
 | 57 | + | 
 | 58 | +var schedule = OCKSchedule(composing: [dailyAtBreakfast, everyTwoDaysAtLunch])  | 
 | 59 | +```  | 
 | 60 | + | 
 | 61 | +### Create and save tasks to the store  | 
 | 62 | + | 
 | 63 | +Once you’ve defined a schedule, use it to create a task. You create a task with an identifier, title, care plan, and schedule. You can also provide instructions for the task as shown in the second line:  | 
 | 64 | + | 
 | 65 | +```swift  | 
 | 66 | +var task = OCKTask(identifier: "doxylamine", title: "Take Doxylamine", carePlanID: nil, schedule: schedule)  | 
 | 67 | + | 
 | 68 | +task.instructions = "Take 25mg of doxylamine when you experience nausea."  | 
 | 69 | +```  | 
 | 70 | + | 
 | 71 | +Next, save your task to the store. You can specify a function to handle the completion of the operation. The code below shows how to save your task, and the format of the parameters passed into the completion handler.  | 
 | 72 | + | 
 | 73 | +```swift  | 
 | 74 | +let storedTask = try await store.addTask(task)  | 
 | 75 | +```  | 
 | 76 | + | 
 | 77 | +### Handle errors  | 
 | 78 | + | 
 | 79 | +If interacting with the store throws an error, you can catch the error to help troubleshoot the problem and decide how to handle it.  | 
 | 80 | + | 
 | 81 | +The thrown error is an instance of `OCKStoreError`, an enumeration that contains a value and a localized description. The enumeration value is one of the following:  | 
 | 82 | + | 
 | 83 | +- term `fetchFailed`: Occurs when a fetch fails.  | 
 | 84 | + | 
 | 85 | +- term `addFailed`: Occurs when adding an entity fails.  | 
 | 86 | + | 
 | 87 | +- term `updateFailed`: Occurs when an update to an existing entity fails.  | 
 | 88 | + | 
 | 89 | +- term `deleteFailed`: Occurs when deleting an existing entity fails.  | 
 | 90 | + | 
 | 91 | +- term `invalidValue`: Occurs when an invalid value is passed.  | 
 | 92 | + | 
 | 93 | +- term `timedOut`: Occurs when an asynchronous action takes too long. This is intended for use by remote databases.  | 
 | 94 | + | 
 | 95 | +Use this value to determine whether to retry the operation, inform the user, or handle the error some other way. To provide feedback to the user, present the localized description to the user.  | 
 | 96 | + | 
 | 97 | +For example, if you attempt to add an entity to the store that’s missing required information, you receive an error enumeration with the value of `OCKStoreError.invalidValue(reason:)`, and the localized description of “OCKCDScheduleElement must have at least 1 non-zero interval.  | 
 | 98 | + | 
 | 99 | +### Display Scheduled tasks  | 
 | 100 | + | 
 | 101 | +Once you have a store populated with tasks, you can display those tasks to the user. CareKit provides pre-built view controllers and a range of controls and views to build your own user interface layouts.  | 
 | 102 | + | 
 | 103 | +The simplest way to present data to the user is to use the pre-built view controllers. The code below builds on previous code listings, and shows how to present task data to the user using an ``OCKDailyTasksPageViewController``.  | 
 | 104 | + | 
 | 105 | +```swift  | 
 | 106 | +let careViewController = OCKDailyTasksPageViewController(store: store)  | 
 | 107 | +self.present(careViewController, animated: true, completion: nil)  | 
 | 108 | +```  | 
 | 109 | + | 
 | 110 | +The ``OCKDailyTasksPageViewController``  observes changes to the store and updates the view automatically. All you need to do is instantiate it with a store and then present it.  | 
 | 111 | + | 
 | 112 | +The ``OCKDailyTasksPageViewController`` displays a header, that contains a weekly calendar, and a body, that includes a list of tasks scheduled for the currently selected date. When a user selects a date in the calendar, the calendar shows all tasks scheduled for that date. When the user taps to complete a task, the controller saves it in the store.  | 
 | 113 | + | 
 | 114 | +You can use view controllers and views available in CareKit to customize the user interface appearance, or use your own.  | 
0 commit comments