-
Notifications
You must be signed in to change notification settings - Fork 443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How do you save an CareKit OCKOutcomeValue for an array of ResearchKit ORKChoiceQuestionResults #680
Comments
In ResearchKit, each step in a survey will generate a particular result type. The result type in the WWDC sample app is different than the one you're dealing with here, so there will be a few extra steps needed to convert that to an OCKOutcomeValue. The first step is to extract the selected text choices from the result. You're just about there in the snippet above. let selectedChoices = results
.first { $0.identifier == ChoiceQuestion1Step }?
.choiceAnswers as! [ORKTextChoice] The next step is to convert each selected choice to an outcome value. let outcomesValues = selectedChoices
.map { OCKOutcomeValue($0.value as! String) } Let me know if that works for you! |
HI Gavi! Thank you for getting back to me (it really means a lot!!), you're from the WWDC 2020 What's New in CareKit - so awesome, it's a pleasure and thank you for the insight! I'll give this a try and see what happens. Out of curiosity, does the suggestion you provided use the string value (seen below: "None", "Slight", "Moderate", "Severe") or number value associated (ie. value: 0,1,2,3) with the ORKTextChoice questions (.singleChoice )? I'm sorry if I wasn't direct or as I didn't specifically say that, what I was looking to do is use the value of the response for insights, so in the example above "3" would be what I want to track. For example, when looking at the answer choices:
....if the person taking the assessment selects "Severe", value: 3, I want the "3" to be what is extracted from the results to be persisted to the CareKit Store for creating insights. Is that what your suggestion will do? Is it possible to do this?? Thank you! |
Ah I see! Yep that's possible as well. If the value is an /// Any value that can be persisted to `OCKStore` must conform to this protocol.
public protocol OCKOutcomeValueUnderlyingType: Codable {}
extension Int: OCKOutcomeValueUnderlyingType {}
extension Double: OCKOutcomeValueUnderlyingType {}
extension Bool: OCKOutcomeValueUnderlyingType {}
extension String: OCKOutcomeValueUnderlyingType {}
extension Data: OCKOutcomeValueUnderlyingType {}
extension Date: OCKOutcomeValueUnderlyingType {} To convert an |
I hope I'm doing this right, I tried:
This gave me the line error of: I feel that I might not be doing something right... |
You're very close! It's a tricky process. The ORKTextChoice(text: "None", value: 0 as NSNumber) Then you'll need to convert the values to let selectedChoices = results
.first { $0.identifier == ChoiceQuestion1Step }?
.choiceAnswers as! [ORKTextChoice]
let outcomesValues = selectedChoices
// Convert the choice values to `NSNumber`s
.map { $0.value as! NSNumber }
// Convert the choice values to CareKit outcome values
.map { OCKOutcomeValue(Double(truncating: $0)) } |
I wanted to add to the above post. I have Aspergers and sometimes struggle explaining things concisely and in ways others understand. I'm not sure if the last post made sense, and I think I have the code added in all of the right places now and am getting some errors with the solutions provided (not sure about the last post, I think the code from the last post may not have been accurate). In the photos below I start from where I have just added the suggestion, I show the error, correct it, and lastly (on no. 4) show the error from trying it out: This is after I correct errors seen in #1-3 and run the app in the simulator, select Is it possible that it has something to do with the CareFeedView Controller as well?? I'm not getting an error there, and this is what it looks like: Thank you!! PS - I have added the full code below of the Surveys.swift file to compliment the photos, in case it helps for big picture context:
|
No worries at all! All of this info is super helpful and helps me run the issue locally to help us solve it. It looks like I gave you the wrong info earlier, apologies! Turns out the result object contains a list of static func extractAnswersFromChoiceSurvey(
_ 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 }),
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
}
// Convert the choice values to CareKit outcome values
let outcomeValues = selectedChoices
.map { OCKOutcomeValue(Double(truncating: $0)) }
return outcomeValues
} |
The error you're seeing here is happening because static func extractAnswersFromChoiceSurvey(
_ 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 }),
let selectedChoices = scale2Results
.first(where: { $0.identifier == ChoiceQuestion1Step })?
.choiceAnswers as? [NSNumber]
else {
assertionFailure("Failed to extract answers from check in survey!")
return nil
}
// Convert the choice values to CareKit outcome values
let outcomeValues = selectedChoices.map { selectedChoice -> OCKOutcomeValue in
var outcomeValue = OCKOutcomeValue(Double(truncating: selectedChoice))
// Set the kind here!
outcomeValue.kind = ChoiceQuestionStep
return outcomeValue
}
return outcomeValues
} |
Hi Gavi! It works!! Thank you so much for all of your help - you've been great!! :) |
Glad to hear it! |
Good day!
I have been following the WWDC 21 hosted by @erik-apple and it's been really great! I had a question and wasn't sure where else would be a good place as I believe it is a CareKit issue (not 100% and still fairly new here). I see that Erik helps out on here and was hoping he, or someone, could help with something pertaining to CareKit in Part 2 of the WWDC.
I have successfully created two ResearchKit ORKTextChoice questions (.singleChoice ) and I'm trying to pass them to CareKit like Erik does with the ORKScaleQuestionResult (.scaleAnswer). Example from my code:
I was able to modify Erik's code from WWDC to extract the answers:
Note: After running the app and submitting the ORKTextChoice answer responses in the simulator, when I go back over to Xcode I can see the correct answer choice when I hover over both "choiceAnswer" and "choiceAnswer2". I take as meaning the code works for extracting the answer choices. This can be seen in the output terminal as well:
Printing description of choiceAnswer: ([NSCoding & NSCopying & NSObject]) choiceAnswer = 1 value { [0] = 0x99d102272eb2af4b Int64(3) } Printing description of ((__NSCFNumber *)0x99d102272eb2af4b): 3
...where "3" at the very end is the value from the ORKTextChoice "choiceAnswer".
In Erik's tutorial the next step is to pass the ResearchKit ORKScaleQuestionResult to a CareKit OCKOutcomeValue using the following code:
I have tried for days to pass the ResearchKit ORKTextChoice to CareKit and Xcode corrected the code to what you see below but still crashes with
Thread 1: signal SIGABRT
on the following line of code:var Value2 = OCKOutcomeValue(NSNumber(pointer: choiceAnswer) as! OCKOutcomeValueUnderlyingType) Value.kind = Question1Step
I have a feeling that the error has something to do with this part of the above code:
OCKOutcomeValue(NSNumber(pointer:
and/oras! OCKOutcomeValueUnderlyingType)
as I get the terminal error:Could not cast value of type 'NSConcreteValue' (0x15e0dcf38) to 'CareKitStore.OCKOutcomeValueUnderlyingType' (0x15e0d9ad0)
As mentioned I have been searching for days and haven't found anything helpful. I am hoping that someone may have some guidance and I would be very grateful! :)
Thank you!
PS - I was trying to be concise, so if more explanation or code is needed, please let me know!
The text was updated successfully, but these errors were encountered: