-
Notifications
You must be signed in to change notification settings - Fork 0
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
Build a research and care app, part 1: Setup onboarding #3
Comments
WWDC21) Build a research and care app, part 1: Setup onboardingBuild a research and care app, part 1: Setup onboarding - WWDC21 - Videos - Apple Developer *본 글은 WWDC 를 보고, 번역 및 요약 그리고 실행해보는 스터디 프로젝트의 일환입니다. 들어가기전에ResearchKit 과 CareKit 에 대해서 더 많은 정보를 얻고 싶다면 아래의 소개글도 도움이 될 것입니다. WWDC 내용
마찬가지로 과거 WWDC 세션에서는 이 두 가지 형제 프레임워크에 대해 자주 논의했지만 올해는 이 두 가지 프레임워크를 함께 사용하여 훨씬 더 나은 환경을 만들 수 있는 방법을 보여드릴 것입니다.
Onboarding and consent참가자에게 우리가 수집할 데이터, 액세스할 수 있는 사람, 무엇을 위해 사용될 건지, 보관 기간을 설명하고 이해하기 쉽게 만드는 것이 가장 중요합니다. 앱에서 이 중요한 부분을 올바르게 수행하는데 도움이 되는
실제 동의 부분으로 넘어가기 전에 이와 같이 참가자를 안내하는 것이 경험을 개선하는 데 실제로 도움이 된다는 것을 알게 되었습니다.
Recoversession resources 에 있는 starter project 를 통해서 진행하겠습니다. https://github.com/carekit-apple/WWDC21-RecoverApp (해당 깃허브 레포지토리에 Setup 방법이 있습니다.) Setup
git clone --recurse-submodule https://github.com/carekit-apple/WWDC21-RecoverApp.git
(Recover Part1 의 Recover 을 선택하면 됩니다.) CareKitCareKit 은 미리 SPM 을 통해서 세팅되어 있습니다. https://github.com/carekit-apple/CareKit Get Started!4개의 파일을 이번 세션에서 다룰 것입니다. 첫번째로 Files
Starter APPstarter app 을 실행하게 되면 지금은 사실상 아무것도 없습니다. 컨텐츠가 없는 OCKDailyPageViewController 가 있을뿐입니다. 하단에 Insights 탭도 있지만 비어있습니다. part 3 동안 이것들을 채울 것입니다. 이제 참가자의 feed 에 consent card 가 나타나도록 해봅시다. 이 consent card 는 나머지 앱에 대한 액세스를 제공합니다. 완료되기 전까지 다른 작업이 표시되지 않으며, 완료된 후에는 다른 모든 작업이 표시되어야 합니다. AppDelegateimport CareKit
import CareKitStore
import UIKit
import os.log
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
let storeManager = OCKSynchronizedStoreManager(
wrapping: OCKStore(
name: "com.apple.wwdc.carekitstore",
type: .inMemory
)
)
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
seedTasks()
return true
}
// MARK: UISceneSession Life Cycle
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
// MARK: Seeding the Store
private func seedTasks() {
// 1.1 Persist an onboarding task
// 얼마나 자주 표시되는지 지정하는 schedule 을 정의해야합니다.
// 온보딩을 위해 참가자가 동의를 할때까지 매일매일 schedule 사용.
let onboardSchedule = OCKSchedule.dailyAtTime(
hour: 0, minutes: 0,
start: Date(), end: nil,
text: "Task Due!",
duration: .allDay)
// 방금 만든 schedule 을 일정을 전달해서 task 를 정의해야합니다.
// id 는 원하는 대로 지정하고, 고유하면된다. 현재는 다른 파일에서 선언된 상수를 사용합니다.
var onboardTask = OCKTask(
id: TaskIDs.onboarding,
title: "Onboard",
carePlanUUID: nil,
schedule: onboardSchedule)
// instructions 를 지정하고, 온보딩을 고수하는 것이 영향받지 않아야 한다는 것을 나타내야 합니다.
/// Instructions about how this task should be performed.
onboardTask.instructions = "You'll need to agree to some terms and conditions before we get started!"
/// If true, completion of this task will be factored into the patient’s overall adherence. True by default.
onboardTask.impactsAdherence = false
// 이것은 기본적으로 대부분의 CareKit 맨 위에 완료링을 채우는 것으로 간주되지 않는 다는 것을 의미한다.
// store 에 task 를 유지할 수 있다.
storeManager.store.addAnyTasks([onboardTask],
callbackQueue: .main) { result in
switch result {
case let .success(tasks):
Logger.store.info("Seeded \(tasks.count) tasks")
case let .failure(error):
Logger.store.warning("Failed to seed tasks:\(error as NSError)")
}
}
}
} 이제 온보딩 작업을 store 에 준비했습니다. 참가자의 피드에 보여줄 준비가 되었습니다. CareViewControllerimport CareKit
import CareKitStore
import CareKitUI
import ResearchKit
import UIKit
import os.log
final class CareFeedViewController: OCKDailyPageViewController,
OCKSurveyTaskViewControllerDelegate {
/// 사용자가 새 날짜로 스와이프할 때마다 호출됩니다.
/// 날짜를 검사하고, 해당 날짜에 표시할 내용을 결정한 다음, 적절한 내용을 listViewController에 추가하는 것이 일입니다.
override func dailyPageViewController(
_ dailyPageViewController: OCKDailyPageViewController,
prepare listViewController: OCKListViewController,
for date: Date) {
// 먼저, 참가자가 온보딩을 완료했는지 확인해야 합니다.
// 1.3 Check if onboarding is complete.
checkIfOnboardingComlete { isOnboarding in
// 1.5 If isn't, show an onboarding card.
guard isOnboarding else {
}
}
}
// 1.2 Define a method that checks if onboarding is complete
/// 메서드 안에 OCKOutomeQuery를 만들고 온보딩 작업과 관련된 모든 결과를 쿼리합니다.
private func checkIfOnboardingComlete(_ completion: @escaping (Bool) -> Void) {
var query = OCKOutcomeQuery()
query.taskIDs = [TaskIDs.onboarding]
// query 를 가지고 결과가 반환되었는지 여부를 확인한다.
storeManager.store.fetchAnyOutcomes(
query: query,
callbackQueue: .main) { result in
switch result {
case .failure:
Logger.feed.error("Failed to fetch onboarding outcomes!")
completion(false)
// 없다면 온보딩이 아닉 완료되지 않은 것.
case let .success(outcomes):
completion(!outcomes.isEmpty)
}
}
}
// 1.6 Refresh the content when onboarding completes
}
Survey
import CareKitStore
import ResearchKit
struct Surveys {
private init() {}
// MARK: Onboarding
// 1.4 Construct an ORKTask for onboarding
static func onboardingSurvey() -> ORKTask {
// 1.4.1 The Welcome Instruction step.
let welcomeInstructionStep = ORKInstructionStep(
identifier: "onboarding.welcome"
)
welcomeInstructionStep.title = "Welcome!"
welcomeInstructionStep.detailText = "Thank you for joining our study. Tap Next to learn more before signing up."
welcomeInstructionStep.image = UIImage(named: "welcome-image")
welcomeInstructionStep.imageContentMode = .scaleAspectFill
// 1.4.2 The Informed Consent Instruction step.
// ...
// 1.4.3 The Signature step (using WebView).
// ...
// 1.4.4 The Request Permissions step.
// ...
// 1.4.5 Completion Step
// ...
}
} 1.4.1
1.4.2// 1.4.2 The Informed Consent Instruction step.
let studyOverviewInstructionStep = ORKInstructionStep(
identifier: "onboarding.overview"
)
studyOverviewInstructionStep.title = "Before You Join"
studyOverviewInstructionStep.iconImage = UIImage(systemName: "checkmark.seal.fill")
// 본문 항목 만들기.
// 글머리 대신 이미지를 사용합니다.
let heartBodyItem = ORKBodyItem(
text: "The study will ask you to share some of your health data.",
detailText: nil,
image: UIImage(systemName: "heart.fill"),
learnMoreItem: nil,
bodyItemStyle: .image
)
let completeTasksBodyItem = ORKBodyItem(
text: "You will be asked to complete various tasks over the duration of the study.",
detailText: nil,
image: UIImage(systemName: "checkmark.circle.fill"),
learnMoreItem: nil,
bodyItemStyle: .image
)
let signatureBodyItem = ORKBodyItem(
text: "Before joining, we will ask you to sign an informed consent document.",
detailText: nil,
image: UIImage(systemName: "signature"),
learnMoreItem: nil,
bodyItemStyle: .image
)
let secureDataBodyItem = ORKBodyItem(
text: "Your data is kept private and secure.",
detailText: nil,
image: UIImage(systemName: "lock.fill"),
learnMoreItem: nil,
bodyItemStyle: .image
)
studyOverviewInstructionStep.bodyItems = [
heartBodyItem,
completeTasksBodyItem,
signatureBodyItem,
secureDataBodyItem
] 1.4.3// 1.4.3 The Signature step (using WebView).
// 다행히도 ResearchKit 에서 이 부분을 쉽게 구현 가능합니다.
// signature 은 ORKWebViewStep 으로 수집할 수 있습니다.
// informedConsentHTML 은 HTML 언어로 작성되었고 WebView 를 사용할 수 있습니다.
let webViewStep = ORKWebViewStep(
identifier: "onboarding.signatureCapture",
html: informedConsentHTML
)
// true 로 설정하게되면, ResearchKit 에서 signature box 를 표시합니다.
webViewStep.showSignatureAfterContent = true 1.4.4// 1.4.4 The Request Permissions step.
// HealthKit 권한을 수집합니다. HealthKitPermissionType 을 두가지 지정해야하는데 쓸 권한과 읽을 권한입니다.
// (wwdc20 에서 소개한 타입.)
let healthKitTypesToWrite: Set<HKSampleType> = [
HKObjectType.quantityType(forIdentifier: .bodyMassIndex)!,
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKObjectType.workoutType()
]
let healthKitTypesToRead: Set<HKObjectType> = [
HKObjectType.characteristicType(forIdentifier: .dateOfBirth)!,
HKObjectType.workoutType(),
HKObjectType.quantityType(forIdentifier: .appleStandTime)!,
HKObjectType.quantityType(forIdentifier: .appleExerciseTime)!
]
let healthKitPermissionType = ORKHealthKitPermissionType(
sampleTypesToWrite: healthKitTypesToWrite,
objectTypesToRead: healthKitTypesToRead
)
// wwdc21 에서는 추가적으로 새로운 두 가지 권한을 도입합니다.
/// 알림 표시, 앱 배지, 사운드 재생에 대한 권한을 요청하는 type 입니다.
let notificationsPermissionType = ORKNotificationPermissionType(
authorizationOptions: [.alert, .badge, .sound]
)
/// device motion data 에 액세스를 요청하는데 도움이되는 type 입니다.
let motionPermissionType = ORKMotionActivityPermissionType()
// read and write, notification, activity 액세스 요청.
let requestPermissionsStep = ORKRequestPermissionsStep(
identifier: "onboarding.requestPermissionsStep",
permissionTypes: [
healthKitPermissionType,
notificationsPermissionType,
motionPermissionType
]
)
requestPermissionsStep.title = "Health Data Request"
requestPermissionsStep.text = "Please review the health data types below and enable sharing to contribute to the study." 1.4.5
// 1.4.5 Completion Step
// Jamie 의 연구에 참여해 준 것에 대해 감사하는 단계입니다.
let completionStep = ORKCompletionStep(
identifier: "onboarding.completionStep"
)
completionStep.title = "Enrollment Complete"
completionStep.text = "Thank you for enrolling in this study. Your participation will contribute to meaningful research!"
/// 지금까지의 ORKCompletionStep 을 통해 ORKOrderedTask 를 반환.
let surveyTask = ORKOrderedTask(
identifier: "onboard",
steps: [
welcomeInstructionStep,
studyOverviewInstructionStep,
webViewStep,
requestPermissionsStep,
completionStep
]
)
return surveyTask CareFeedViewController 로 돌아가서 CareKit 기반의 앱에서 이 기능을 표시하는 방법을 다시 살펴보자! CareFeedViewController
// MARK: SurveyTaskViewControllerDelegate
// 1.6 Refresh the content when onboarding completes
//
func surveyTask(
viewController: OCKSurveyTaskViewController,
for task: OCKAnyTask,
didFinish result: Result<ORKTaskViewControllerFinishReason, Error>) {
// 참가자가 중간에 취소한 것이 아니라 온보딩을 끝까지 성공시킨 경우입니다.
// 이때 피드의 새로고침 진행.
if case let .success(reason) = result, reason == .completed {
reload()
}
} 자, 이제 앱이 제대로 작동하는지 확인해 보겠습니다.
온보딩이 끝나게되면 consent 를 완료하라는 메시지가 더 이상 표시되지 않습니다. 대신, 앱의 모든 내용이 표시됩니다. 다음 세션에서 이 내용을 살펴보겠습니다!
크… 간지 |
The text was updated successfully, but these errors were encountered: