WWDC Quick Look 💓 By SwiftGGTeam
What's new in ResearchKit

What's new in ResearchKit

观看原视频

Highlight

ResearchKit 2020 更新把知情同意签名、HealthKit 权限请求、问卷复核、3D 模型展示和自定义 active task 接入同一套研究任务流程,开发者可以用更少自建界面采集更准确的研究数据。

核心内容

医学研究 App 的第一关通常是流程,而不只是算法。参与者要看懂研究目的,完成知情同意,授权健康数据,回答问卷,再做一些主动任务。每一步都需要解释、输入、校验和结果保存。以前开发者经常要在 ResearchKit 外面补一层自定义界面,把授权、签名、复核和多媒体交互串起来。

这场 session 展示的变化,是把这些断点收回到 ResearchKit 的 task flow 里。ORKInstructionStep 可以承载更丰富的说明内容,ORKWebViewStep 可以在同一个 HTML 同意书页面下方收集签名,新的 HealthKit permission step 把健康数据授权放进研究流程,问卷增加“不知道”选项、字符数提示、清除按钮和复核页面。(02:54

后半场继续扩展 active task 的边界。研究 App 可以用 ORK3DModelStep 展示 USDZ 或 BioDigital 3D 人体模型,用视觉方式解释身体部位和病灶;开发者也可以从 ORKActiveStep 开始实现自己的前置摄像头任务,采集视频文件、记录重试次数,再把结果交回 ORKTaskViewController。(12:24

ResearchKit 在这里承担的是研究流程的骨架。开发者仍然决定研究内容、模型素材和结果处理方式,但不必为每个常见环节重写一套界面。参与者看到的是连续任务,研究团队得到的是结构化结果。

详细内容

Onboarding:用 instruction step 和 web view step 降低加入门槛

03:24)研究 App 的 onboarding(加入流程)要先讲清楚研究是什么。Session 用 ORKInstructionStep 创建欢迎页,设置标题、说明文字和图片。

let instructionStep = ORKInstructionStep(identifier: "InstructionStepIdentifier")
instructionStep.title = "Welcome!"
instructionStep.detailText = "Thank you for joining our study. Tap Next to learn more before signing up."
instructionStep.image =  UIImage(named: "health_blocks")!

关键点:

  • ORKInstructionStep 是 ResearchKit 中用于说明内容的 step。
  • identifier 给这一步一个稳定标识,后续结果和流程都依赖它。
  • titledetailText 负责解释当前步骤的目的。
  • image 让研究说明不只是一段文字,适合放研究主题图或引导图。

04:08)同一个 instruction step 还能加入 ORKBodyItem。演示用 SF Symbols 的心形图标,把知情同意前的说明拆成更容易扫读的项目。

let informedConsentInstructionStep = ORKInstructionStep(identifier: "ConsentStepIdentifier")
informedConsentInstructionStep.title = "Before You Join"
informedConsentInstructionStep.image = UIImage(named: "informed_consent")!

let heartBodyItem = ORKBodyItem(text: exampleText,
                                detailText: nil,
                                image: UIImage(systemName: "heart.fill"),
                                learnMoreItem: nil,
                                bodyItemStyle: .image)

informedConsentInstructionStep.bodyItems = [heartBodyItem]

关键点:

  • ORKBodyItem 把一条说明内容、图标和样式封装成可复用项目。
  • UIImage(systemName:) 说明这里可以直接使用 SF Symbols。
  • bodyItemStyle: .image 让图标按图片样式显示。
  • bodyItems 是数组,适合把风险、收益、数据用途拆成多条说明。

05:04)知情同意的签名也被合并进 ORKWebViewStep。过去展示同意书和收集签名需要两个步骤;现在设置一个属性,就能在 HTML 内容下方显示签名区。

let webViewStep = ORKWebViewStep(identifier: String(describing: Identifier.webViewStep), html: exampleHtml)
webViewStep.showSignatureAfterContent = true

关键点:

  • ORKWebViewStep 负责展示 HTML 格式的同意书或说明文档。
  • html 参数传入要展示的内容。
  • showSignatureAfterContent = true 会在内容后显示签名视图。
  • 参与者在一个页面里读完文档并签名,流程更短,也少一个自定义界面。

05:25)HealthKit 授权也进入 onboarding。Transcript 明确提到新的 request permission step:开发者传入想写入的 HKSampleType 集合和想读取的 HKObjectType 集合,创建 ORKHealthKitPermissionType,再放入 ORKHealthKitPermissionStep。这样,健康数据授权不用跳出 ResearchKit 流程单独实现。

HealthKit permission flow in ResearchKit
1. Create a set of HKSampleTypes for data the app wants write access to.
2. Create a set of HKObjectTypes for data the app wants read access to.
3. Create ORKHealthKitPermissionType with those two sets.
4. Create ORKHealthKitPermissionStep with the permission type array.

关键点:

  • HKSampleType 对应写入权限,适合研究 App 保存采集到的健康样本。
  • HKObjectType 对应读取权限,适合读取已有健康数据作为研究上下文。
  • ORKHealthKitPermissionType 把读写类型合在一起。
  • ORKHealthKitPermissionStep 把系统授权请求放进 ResearchKit task flow。

Survey:减少无效答案,允许参与者复核

07:43)问卷部分新增 ORKSESAnswerFormat。它适合展示阶梯式量表,让参与者在“Optimal Health”和“Poor Health”之间选择更贴近自己的状态。

let sesAnswerFormat = ORKSESAnswerFormat(topRungText: "Optimal Health",
                                         bottomRungText: "Poor Health")

let sesFormItem = ORKFormItem(identifier: "sesIdentifier",
                                      text: exampleText,
                                      answerFormat: sesAnswerFormat)

关键点:

  • ORKSESAnswerFormat 负责阶梯式量表问题。
  • topRungTextbottomRungText 定义量表两端的语义。
  • ORKFormItem 把问题文本和答案格式组合进表单。
  • 这类问题适合主观健康状态、生活质量或自评量表。

08:47)量表问题还新增了“不知道”按钮。研究场景里,强迫参与者回答一个不确定问题,会制造噪声。shouldShowDontKnowButtoncustomDontKnowButtonText 让参与者明确表达无法回答。

let scaleAnswerFormat = ORKScaleAnswerFormat(maximumValue: 10, minimumValue: 1, defaultValue: 11, step: 1)
scaleAnswerFormat.shouldShowDontKnowButton = true
scaleAnswerFormat.customDontKnowButtonText = "Prefer not to answer"

let scaleAnswerFormItem = ORKFormItem(identifier: "ScaleAnswerFormItemIdentifier",
                                      text: "What is your current pain level?",
                                      answerFormat: scaleAnswerFormat)

关键点:

  • ORKScaleAnswerFormat 定义 1 到 10 的疼痛程度量表。
  • shouldShowDontKnowButton = true 显示“不知道”入口。
  • customDontKnowButtonText 可以替换默认文案,适合隐私敏感问题。
  • ORKFormItem 把这个答案格式绑定到具体问题。

09:47)自由文本输入也有更新。Session 提到最大字符数提示和清除按钮,目的是让参与者知道还能输入多少内容,也能快速清空重写。

let textAnswerFormat = ORKAnswerFormat.textAnswerFormat()
textAnswerFormat.multipleLines = true
textAnswerFormat.maximumLength = 280;
textAnswerFormat.hideWordCountLabel = false
textAnswerFormat.hideClearButton = false

关键点:

  • textAnswerFormat() 创建文本答案格式。
  • multipleLines = true 允许长文本回答。
  • maximumLength = 280 限制输入长度。
  • hideWordCountLabel = false 显示字符数提示。
  • hideClearButton = false 显示清除按钮。

11:00)问卷提交前,ORKReviewViewController 让参与者查看所有问题和回答,并通过 edit 更新答案。Session 把它放在“提高数据准确性”的场景里:人会填错,系统应该给一次检查机会。

let reviewVC = ORKReviewViewController(task: taskViewController.task,
                                       result: taskViewController.result,
                                       delegate: self)
reviewVC.reviewTitle = "Review your response"
reviewVC.text = "Please take a moment to review your responses below. If you need to change any answers just tap the edit button to update your response."

关键点:

  • taskViewController.task 提供原始任务结构。
  • taskViewController.result 提供当前已经收集到的回答。
  • delegate: self 要求实现更新结果和选择未完成单元格相关方法。
  • reviewTitletext 负责解释复核页的用途。

Active Tasks:从听力任务到 3D 模型

11:48)ResearchKit 的 hearing task 更新偏向体验细节。环境 SPL meter 新增动画,用来提示背景噪声是否在阈值内;dB HL tone audiometry step 更新按钮、触觉反馈和进度显示,并加入 AirPods Pro 校准数据支持。这里没有官方代码片段,核心是减少听力测试过程中的误操作和不确定感。

Hearing task updates
- Environment SPL meter shows a clearer threshold animation.
- dB HL tone audiometry step updates button UI and haptics.
- Progress indicator changes to a label.
- Calibration data supports AirPods Pro.

关键点:

  • SPL meter 的动画帮助参与者判断测试环境是否合格。
  • 按钮和触觉反馈降低测试中的操作成本。
  • 文本式进度比抽象进度条更容易理解。
  • AirPods Pro 校准数据让这类硬件可以用于相关听力任务。

14:30)3D 模型是更大的能力扩展。ResearchKit 新增 ORK3DModelStepORKUSDZModelManager。开发者把 USDZ 文件加入 Xcode 项目,创建 model manager,再交给 3D step 展示。

let usdzModelManager = ORKUSDZModelManager(usdzFileName: "toy_drummer")
usdzModelManager.allowsSelection = false
usdzModelManager.highlightColor = .yellow
usdzModelManager.enableContinueAfterSelection = false
usdzModelManager.identifiersOfObjectsToHighlight = arrayOfIdentifiers

let threeDimensionalModelStep = ORK3DModelStep(identifier: drummerModelIdentifier,
                                               modelManager: usdzModelManager)

关键点:

  • ORKUSDZModelManager 读取项目中的 USDZ 模型。
  • allowsSelection 控制用户能否选择模型部件。
  • highlightColor 设置高亮颜色。
  • enableContinueAfterSelection 控制继续按钮是否依赖选择行为。
  • identifiersOfObjectsToHighlight 可以预先高亮模型中的指定对象。
  • ORK3DModelStep 把 model manager 接入 ResearchKit task flow。

15:31ORK3DModelManager 是抽象父类,Apple 明确希望社区继承它。Session 展示了 BioDigital 提供的 ORKBioDigitalModelManager:模型通过 web 加载,可以在管理后台或 SDK 中更新,还能添加标签、颜色和注释。演示场景包括让用户在人体模型上指出疼痛部位,以及用心脏模型解释冠状动脉堵塞位置。

BioDigital model manager workflow
1. Import ResearchKit and BioDigital's HumanKit.
2. Create an ORKBioDigitalModelManager instance.
3. Set inherited properties such as highlight color and identifiers to highlight.
4. Use BioDigital-specific APIs to hide objects, load a model ID, and annotate an object.
5. Create ORK3DModelStep with that manager.

关键点:

  • ORK3DModelManager 的职责是抽象 3D 模型体验所需的共同能力。
  • ORKBioDigitalModelManager 是社区扩展,不是 Apple 内置 USDZ 管理器。
  • web 加载模型的好处是内容更新不一定需要发新版 App。
  • 标签和注释适合医学教育、疼痛定位和医生解释检查结果。

自定义 active task:前置摄像头任务的结构

20:35)自定义 active task 的基本路径是:App 创建 ORKTask,把一组 step 交给 ORKTaskViewController 展示,完成后通过 delegate 拿到 ORKTaskResult。Session 的例子是前置摄像头任务,用户可以实时预览、开始录制、停止录制、复核视频并重试。

ResearchKit task roundtrip
1. The app creates an ORKTask object.
2. ORKTaskViewController receives the task and presents each step.
3. Each active step collects its own result.
4. ORKTaskViewControllerDelegate returns ORKTaskResult to the app.

关键点:

  • ORKTask 是一组 step 的集合。
  • ORKTaskViewController 负责展示 step,App 不需要继承它。
  • ORKTaskResult 汇总每个 step 的结果。
  • delegate 是 ResearchKit 回到业务代码的出口。

21:51)实现前置摄像头任务时,演讲者创建 ORKFrontFacingCameraStep,继承自 ORKActiveStep,并增加最大录制时长、是否允许复核、是否允许重试三个配置项。随后让这个 step 返回自己的 view controller class。

ORKFrontFacingCameraStep design
- subclass ORKActiveStep
- add maximumDuration
- add allowsReview
- add allowsRetry
- override stepViewControllerClass
- return ORKFrontFacingCameraStepViewController

关键点:

  • ORKActiveStep 适合需要传感器、计时、录音录像等主动采集的任务。
  • 配置项放在 step 上,便于 task 组装时决定这次任务的行为。
  • stepViewControllerClass 把数据模型和展示逻辑连接起来。
  • 自定义 view controller 继承 ORKActiveStepViewController

23:23)界面层使用自定义 UIView。它接收 AVCaptureSession 显示实时预览,向 view controller 回传按钮事件,并提供计时器和录制后选项。这里的重点是:摄像头代码仍由 App 管理,ResearchKit 给 active task 结果、流程和展示提供插槽。

Front-facing camera content view responsibilities
- receive AVCaptureSession
- set up an AVCaptureVideoPreviewLayer
- pass view events back through a block
- start a timer with the maximum duration
- show review and retry options before submission

关键点:

  • AVCaptureSession 仍然来自 AVFoundation。
  • 内容视图只负责预览、计时和交互事件。
  • 事件通过 block 回传,view controller 决定如何响应。
  • 复核和重试能力来自 step 配置,界面按配置显示选项。

24:46)结果层继承 ORKFileResult。例子中的 ORKFrontFacingCameraStepResult 记录视频文件 URL,还增加 retryCount,用于记录用户删除并重录的次数。view controller 覆盖 result 方法,把自定义结果追加到当前结果集合中。

Front-facing camera result
- subclass ORKFileResult
- store contentType
- store fileURL
- add retryCount
- append ORKFrontFacingCameraStepResult to the current results collection

关键点:

  • 视频是文件结果,用 ORKFileResult 更贴近数据形态。
  • fileURL 让 App 在 task 结束后找到录制文件。
  • retryCount 是研究中有价值的行为数据,可以反映任务难度或用户犹豫。
  • 覆盖 result 方法是把自定义采集数据交回 ResearchKit 的关键。

25:49)最后的 Xcode 演示把三个 step 串起来:欢迎用的 ORKInstructionStep,刚创建的 ORKFrontFacingCameraStep,结束用的 completion step。它们放入 ORKOrderedTask,再注入 ORKTaskViewController 并展示。完成后 delegate 读取自定义结果,打印录制文件 URL 和重试次数。

Demo task composition
1. Create an instruction step.
2. Create ORKFrontFacingCameraStep.
3. Set the maximum recording limit to 15 seconds.
4. Allow review and retry.
5. Add a completion step.
6. Create ORKOrderedTask with all steps.
7. Present ORKTaskViewController.
8. Read ORKFrontFacingCameraStepResult in the delegate.

关键点:

  • ORKOrderedTask 适合线性流程。
  • 15 秒上限、review 和 retry 都是前面 step 暴露的配置。
  • ORKTaskViewControllerDelegate 是处理完成、取消和失败的统一入口。
  • 自定义 active task 最终仍然遵守 ResearchKit 的 task-result 模型。

核心启发

  • 做什么:为慢病研究 App 做一个完整加入流程。 为什么值得做ORKInstructionStepORKBodyItemORKWebViewStep 和签名显示可以覆盖说明、同意书和签名。 怎么开始:先用 instruction step 写清研究目的,再用 web view step 展示 HTML 同意书,并把 showSignatureAfterContent 打开。

  • 做什么:把健康数据授权嵌入研究报名流程。 为什么值得做:新的 HealthKit permission step 让授权不必跳出 ResearchKit,自定义界面更少。 怎么开始:整理要写入的 HKSampleType 和要读取的 HKObjectType,创建 ORKHealthKitPermissionType,再放入 ORKHealthKitPermissionStep

  • 做什么:给症状问卷增加复核页和“不知道”选项。 为什么值得做ORKDontKnow 按钮减少被迫作答带来的脏数据,ORKReviewViewController 让参与者提交前改正错误。 怎么开始:在量表答案格式上开启 shouldShowDontKnowButton,问卷完成后用 task 和 result 初始化 ORKReviewViewController

  • 做什么:做一个人体部位选择或疾病教育任务。 为什么值得做ORK3DModelStepORKUSDZModelManager 能把交互式 3D 模型放进 ResearchKit flow,适合解释疼痛位置、肌肉群或检查结果。 怎么开始:准备 USDZ 模型,把需要高亮的对象 identifier 收集成数组,创建 ORKUSDZModelManager 后交给 ORK3DModelStep

  • 做什么:构建一个视频采集 active task。 为什么值得做:Session 展示了前置摄像头任务的完整结构,视频文件和重试次数都能作为 ResearchKit 结果返回。 怎么开始:继承 ORKActiveStep 定义配置,继承 ORKActiveStepViewController 管理 AVCaptureSession,用 ORKFileResult 保存录制文件 URL。

关联 Session

评论

GitHub Issues · utterances