diff --git a/CareKitEssentials.xcodeproj/project.pbxproj b/CareKitEssentials.xcodeproj/project.pbxproj
index ecd7a1f6..ccd8a201 100644
--- a/CareKitEssentials.xcodeproj/project.pbxproj
+++ b/CareKitEssentials.xcodeproj/project.pbxproj
@@ -199,10 +199,10 @@
isa = PBXGroup;
children = (
OBJ_26 /* Calendar+Dates.swift */,
- 700DA9062C2A66BF00435E2C /* Logger.swift */,
911BDB272A11C491004F8442 /* CGFloat.swift */,
OBJ_32 /* CustomLinearCareTaskProgress.swift */,
OBJ_27 /* Image.swift */,
+ 700DA9062C2A66BF00435E2C /* Logger.swift */,
OBJ_29 /* OCKAnyEvent.swift */,
OBJ_28 /* OCKAnyEvent+CustomStringConvertable.swift */,
OBJ_30 /* OCKAnyOutcome.swift */,
diff --git a/README.md b/README.md
index a13da40e..cfa9822e 100644
--- a/README.md
+++ b/README.md
@@ -7,4 +7,18 @@
![Codecov](https://codecov.io/gh/netreconlab/CareKitEssentials/branches/main/graph/badge.svg)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/netreconlab/ParseCareKit/#license)
-Provides essential cards, viewa, models, protocols, and extentions to expedite building [CareKit](https://github.com/carekit-apple/CareKit) based applications.
+Provides essential cards, views, models, protocols, and extentions to expedite building [CareKit](https://github.com/carekit-apple/CareKit) based applications.
+
+## Entensions
+A number of public extensions are available to make using CareKit easier. All of the extensions can be found in the [Extensions](https://github.com/netreconlab/CareKitEssentials/tree/main/Sources/CareKitEssentials/Extensions) folder.
+
+## Usage
+You can create SwiftUI views that conform to [CareKitEssentialView](https://github.com/netreconlab/CareKitEssentials/blob/main/Sources/CareKitEssentials/Cards/Shared/CareKitEssentialView.swift) to obtain a number of convenience methods for saving and deleting outcomes. The following views are based on `CareKitEssentialView`:
+
+### iOS
+[SliderLogTaskView](https://github.com/netreconlab/CareKitEssentials/blob/main/Sources/CareKitEssentials/Cards/iOS/SliderLog/SliderLogTaskView.swift) can be used to quickly create a slider view
+
+
+### watchOS
+[DigitalCrownView](https://github.com/netreconlab/CareKitEssentials/blob/main/Sources/CareKitEssentials/Cards/watchOS/DigitalCrown/DigitalCrownView.swift) can be used to quickly create a view that responds to the crown
+
\ No newline at end of file
diff --git a/Sources/CareKitEssentials/Cards/Shared/CareKitEssentialView.swift b/Sources/CareKitEssentials/Cards/Shared/CareKitEssentialView.swift
index 4e440257..b8e95fa7 100644
--- a/Sources/CareKitEssentials/Cards/Shared/CareKitEssentialView.swift
+++ b/Sources/CareKitEssentials/Cards/Shared/CareKitEssentialView.swift
@@ -27,14 +27,12 @@ public protocol CareKitEssentialView: View {
with values: [OCKOutcomeValue]?
) async throws
- /// Update an `OCKAnyEvent` with new a `OCKOutcome`.
+ /// Save a new `OCKAnyOutcome`.
/// - Parameters:
- /// - event: The event to update.
- /// - outcome: A new `OCKOutcome`.
- /// - Throws: An error if the outcome values cannot be updated.
- func updateEvent(
- _ event: OCKAnyEvent,
- with outcome: OCKOutcome?
+ /// - outcome: A new `OCKAnyOutcome`.
+ /// - Throws: An error if the outcome cannot be updated.
+ func saveOutcome(
+ _ outcome: OCKAnyOutcome
) async throws
/// Create an `OCKEventQuery` constrained to a set of `taskIDs` on a particular date.
@@ -50,43 +48,31 @@ public protocol CareKitEssentialView: View {
public extension CareKitEssentialView {
+ func deleteEventOutcome(_ event: OCKAnyEvent) async throws {
+ guard let outcome = event.outcome else {
+ throw CareKitEssentialsError.errorString("The event does not contain an outcome: \(event)")
+ }
+ _ = try await careStore.deleteAnyOutcome(outcome)
+ }
+
func updateEvent(
_ event: OCKAnyEvent,
with values: [OCKOutcomeValue]?
) async throws {
guard let values = values else {
// Attempts to delete outcome if it already exists.
- _ = try await self.saveOutcomeValues(
- [],
- event: event,
- store: careStore
- )
+ try await deleteEventOutcome(event)
return
}
_ = try await self.appendOutcomeValues(
values,
- event: event,
- store: careStore
+ event: event
)
}
- func updateEvent(
- _ event: OCKAnyEvent,
- with outcome: OCKOutcome?
+ func saveOutcome(
+ _ outcome: OCKAnyOutcome
) async throws {
- guard let outcome = outcome else {
- guard let task = event.task as? OCKAnyVersionableTask else {
- throw CareKitEssentialsError.errorString("Cannot make outcome for event: \(event)")
- }
- let outcome = OCKOutcome(
- taskUUID: task.uuid,
- taskOccurrenceIndex: event.scheduleEvent.occurrence,
- values: []
- )
- // Attempts to set the latest outcome values to an empty array.
- _ = try await careStore.deleteAnyOutcome(outcome)
- return
- }
_ = try await careStore.addAnyOutcome(outcome)
}
@@ -98,22 +84,20 @@ public extension CareKitEssentialView {
/// Otherwise a new `OCKOutcome` is created with the respective outcome values.
func appendOutcomeValues(
_ values: [OCKOutcomeValue],
- event: OCKAnyEvent,
- store: OCKAnyStoreProtocol
+ event: OCKAnyEvent
) async throws {
// Update the outcome with the new value
guard var outcome = event.outcome else {
let outcome = createOutcomeWithValues(
values,
- event: event,
- store: store
+ event: event
)
- _ = try await store.addAnyOutcome(outcome)
+ _ = try await careStore.addAnyOutcome(outcome)
return
}
outcome.values.append(contentsOf: values)
- _ = try await store.updateAnyOutcome(outcome)
+ _ = try await careStore.updateAnyOutcome(outcome)
return
}
@@ -124,18 +108,13 @@ public extension CareKitEssentialView {
/// - Note: Setting `values` to an empty array will delete the current `OCKOutcome` if it currently exists.
func saveOutcomeValues(
_ values: [OCKOutcomeValue],
- event: OCKAnyEvent,
- store: OCKAnyStoreProtocol
+ event: OCKAnyEvent
) async throws {
// Check if outcome values need to be updated.
guard !values.isEmpty else {
// If the event has already been completed
- guard let oldOutcome = event.outcome else {
- return
- }
- // Delete the outcome, and create a new one.
- _ = try await store.deleteAnyOutcome(oldOutcome)
+ try await deleteEventOutcome(event)
return
}
@@ -144,15 +123,14 @@ public extension CareKitEssentialView {
// Create a new outcome with the new values.
let outcome = createOutcomeWithValues(
values,
- event: event,
- store: store
+ event: event
)
- _ = try await store.addAnyOutcome(outcome)
+ _ = try await careStore.addAnyOutcome(outcome)
return
}
// Update the outcome with the new values.
currentOutcome.values = values
- _ = try await store.updateAnyOutcome(currentOutcome)
+ _ = try await careStore.updateAnyOutcome(currentOutcome)
}
/// Create an outcome for an event with the given outcome values.
@@ -160,8 +138,7 @@ public extension CareKitEssentialView {
/// - values: The outcome values to attach to the outcome.
func createOutcomeWithValues(
_ values: [OCKOutcomeValue],
- event: OCKAnyEvent,
- store: OCKAnyStoreProtocol
+ event: OCKAnyEvent
) -> OCKAnyOutcome {
let outcome = OCKOutcome(
taskUUID: event.task.uuid ,
diff --git a/Sources/CareKitEssentials/Cards/iOS/LabeledValueTaskView.swift b/Sources/CareKitEssentials/Cards/iOS/LabeledValueTaskView.swift
index dad9131a..3eb14578 100644
--- a/Sources/CareKitEssentials/Cards/iOS/LabeledValueTaskView.swift
+++ b/Sources/CareKitEssentials/Cards/iOS/LabeledValueTaskView.swift
@@ -22,8 +22,10 @@ public extension LabeledValueTaskView where Header == InformationHeaderView {
/// - Parameters:
/// - event: The data that appears in the view.
/// - numberFormatter: An object that formats the progress and target values.
- init(event: CareStoreFetchedResult,
- numberFormatter: NumberFormatter? = nil) {
+ init(
+ event: CareStoreFetchedResult,
+ numberFormatter: NumberFormatter? = nil
+ ) {
let currentEvent = event.result