WWDC ResearchKit + CareKit - Thread 1: Fatal error: Failed to extract answers from check in survey

59 views Asked by At

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!

0

There are 0 answers