Skip to content

ORKTextChoice + ORKPredicateStepNavigationRule + CareKit + ResearchKit #681

@InfuriatingYetti

Description

@InfuriatingYetti

Good day @gavirawson-apple - hope you're doing well!

I tagged you because this question is an extension from the last question you helped me with (found here: [https://github.com//issues/680]), and anyone who may be able to help is more more than welcome! :)

I was reading about a feature called ORKPredicateStepNavigationRule and was trying to implement it in the previous code we were working on. I came up with the following code below...it sort of works in that it isn't throwing any codes and allows me to persist the data to CareKit Store and doesn't work because it isn't navigating to the second survey.

Going back to the survey you helped me on, if the person were to select an answer greater than value: 0 in the ORKTextChoice(text: "None", value: 0 as NSNumber) I am wanting to have it take them to another set of questions that is a part of another survey on another form, but only once the complete the first form.

First question, is it possible to do this with the layout design seen in @erik-apple 's WWDC 21 + what we worked on previously? If so, I can keep trying...going in I was taking the Han Solo approach:

What happens is after I select an answer response and click Done it closes it like normal. I was thinking it either:

a) What I'm trying can't be done the way I'm trying to do it
b) The form is closing before it can run to the code to open the second survey, either in the current or new window
c) There is a step missing and I somehow need to have the first survey persist to CareKit and from CareKit somehow make it open the second survey.
d) ...
photofunny net__final_3814458426951396812_origen

If seeing the code helps, this is what I've tried, again looking to have it both persist the answers from the first form to CareKit Store and also automatically go to another based on the answer response from the question once the first survey is complete:

 `import CareKitStore
import ResearchKit

struct ChoiceQuestions {
    
    static let choiceIdentifier = "choice"
    static let choiceFormIdentifier = "choice.form"
    static let ChoiceQuestion1Step = "checkin.form.choicequestion1"
    static let ChoiceQuestionStep = "checkin.form.Choice"
    
    static let choice2Identifier = "choice2"
    static let choice2FormIdentifier = "choice2.form"
    static let Choice2Question1Step = "checkin.form.choice2question1"
    static let Choice2QuestionStep = "checkin.form.Choice2"
    
    static func Choices1() -> ORKNavigableOrderedTask {
        
        let Choices = [
            ORKTextChoice(text: "None", value: 0 as NSNumber),
            ORKTextChoice(text: "Slight", value: 1 as NSNumber),
            ORKTextChoice(text: "Mild", value: 2 as NSNumber),
            ORKTextChoice(text: "Severe", value: 3 as NSNumber),
        ]
        
        let choiceAnswerFormat = ORKAnswerFormat.choiceAnswerFormat(with: .singleChoice, textChoices: Choices)
        
        let choiceStep = ORKFormItem(identifier: ChoiceQuestion1Step, text: "Text question goes here", answerFormat: choiceAnswerFormat)
        choiceStep.isOptional = false
        
        let formStep = ORKFormStep(identifier: choiceFormIdentifier, title: "Choice Question", text: "Instructions for questions")
        formStep.formItems = [choiceStep]
        formStep.isOptional = false
        
        let expectedAnswerValuesMild: [NSNumber] = [2]
        let expectedAnswerValuesSevere: [NSNumber] = [3]
        let predicateMild = ORKResultPredicate.predicateForChoiceQuestionResult(with: ORKResultSelector(resultIdentifier: ChoiceQuestion1Step), expectedAnswerValues: expectedAnswerValuesMild)
        let predicateSevere = ORKResultPredicate.predicateForChoiceQuestionResult(with: ORKResultSelector(resultIdentifier: ChoiceQuestion1Step), expectedAnswerValues: expectedAnswerValuesSevere)
        
        let navigationRule = ORKPredicateStepNavigationRule(
            resultPredicatesAndDestinationStepIdentifiers: [
                (predicateMild, Choice2QuestionStep),
                (predicateSevere, Choice2QuestionStep)
            ])
        
        let task = ORKNavigableOrderedTask(identifier: choiceIdentifier, steps: [formStep])
        task.setNavigationRule(navigationRule, forTriggerStepIdentifier: ChoiceQuestion1Step)
        
        return task
    }
    
    static func extractAnswersFromNav(
        _ result: ORKTaskResult) -> [OCKOutcomeValue]? {
            
            guard
                let choiceResult = result.results?
                    .compactMap({ $0 as? ORKStepResult })
                    .first(where: { $0.identifier == choiceFormIdentifier }),
                
                    let scale2Results = choiceResult
                    .results?
                    .compactMap({ $0 as? ORKChoiceQuestionResult }),
//1
                    let selectedChoices = scale2Results
                    .first(where: { $0.identifier == ChoiceQuestion1Step })?
                    // This line was the key!
                    .choiceAnswers as? [NSNumber]
                    
                    
            else {
                assertionFailure("Failed to extract answers from check in survey!")
                return nil
            }
            
            
            //1
                       // Convert the choice values to CareKit outcome values
                       let outcomeValue = selectedChoices.map { selectedChoice -> OCKOutcomeValue in

                               var outcomeValue = OCKOutcomeValue(Double(truncating: selectedChoice))
                       
                       // Set the kind here!
                       outcomeValue.kind = ChoiceQuestion1Step
                       
                       return outcomeValue
                   }
    
            // Convert the choice values to CareKit outcome values
            let outcomeValue1 = selectedChoices.map { selectedChoice -> OCKOutcomeValue in

                    var outcomeValue1 = OCKOutcomeValue(Double(truncating: selectedChoice))
            
            // Set the kind here!
             outcomeValue1.kind = ChoiceQuestion1Step
            
            return outcomeValue1
        }
             

                 return outcomeValue1
             }
            
    
    static func Choices2() -> ORKTask {
        
        let Choices2 = [
            ORKTextChoice(text: "None", value: 0 as NSNumber),
            ORKTextChoice(text: "Slight", value: 1 as NSNumber),
            ORKTextChoice(text: "Mild", value: 2 as NSNumber),
            ORKTextChoice(text: "Severe", value: 3 as NSNumber),
        ]
        
        let choiceAnswerFormat2 =  ORKAnswerFormat.choiceAnswerFormat(with: .singleChoice, textChoices: Choices2)
        
        let choice2Step = ORKFormItem(identifier: Choice2Question1Step, text: "Text question goes here", answerFormat: choiceAnswerFormat2)
        choice2Step.isOptional = false
        
        let form2Step = ORKFormStep(identifier: choice2FormIdentifier, title: "Choice Question", text: "Instructions for questions")
        form2Step.formItems = [choice2Step]
        form2Step.isOptional = false
        
        let task = ORKOrderedTask(identifier: choice2Identifier, steps: [form2Step])
        
        return task
    }
}

`

I have also tried creating a second swift file, whereas it would open the second from second file automatically based on the answer response and once the first survey was submitted - did the same thing, it submits the first survey and doesn't open the second.

Do you think what I am trying to do is possible, or do I need a different approach?!

Thank you for your help!!

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