Good morning everyone - hope everyone is doing well!
I am learning to use ResearchKit and CareKit from the WWDC code-along. The pre-completed code-along file works great. The way they have it set up is there is a survey with a couple of sliding scale questions that when completed are stored in the CareKit Store and are extracted to complete the rings at the top of the app to show the person has completed the surveys for the day.
Now, I am trying to add a ORKTextChoice survey (multiple choice) to the code-along scale questions. So far I have been able to add in the ORKTextChoice survey to the existing scale questions. I can open the survey and select the answer choice; however when I click Done, I think the app tries to extract the answers from the ORKTextChoice to fill the ring I am getting an error.
else {
assertionFailure("Failed to extract answers from check in survey!")
return nil
}
> Thread 1: Fatal error: Failed to extract answers from check in survey!
Additionally, what I am trying to do here is to have multiple choice questions that store into CareKit as a number (where it says (in bold): ORKTextChoice(text: "Home oxygen use", value: 0 as NSNumber)) value so that later I can create a chart of the numbers based on the answer responses.
This is where I am getting the error (towards the very bottom of the full code below):
static let checkInIdentifier = "checkin"
static let checkInFormIdentifier = "checkin.form"
static let checkInPainItemIdentifier = "checkin.form.pain"
static let checkInSleepItemIdentifier = "checkin.form.sleep"
static let checkInSleepItemIdentifier2 = "checkin.form.sleep2"
static let TextChoiceQuestionStep = "checkin.form.sleep3"
static func checkInSurvey() -> ORKTask {
let painAnswerFormat = ORKAnswerFormat.scale(
withMaximumValue: 10,
minimumValue: 1,
defaultValue: 0,
step: 1,
vertical: false,
maximumValueDescription: "Very painful",
minimumValueDescription: "No pain"
)
let sleepAnswerFormat = ORKAnswerFormat.scale(
withMaximumValue: 12,
minimumValue: 0,
defaultValue: 0,
step: 1,
vertical: false,
maximumValueDescription: nil,
minimumValueDescription: nil
)
let sleepAnswerFormat2 = ORKAnswerFormat.scale(
withMaximumValue: 12,
minimumValue: 0,
defaultValue: 0,
step: 1,
vertical: false,
maximumValueDescription: nil,
minimumValueDescription: nil
)
let breathingChoices = [
ORKTextChoice(text: "Home oxygen use", value: 0 as NSNumber),
ORKTextChoice(text: "Cystic fibrosis", value: 1 as NSNumber),
ORKTextChoice(text: "Chronic lung disease", value: 2 as NSNumber),
]
let breathingAnswerFormat = ORKAnswerFormat.choiceAnswerFormat(
with: .singleChoice, //<-- .multipleChoice can allow for multiple options selected
textChoices: breathingChoices
)
let painItem = ORKFormItem(
identifier: checkInPainItemIdentifier,
text: "How would you rate your pain?",
answerFormat: painAnswerFormat
)
painItem.isOptional = false
let sleepItem = ORKFormItem(
identifier: checkInSleepItemIdentifier,
text: "How many hours of sleep did you get last night?",
answerFormat: sleepAnswerFormat
)
sleepItem.isOptional = false
let sleepItem2 = ORKFormItem(
identifier: checkInSleepItemIdentifier2,
text: "How many hours of sleep did you get last night2?",
answerFormat: sleepAnswerFormat2
)
sleepItem2.isOptional = false
let breathingStep = ORKFormItem(
identifier: TextChoiceQuestionStep,
text: "What of the following apply to your child's current breathing condition? (check all that apply)",
answerFormat: breathingAnswerFormat
)
breathingStep.isOptional = false
let formStep = ORKFormStep(
identifier: checkInFormIdentifier,
title: "Check In",
text: "Please answer the following questions."
)
formStep.formItems = [painItem, sleepItem, sleepItem2, breathingStep]
formStep.isOptional = false
let surveyTask = ORKOrderedTask(
identifier: checkInIdentifier,
steps: [formStep]
)
return surveyTask
}
static func extractAnswersFromCheckInSurvey(
_ result: ORKTaskResult) -> [OCKOutcomeValue]? {
guard
let response = result.results?
.compactMap({ $0 as? ORKStepResult })
.first(where: { $0.identifier == checkInFormIdentifier }),
let scaleResults = response
.results?.compactMap({ $0 as? ORKScaleQuestionResult }),
let painAnswer = scaleResults
.first(where: { $0.identifier == checkInPainItemIdentifier })?
.scaleAnswer,
let sleepAnswer = scaleResults
.first(where: { $0.identifier == checkInSleepItemIdentifier })?
.scaleAnswer,
let breathAnswer = scaleResults
.first(where: { $0.identifier == TextChoiceQuestionStep })?
.scaleAnswer
else {
assertionFailure("Failed to extract answers from check in survey!")
return nil
}
var painValue = OCKOutcomeValue(Double(truncating: painAnswer))
painValue.kind = checkInPainItemIdentifier
var sleepValue = OCKOutcomeValue(Double(truncating: sleepAnswer))
sleepValue.kind = checkInSleepItemIdentifier
var breathValue = OCKOutcomeValue(Double(truncating: breathAnswer))
sleepValue.kind = checkInSleepItemIdentifier
return [painValue, sleepValue, breathValue]
}
For reference, here is the code-along: https://developer.apple.com/videos/play/wwdc2021/10068/
Here is the Git with the code-along code: https://github.com/carekit-apple/WWDC21-RecoverApp
The ORKTextChoice survey questions (ie. Home oxygen use, etc.) came from here: https://github.com/ResearchKit/ResearchKit/issues/919
I appreciate any help and guidance any of you can provide - Thank you!