From f25580e95bfdad02383980dcb94406cf97b08ea8 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Fri, 23 Feb 2024 22:23:09 -0800 Subject: [PATCH] Replace ORKOrderedTaskView with new ResearchKit one (#23) # Replace ORKOrderedTaskView with new ResearchKit one ## :recycle: Current situation & Problem This PR updates to our latest version of ResearchKit and replaces the internal `ORKOrderedTaskView` implementation with the new one available in `ResearchKitSwiftUI`. ## :gear: Release Notes * Updated to new ResearchKit version ## :books: Documentation -- ## :white_check_mark: Testing -- ## :pencil: Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md). --- Package.swift | 7 +- .../ORKOrderedTaskView.swift | 89 ------------------- .../QuestionnaireView.swift | 24 +++-- 3 files changed, 22 insertions(+), 98 deletions(-) delete mode 100644 Sources/SpeziQuestionnaire/ORKOrderedTaskView.swift diff --git a/Package.swift b/Package.swift index 9ea9c87..9fea6e3 100644 --- a/Package.swift +++ b/Package.swift @@ -22,8 +22,8 @@ let package = Package( dependencies: [ .package(url: "https://github.com/StanfordSpezi/Spezi", from: "1.0.0"), .package(url: "https://github.com/apple/FHIRModels", .upToNextMinor(from: "0.5.0")), - .package(url: "https://github.com/StanfordBDHG/ResearchKit", from: "2.2.21"), - .package(url: "https://github.com/StanfordBDHG/ResearchKitOnFHIR", from: "1.0.0") + .package(url: "https://github.com/StanfordBDHG/ResearchKit", from: "2.2.25"), + .package(url: "https://github.com/StanfordBDHG/ResearchKitOnFHIR", from: "1.1.0") ], targets: [ .target( @@ -33,7 +33,8 @@ let package = Package( .product(name: "ModelsR4", package: "FHIRModels"), .product(name: "ResearchKitOnFHIR", package: "ResearchKitOnFHIR"), .product(name: "FHIRQuestionnaires", package: "ResearchKitOnFHIR"), - .product(name: "ResearchKit", package: "ResearchKit") + .product(name: "ResearchKit", package: "ResearchKit"), + .product(name: "ResearchKitSwiftUI", package: "ResearchKit") ] ), .testTarget( diff --git a/Sources/SpeziQuestionnaire/ORKOrderedTaskView.swift b/Sources/SpeziQuestionnaire/ORKOrderedTaskView.swift deleted file mode 100644 index 8eabd5e..0000000 --- a/Sources/SpeziQuestionnaire/ORKOrderedTaskView.swift +++ /dev/null @@ -1,89 +0,0 @@ -// -// This source file is part of the Stanford Spezi open-source project -// -// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) -// -// SPDX-License-Identifier: MIT -// - -import ModelsR4 -import ResearchKit -import ResearchKitOnFHIR -import Spezi -import SwiftUI -import UIKit - - -struct ORKOrderedTaskView: UIViewControllerRepresentable { - class Coordinator: NSObject, ORKTaskViewControllerDelegate, ObservableObject { - private let result: @MainActor (QuestionnaireResult) async -> Void - - - init(result: @escaping @MainActor (QuestionnaireResult) async -> Void) { - self.result = result - } - - - func taskViewController( - _ taskViewController: ORKTaskViewController, - didFinishWith reason: ORKTaskViewControllerFinishReason, - error: Error? - ) { - _Concurrency.Task { @MainActor in - switch reason { - case .completed: - let fhirResponse = taskViewController.result.fhirResponse - fhirResponse.subject = Reference(reference: FHIRPrimitive(FHIRString("My Patient"))) - - await result(.completed(fhirResponse)) - case .discarded, .earlyTermination: - await result(.cancelled) - case .failed: - await result(.failed) - case .saved: - break // we don't support that currently - @unknown default: - break - } - } - } - } - - - private let tasks: ORKOrderedTask - private let tintColor: Color - private let questionnaireResponse: @MainActor (QuestionnaireResult) async -> Void - - - /// - Parameters: - /// - tasks: The `ORKOrderedTask` that should be displayed by the `ORKTaskViewController` - /// - result: A closure receiving the ``QuestionnaireResult`` for the task view. - /// - tintColor: The tint color to use with ResearchKit views - init( - tasks: ORKOrderedTask, - result: @escaping @MainActor (QuestionnaireResult) async -> Void, - tintColor: Color = Color(UIColor(named: "AccentColor") ?? .systemBlue) - ) { - self.tasks = tasks - self.tintColor = tintColor - self.questionnaireResponse = result - } - - - func makeCoordinator() -> Coordinator { - Coordinator(result: questionnaireResponse) - } - - func updateUIViewController(_ uiViewController: ORKTaskViewController, context: Context) { - uiViewController.view.tintColor = UIColor(tintColor) - uiViewController.delegate = context.coordinator - } - - func makeUIViewController(context: Context) -> ORKTaskViewController { - // Create a new instance of the view controller and pass in the assigned delegate. - let viewController = ORKTaskViewController(task: tasks, taskRun: nil) - viewController.view.tintColor = UIColor(tintColor) - viewController.delegate = context.coordinator - return viewController - } -} diff --git a/Sources/SpeziQuestionnaire/QuestionnaireView.swift b/Sources/SpeziQuestionnaire/QuestionnaireView.swift index 31d3db2..2c88030 100644 --- a/Sources/SpeziQuestionnaire/QuestionnaireView.swift +++ b/Sources/SpeziQuestionnaire/QuestionnaireView.swift @@ -11,6 +11,7 @@ import ModelsR4 import OSLog import ResearchKit import ResearchKitOnFHIR +import ResearchKitSwiftUI import SwiftUI @@ -45,11 +46,7 @@ public struct QuestionnaireView: View { public var body: some View { if let task = createTask(questionnaire: questionnaire) { - ORKOrderedTaskView( - tasks: task, - result: questionnaireResult, - tintColor: .accentColor - ) + ORKOrderedTaskView(tasks: task, tintColor: .accentColor, result: handleResult) .ignoresSafeArea(.container, edges: .bottom) .ignoresSafeArea(.keyboard, edges: .bottom) .interactiveDismissDisabled() @@ -72,7 +69,22 @@ public struct QuestionnaireView: View { self.completionStepMessage = completionStepMessage self.questionnaireResult = questionnaireResult } - + + private func handleResult(_ result: TaskResult) async { + let questionnaireResult: QuestionnaireResult + switch result { + case let .completed(result): + let fhirResponse = result.fhirResponse + questionnaireResult = .completed(result.fhirResponse) + case .cancelled: + questionnaireResult = .cancelled + case .failed: + questionnaireResult = .failed + } + + await self.questionnaireResult(questionnaireResult) + } + /// Creates a ResearchKit navigable task from a questionnaire /// - Parameter questionnaire: a questionnaire