사용자 요구('이거까지 하고 배포'): 통계·기록에서도 건강 데이터를 하루다님 스타일로.
전부 표시 전용 — HealthCache 인메모리 읽기만, HK 신규 조회·스키마·집계 수학 무변경.
- 통계 탭 맨 아래: 하루=지표 값 칩 카드 / 주간·월간(롤링 포함)=
'건강 지표 (일별)' 추이 카드(지표 선택 캡슐 메뉴·요일/일 축·단위 라벨, 분홍 단일 선)
+ '건강 지표 합계·평균' 표(분모=기존 '이미 시작된 날/주' 규칙 상속, 0 지표 생략)
- 기록 탭 목록 맨 아래 '건강 데이터' 섹션 — 그날 칩(과거 날짜도 캐시로)
- 표시 규칙: 지표=타일 선택 상속, 마스터 스위치=설정 '건강 데이터 표시'(문구 확장),
미연결·맥=숨김, 내보내기 미포함(비교 카드 전례)
- 값 공급 단일 지점 HealthDisplayValues 신설(수면=유효 표시 구간 키, 일기 카드도 위임),
칩 UI HealthValueChipGrid 공용 — 빌드 9 최적화 그대로 유지
- 도움말·팝업·설정 푸터·whats-new 3언어 갱신(새 키 5·수정 3, 전 카탈로그 0/0)
검증: 자가 검증 62/20/27/10 ALL PASS(수치 불변), 시각 QA(하루·주간[합계 53,966보 시드
검산 일치]·월간 롤링[30일 분모]·기록 목록 과거 날짜·ja·18.5[경과일 분모 4일 검산 일치]),
Debug·Store·18.5 빌드 그린. 종목별 운동 통계는 1.6 후보 보류. CURRENT_PROJECT_VERSION 10.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtZwRRjbtM9pZJDM4FkTq6
468 lines
40 KiB
Swift
468 lines
40 KiB
Swift
//
|
|
// HelpView.swift
|
|
// Haru_Danim
|
|
//
|
|
// 설정 → 도움말: 앱 사용법 안내.
|
|
// 기기에 맞는 내용만 보여준다 — iPhone은 탭바/버블 메뉴·다이나믹 아일랜드·애플워치,
|
|
// iPad는 사이드바·일기(다이어리). 각 주제는 접었다 펼치는 DisclosureGroup.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
// MARK: - 도움말 데이터
|
|
|
|
private struct HelpTopic: Identifiable {
|
|
let id = UUID()
|
|
let symbol: String
|
|
let title: LocalizedStringKey
|
|
let body: LocalizedStringKey
|
|
/// 설명 아래 붙는 예시 스크린샷의 베이스 이름 (예: "help-main").
|
|
/// 실제 파일은 언어 접미사가 붙은 IOS/HelpImages/help-main-ko.jpg 형태 — HelpImage가 해석
|
|
var imageName: String? = nil
|
|
}
|
|
|
|
/// 도움말 스크린샷 로더 — 앱 표시 언어(ko/en/ja)에 맞는 변형을 고른다.
|
|
/// 스크린샷에 UI 문구가 박혀 있어 String Catalog 대신 언어별 파일로 관리한다.
|
|
private enum HelpImage {
|
|
static func load(_ base: String) -> UIImage? {
|
|
let lang: String
|
|
switch Bundle.main.preferredLocalizations.first?.prefix(2) {
|
|
case "en": lang = "en"
|
|
case "ja": lang = "ja"
|
|
default: lang = "ko"
|
|
}
|
|
// jpg는 UIImage(named:)의 확장자 생략 탐색에 안 걸릴 수 있어 URL로 직접 연다
|
|
for candidate in ["\(base)-\(lang)", "\(base)-ko"] {
|
|
if let url = Bundle.main.url(forResource: candidate, withExtension: "jpg"),
|
|
let image = UIImage(contentsOfFile: url.path) {
|
|
return image
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
private struct HelpGroup: Identifiable {
|
|
let id = UUID()
|
|
let title: LocalizedStringKey
|
|
let topics: [HelpTopic]
|
|
}
|
|
|
|
// MARK: - 도움말 화면
|
|
|
|
struct HelpView: View {
|
|
private var groups: [HelpGroup] {
|
|
var result: [HelpGroup] = [basics, mainTab, goals, history]
|
|
// 건강 데이터(1.5)는 지원 기기(아이폰·아이패드)에서만 안내 — 맥은 기능 자체가 없다
|
|
if HealthDataStore.isAvailable {
|
|
result.append(health)
|
|
}
|
|
result.append(sync)
|
|
// 일기는 1.5 추가분부터 전 기기 (아이폰 포함 — §6.7)
|
|
result.append(diary)
|
|
if !DeviceLayout.isPad {
|
|
result.append(iphoneUI)
|
|
result.append(watch)
|
|
}
|
|
result.append(premiumHelp)
|
|
return result
|
|
}
|
|
|
|
var body: some View {
|
|
ScrollViewReader { proxy in
|
|
List {
|
|
ForEach(groups) { group in
|
|
Section(group.title) {
|
|
ForEach(group.topics) { topic in
|
|
// 검증용: -helpExpandAll YES(DEBUG) → 모든 주제를 펼친 채 시작 (스크린샷 검증)
|
|
Group {
|
|
if Self.forceExpanded {
|
|
DisclosureGroup(isExpanded: .constant(true)) {
|
|
topicBody(topic)
|
|
} label: {
|
|
topicLabel(topic)
|
|
}
|
|
} else {
|
|
DisclosureGroup {
|
|
topicBody(topic)
|
|
} label: {
|
|
topicLabel(topic)
|
|
}
|
|
}
|
|
}
|
|
.id(topic.imageName ?? topic.id.uuidString)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.onAppear {
|
|
#if DEBUG
|
|
// 검증용: -helpScrollTo help-main 등 → 해당 이미지 토픽으로 스크롤
|
|
if let anchor = UserDefaults.standard.string(forKey: "helpScrollTo") {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
|
|
withAnimation { proxy.scrollTo(anchor, anchor: .top) }
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
.scrollContentBackground(.hidden)
|
|
.background(AppTheme.background)
|
|
.navigationTitle("도움말")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar(.hidden, for: .tabBar)
|
|
}
|
|
|
|
/// 검증용 전체 펼침 (DEBUG 런치 인자 -helpExpandAll YES)
|
|
private static let forceExpanded: Bool = {
|
|
#if DEBUG
|
|
return UserDefaults.standard.bool(forKey: "helpExpandAll")
|
|
#else
|
|
return false
|
|
#endif
|
|
}()
|
|
|
|
private func topicBody(_ topic: HelpTopic) -> some View {
|
|
VStack(alignment: .leading, spacing: 10) {
|
|
Text(topic.body)
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
if let name = topic.imageName, let image = HelpImage.load(name) {
|
|
Image(uiImage: image)
|
|
.resizable()
|
|
.scaledToFit()
|
|
.frame(maxWidth: 300)
|
|
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
|
|
.overlay(
|
|
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
|
.strokeBorder(.quaternary)
|
|
)
|
|
.frame(maxWidth: .infinity)
|
|
.accessibilityHidden(true) // 본문 설명의 예시 그림 — 낭독 중복 방지
|
|
}
|
|
}
|
|
.padding(.vertical, 4)
|
|
}
|
|
|
|
private func topicLabel(_ topic: HelpTopic) -> some View {
|
|
Label {
|
|
Text(topic.title)
|
|
.font(.body.weight(.medium))
|
|
} icon: {
|
|
Image(systemName: topic.symbol)
|
|
.foregroundStyle(AppTheme.green)
|
|
}
|
|
}
|
|
|
|
// MARK: 공통 — 기본 개념
|
|
|
|
private var basics: HelpGroup {
|
|
HelpGroup(title: "기본 개념", topics: [
|
|
HelpTopic(
|
|
symbol: "figure.walk",
|
|
title: "행동 — 기록의 기본 단위",
|
|
body: "습관이나 할 일을 행동 탭에서 '행동'으로 등록해요. 만들 때 시간 측정(시작·종료를 눌러 걸린 시간을 재요)과 횟수 기록(누를 때마다 +1) 중 하나를 골라요. 이름·아이콘·꼬리표는 나중에 언제든 바꿀 수 있지만, 추적 방식만은 바꿀 수 없으니 처음에 잘 정해 주세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "tag.fill",
|
|
title: "꼬리표 — 색으로 분류",
|
|
body: "꼬리표는 행동을 묶어 주는 이름표예요. 꼬리표마다 고유한 색이 있어서 행동 버튼의 색도 지정한 꼬리표의 색을 따라가요. 한 행동에 꼬리표를 여러 개 붙여도 되고, 꼬리표 탭이나 행동 만들기 화면에서 바로 새로 만들 수도 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "flag.fill",
|
|
title: "목표와 다짐",
|
|
body: "목표는 '토익 700점 받기'처럼 큰 방향이고, 다짐은 그 목표를 이루기 위한 실천 약속이에요. 다짐을 만들 때는 행동(또는 꼬리표)을 고르고 주기(하루·주간·월간·특정 기간)와 목표량을 정해요. '이상 달성'뿐 아니라 '이하 유지'(예: 영상 시청은 하루 1시간 이하)로도 만들 수 있어요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 모음 탭
|
|
|
|
private var mainTab: HelpGroup {
|
|
HelpGroup(title: "모음 탭", topics: [
|
|
HelpTopic(
|
|
symbol: "play.circle.fill",
|
|
title: "측정 시작·종료",
|
|
body: "행동 버튼을 누르면 시간형은 측정이 시작되고, 다시 누르면 끝나요 — 측정 중인 버튼은 노란 테두리로 표시돼요. 횟수형은 누를 때마다 1씩 올라가요. 여러 행동을 동시에 측정해도 되고, 측정 중인 행동은 위쪽 '현재 진행 중'에서도 끝낼 수 있어요. 끄는 걸 자주 잊는다면 설정 → 측정에서 '장시간 측정 알림'을 켜 보세요. 정해 둔 시간을 넘기면 알려줘요.",
|
|
imageName: "help-main"
|
|
),
|
|
HelpTopic(
|
|
symbol: "clock.badge.xmark",
|
|
title: "짧은 기록 무시",
|
|
body: "설정 → 측정에서 '짧은 기록 무시'를 켜면, 정한 시간보다 짧게 재고 끝낸 기록은 저장하지 않아요. 버튼을 실수로 눌렀다가 바로 껐을 때 의미 없는 기록이 쌓이는 걸 막아 줘요. 기준 시간은 3초부터 1분까지 고를 수 있고, 위젯·워치·시리로 끝낼 때도 똑같이 적용돼요. 이 설정은 iCloud를 통해 모든 기기에 같이 적용되고, 애플워치에서 끝낸 측정은 짝지어진 아이폰의 설정을 따라요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "star.fill",
|
|
title: "즐겨찾기 모아 보기",
|
|
body: "행동을 즐겨찾기로 지정하면 모음 탭이 '즐겨찾기'와 '나머지 행동' 두 부분으로 나뉘고, 즐겨찾기가 늘 위에 와요. 새로 지정한 행동은 즐겨찾기 맨 뒤에 붙어요. 지정하는 방법은 두 가지예요 — 행동 버튼을 길게 눌러 '즐겨찾기'를 고르거나, 행동 탭에서 행동을 열어 별을 눌러요. 순서는 '배치 편집'에서 끌어 옮기거나 행동 탭 오른쪽 위 ⋯ 메뉴의 '즐겨찾기 순서 변경'으로 바꿀 수 있고, 이 순서는 애플워치의 즐겨찾기에도 그대로 적용돼요. 배치 편집 중에는 즐겨찾기와 나머지 사이로 끌어서 지정하거나 해제할 수도 있어요. '나머지 행동' 제목을 누르면 아래를 접어 둘 수 있어서, 행동이 많아져도 자주 쓰는 것만 남겨요(접힘은 기기마다 따로 저장돼요)."
|
|
),
|
|
HelpTopic(
|
|
symbol: "arrow.clockwise",
|
|
title: "새로고침 버튼",
|
|
body: "모음 탭 왼쪽 위의 새로고침 버튼은 앱을 껐다 켠 것처럼 화면을 처음부터 다시 불러오고, 홈 화면 위젯과 애플워치도 함께 새로 고쳐요. 다른 기기에서 바꾼 내용이 아직 안 보이거나 위젯이 굼떠 보일 때 눌러 보세요. iCloud 동기화와 위젯이 프리미엄 기능이라, 이 버튼도 프리미엄을 쓸 때만 보여요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "hand.tap.fill",
|
|
title: "길게 누르기 메뉴",
|
|
body: "행동 버튼을 길게 누르면 메뉴가 열려요 — 기록 직접 입력·수정, 즐겨찾기 지정·해제, 기록 확인, 통계 보기, 행동 설정 수정, 삭제까지 여기서 다 돼요. 시간형은 시작·종료 시각을, 횟수형은 횟수와 시각을 직접 고칠 수 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "note.text",
|
|
title: "기록에 메모 남기기",
|
|
body: "행동 탭에서 행동을 열어 '기록 시 메모 창 표시'를 켜 보세요. 시간 측정을 끝내거나 횟수를 더할 때마다 메모 창이 떠서 그 기록에 한 줄을 남길 수 있어요(건너뛰어도 돼요). 이 설정은 기기마다 따로 저장돼요. 남긴 메모는 기록 탭에 노란 글씨로 보이고, 기록을 눌러 수정할 때 메모를 고치거나 새로 붙일 수도 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "square.grid.3x3.fill",
|
|
title: "배치 편집",
|
|
body: "오른쪽 위 '배치 편집'을 누르면 버튼들이 흔들리기 시작하고, 끌어서 순서를 바꿀 수 있어요. 한 줄에 몇 개를 둘지도 여기서 골라요. '완료'를 누르면 저장되고, 이 순서는 위젯이 행동을 고르는 기본 순서로도 쓰여요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 목표 활용
|
|
|
|
private var goals: HelpGroup {
|
|
HelpGroup(title: "목표 탭", topics: [
|
|
HelpTopic(
|
|
symbol: "chart.bar.fill",
|
|
title: "진행률 읽는 법",
|
|
body: "다짐마다 하루·주간·월간 진행률이 보여요. 주간·월간 진행률은 어느 하루의 초과 달성이 다른 날의 미달을 가리지 않도록 하루 목표량까지만 인정해서 더하고, 요일·날짜를 정한 다짐은 수행일의 기록만 세요 — 수행일이 아닌 날의 '하루' 칸에는 '수행일 아님'이 표시돼요. 주간·월간 다짐이 이번 주(이번 달) 몫을 이미 채웠다면 '하루'는 0% 대신 '이번 주 달성'·'이번 달 달성'으로 바뀌고 목표의 하루 진행률에도 달성으로 들어가요 — 오늘은 더 하지 않아도 된다는 뜻이에요. 다짐 자신의 주기(하루 다짐의 '하루' 같은)에서는 100%를 넘는 초과 달성이 그대로 보이지만, 주간 다짐의 '하루'처럼 주기와 다른 기간은 목표를 그 기간 몫으로 나눈 페이스 기준이라 100%까지만 보여요. '이하 유지' 다짐은 한도 안이면 100%, 넘으면 0%예요 — 주간·월간 한도 다짐의 '하루'는 하루 몫 기준이라, 주간 한도가 아직 남았어도 오늘 많이 쓰면 먼저 알려 주는 경고 역할을 해요.",
|
|
imageName: "help-goal"
|
|
),
|
|
HelpTopic(
|
|
symbol: "clock.badge.checkmark",
|
|
title: "마감 시각까지 달성하기",
|
|
body: "하루 단위 다짐을 만들 때 '마감 시각까지만 집계'를 켜면, 하루 시작부터 그 시각까지의 기록만 다짐에 세요. 예를 들어 '일어나기 1회 · 오전 8:00까지'로 만들면 8시가 지나 누른 기록은 기록 탭에는 남지만 그날 달성으로는 치지 않아요. '이하 유지' 다짐은 마감까지 한도를 지키면 그날 달성이에요. 시간 측정이 마감에 걸치면 마감 전까지의 시간만 인정돼요. 하루 시작 시간보다 이른 시각을 고르면 다음 날 새벽(그 하루가 끝나기 전)을 뜻해요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "flame.fill",
|
|
title: "연속 달성 표시",
|
|
body: "다짐을 끊기지 않고 지키면 불꽃과 함께 '연속 3일'처럼 표시돼요. 요일이나 날짜를 정한 다짐은 그 수행일만 세고, 주간·월간 다짐은 '연속 몇 주·몇 달'로 세요. 세는 건 목표 시작일부터고, 아직 끝나지 않은 오늘(이번 주기)은 못 채웠어도 끊긴 걸로 치지 않아요. '이하 유지' 다짐은 한도를 넘는 순간 끊겨요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "checkmark.seal.fill",
|
|
title: "목표 종료와 판정",
|
|
body: "종료일이 있는 목표는 날짜가 지나면 저절로 달성 여부가 판정돼요 — 앱을 며칠 뒤에 열어도 종료일까지의 기록으로 판정하니 결과가 달라지지 않아요. 종료일이 없는 목표는 수동 종료 버튼으로 마쳐요. 판정 기준은 다짐들의 평균 달성률이에요. 목표를 만들 때 정한 '달성 판정 기준'(기본 100%) 이상이면 달성이라, 기준을 80%로 두면 조금 못 채워도 달성으로 남길 수 있어요. 다짐 없이 종료일이 지난 목표는 '달성했나요?' 상태가 되어 직접 고르면 되고, 완료된 목표의 종료일을 고치면 다시 판정돼요 — 미래로 옮기면 진행 중으로 돌아와요. 완료된 목표는 목록 아래 '완료된 목표'에서 볼 수 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "pin.fill",
|
|
title: "모음 탭에 목표 카드 띄우기",
|
|
body: "설정 → '모음 탭 목표 진행 현황'에서 목표를 고르면 모음 탭 맨 위에 진행 현황 카드가 떠요. 여러 개를 고르면 카드를 옆으로 쓸어 한 장씩 넘겨 볼 수 있어요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 기록·통계
|
|
|
|
private var history: HelpGroup {
|
|
HelpGroup(title: "기록·통계 탭", topics: [
|
|
HelpTopic(
|
|
symbol: "calendar",
|
|
title: "기록 보기·고치기",
|
|
body: "기록 탭에는 하루의 모든 기록이 모여요. 위쪽 화살표로 날짜를 옮기고, 기록을 누르면 바로 고칠 수 있어요. 타임테이블 보기로 바꾸면 하루나 일주일을 24시간 축 위에서 한눈에 볼 수 있어요.",
|
|
imageName: "help-history"
|
|
),
|
|
HelpTopic(
|
|
symbol: "line.3.horizontal.decrease.circle",
|
|
title: "필터와 하루 기준",
|
|
body: "필터 버튼으로 보고 싶은 행동만 골라 볼 수 있어요. 설정의 '주 시작 요일'과 '하루 시작 시간'은 앱의 모든 집계에 적용돼요. 예를 들어 하루 시작을 06:00으로 두면, 새벽에 남긴 기록은 전날의 실적으로 세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "square.and.arrow.up",
|
|
title: "이미지로 내보내기",
|
|
body: "기록·통계 탭 오른쪽 위의 내보내기 버튼을 누르면, 지금 보고 있는 기간이 그대로 고화질 이미지 리포트가 돼요. 라이트·다크 테마를 골라 공유하거나 사진 앱에 저장해 두세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "calendar.badge.clock",
|
|
title: "지난 7일·30일로 보기",
|
|
body: "통계 탭의 주간·월간에서 '지난 7일/30일 단위로 보기'를 켜면, 달력의 주·월 대신 오늘로 끝나는 최근 7일·30일을 봐요. 주초나 월초라 그래프가 텅 비어 보일 때 특히 좋아요. 화살표는 7일·30일씩 움직이고, 맨 위 비교 카드도 바로 앞 7일·30일과의 비교로 바뀌어요. 홈 화면 통계 위젯에도 '지난 7일'·'지난 30일' 기간이 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "arrow.up.arrow.down",
|
|
title: "이전 기간과 비교",
|
|
body: "통계 탭 맨 위의 비교 카드는 지금 보는 하루·주·월의 총 시간과 횟수를 바로 앞 기간(어제·지난주·지난달)과 견주어 보여줘요. 필터를 걸어 두면 고른 행동들만으로 비교해요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "tablecells",
|
|
title: "CSV로 백업·복원하기",
|
|
body: "설정 → 데이터 → '데이터 내보내기'에서 모든 기록(행동·시간·횟수·목표·다짐)을 CSV 파일로 만들 수 있어요. 구간을 직접 정해 그 기간의 기록만 내보낼 수도 있고요. 스프레드시트에서 열어 살펴보거나 백업으로 보관해 두세요 — 내보내기는 무료에서도 쓸 수 있어요.\n'데이터 가져오기'(프리미엄)를 쓰면 내보냈던 CSV에서 행동과 시간·횟수 기록을 되살릴 수 있어요. 기존 데이터는 건드리지 않고 새 기록만 더하며, 이미 있는 기록은 알아서 건너뛰니 같은 파일을 여러 번 가져와도 안전해요. CSV에만 있는 행동은 새로 만들어지고, 이름과 방식이 같은 행동이 이미 있으면 그 행동으로 이어져요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "trash",
|
|
title: "데이터 정리·초기화",
|
|
body: "기록이 오래 쌓여 정리하고 싶다면 설정 → 데이터 → '데이터 정리·초기화'를 써 보세요. 전체를 비우거나, 처음부터 정한 날짜까지의 기록·일기만 지울 수 있어요 — 이때 행동·꼬리표·목표·다짐과 일기 양식은 남고, 그 날짜에 걸쳐 있는 측정과 진행 중인 측정도 남아요. '일기만'을 고르면 기록은 그대로 두고 일기만 지워요 — 사진과 필기로 커진 일기 용량만 줄이고 싶을 때 좋아요. 지우기 전에 CSV 백업과, 지울 기록을 한눈에 담은 '정리 리포트'(PDF·이미지)를 만들어 보관할 수 있어요. 백업을 켰다면 파일을 만든 뒤에만 삭제로 넘어갈 수 있고요. 과거 기록이 사라지면 다짐의 연속 달성은 끊겨요. iCloud 동기화 중이면 다른 기기에서도 함께 지워지니 백업을 꼭 저장해 두세요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 건강 데이터 (1.5)
|
|
|
|
private var health: HelpGroup {
|
|
HelpGroup(title: "건강 데이터", topics: [
|
|
HelpTopic(
|
|
symbol: "heart.fill",
|
|
title: "모음 탭에서 건강 데이터 보기",
|
|
body: "모음 탭의 '건강 데이터' 줄에서 '애플 건강 연결하기'를 누르면 걸음 수·운동 시간·수면 같은 오늘 데이터를 타일로 볼 수 있어요. 어떤 지표를 어떤 순서로 보여줄지는 줄 오른쪽의 지표 버튼에서 고르고, 설정 → '건강 데이터'에서 줄 자체를 끄거나 즐겨찾기·나머지 행동과의 순서를 바꿀 수 있어요. 골라 둔 지표는 통계 탭 아래의 건강 카드(하루 값·지표별 추이·합계와 하루 평균)와 기록 탭 목록의 그날 건강 카드에도 그대로 쓰여요 — '건강 데이터 표시'를 끄면 이 카드들도 함께 사라져요.\n값은 애플 건강 앱이 가진 데이터를 읽어 온 거예요 — 하루 다님이 서버로 보내거나 iCloud에 저장하는 일은 없어요. 걸음·운동 같은 값은 설정의 '하루 시작 시간' 기준으로 오늘 하루를 더한 것이고, 수면만은 정해 둔 수면 구간(기본 저녁 9시~다음 날 아침 9시)에서 잔 시간을 통째로 '그날 잔 것'으로 세요. 애플워치에 쌓인 데이터는 워치와 아이폰이 동기화된 뒤에 보이니 값이 안 맞아 보이면 잠시 뒤 다시 확인해 주세요. 값이 계속 0이라면 아이폰의 설정 → 개인정보 보호 및 보안 → 건강에서 하루 다님의 읽기 권한을 확인해 주세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "bed.double.fill",
|
|
title: "수면 표시 구간 맞추기",
|
|
body: "타일의 수면이 실제와 다르게 0으로 보인다면, 그 잠이 수면 구간 밖에 있었을 가능성이 커요 — 기본 구간(저녁 9시~다음 날 아침 9시)은 아침 9시 이후에 잔 잠을 세지 않거든요. 설정 → 건강 데이터 → '수면 표시 구간'에서 구간을 바꿔 보세요. 시작과 끝을 같은 시각으로 두면 그 시각에 끝나는 하루 전체(24시간)를 보고, '요일마다 다르게'를 켜면 야간 근무처럼 특정 요일만 낮에 자는 패턴도 요일별 구간으로 맞출 수 있어요.\n이 설정은 모음 탭 타일과 일기의 건강 카드에 적용돼요. 다짐의 수면 구간은 다짐 편집에서 따로 정하고, 새로 만드는 수면 다짐은 여기의 전체 구간으로 시작해요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "heart.text.square.fill",
|
|
title: "일기에서 건강 데이터 보기",
|
|
body: "일기의 하루 정리 첫 페이지에 '건강 데이터' 카드가 있어요 — 그날의 걸음·운동·수면 같은 값을 일기와 함께 봐요. 카드 오른쪽 위 버튼으로 보여줄 지표를 고르면 모든 날짜에 함께 적용돼요. 일기와 기록 탭의 타임테이블에는 수면·운동이 실제 시간 그대로 옅은 블록으로 깔려요 — 기본 색은 수면 남보라·운동 주황이고, 설정 → 건강 데이터 → '타임테이블 표시 색'에서 바꿀 수 있어요. 필터의 '건강 데이터' 토글로 켜고 끄면 두 타임테이블에 함께 적용돼요.\n건강 값은 기기 안에만 있어서 카드의 값도 기기마다 다를 수 있어요 — 아이패드는 시스템의 건강 iCloud 동기화를 켠 경우에만 아이폰과 같은 값이 보이고, 맥에서는 카드와 블록이 보이지 않아요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "figure.run",
|
|
title: "건강 데이터로 다짐 만들기 (프리미엄)",
|
|
body: "다짐을 만들 때 대상에서 '건강'을 고르면 '매일 8,000보', '수면 8시간 이상', '달리기 30분'처럼 건강 데이터를 목표로 삼을 수 있어요. 걸음 수·운동 시간·수면·활동 에너지·이동 거리·일어서기·마음챙김·물 섭취를 고를 수 있고, 운동은 달리기·수영·근력 운동 같은 종목별로도 만들 수 있어요 — 종목별 시간은 건강 앱에 기록된 운동 기준이라 활동 링의 '운동 시간'과는 값이 다를 수 있어요. 건강 다짐은 하루 단위로만 반복돼요(요일 지정은 돼요). 목표 탭·위젯에서 이 다짐이 보일 색도 만들 때 직접 고를 수 있어요 — 기본은 분홍이고, 타임테이블의 수면·운동 블록 색과는 별개예요.\n수면 다짐은 '수면 구간'(기본 저녁 9시~다음 날 아침 9시)을 정해 두면 그 안에서 잔 시간을 통째로 그날 것으로 세요 — 자정을 넘겨 자도 하루가 쪼개지지 않아요. 진행률·연속 달성·목표 판정은 다른 다짐과 똑같은 규칙으로 계산돼요. 건강 데이터가 없는 기기(맥 등)에서는 건강 다짐이 '데이터 없음'으로 보이고 목표 진행률에서 빠져요 — 아이폰에서 보면 정상으로 보여요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 동기화
|
|
|
|
private var sync: HelpGroup {
|
|
HelpGroup(title: "기기 간 동기화 (프리미엄)", topics: [
|
|
HelpTopic(
|
|
symbol: "icloud.fill",
|
|
title: "동기화 켜기",
|
|
body: "설정 → 프리미엄에서 '기기 간 동기화'를 켜면 아이폰·아이패드·맥의 데이터가 iCloud로 하나가 돼요. 켠 뒤에는 앱을 완전히 껐다가 다시 열어야 적용돼요. 모든 기기가 같은 Apple 계정으로 로그인되어 있어야 하고요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "arrow.triangle.2.circlepath",
|
|
title: "반영이 늦을 때",
|
|
body: "iCloud 동기화는 네트워크 상황에 따라 몇 초에서 몇 분까지 걸릴 수 있어요. 다른 기기의 기록이 안 보이면 모음 탭 왼쪽 위의 새로고침 버튼을 눌러 보세요. 그래도 안 보이면 잠시 뒤 다시 시도하거나, 두 기기 모두 인터넷에 연결되어 있는지 확인해 주세요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 일기 (1.5 추가분부터 아이폰 포함 전 기기)
|
|
|
|
private var diary: HelpGroup {
|
|
HelpGroup(title: "일기 (프리미엄)", topics: [
|
|
HelpTopic(
|
|
symbol: "book.closed.fill",
|
|
title: "하루 정리 첫 페이지",
|
|
body: "일기 탭 달력에서 날짜를 누르면 그날의 일기가 열려요. 첫 페이지에는 오늘 기분·요약·목표 진행 현황·할 일·24시간 타임테이블·기록·건강 데이터가 모여 하루가 한눈에 정리돼요. 오른쪽 위 ⋯ 메뉴의 '첫 화면 구성'에서 섹션을 보일지 말지와 순서를 바꿀 수 있어요. 기분 사진을 남긴 날은 달력의 그 칸에 사진이 배경으로 깔려요. 일기는 아이폰·아이패드·맥에서 쓸 수 있고, iCloud 동기화를 켜면 어느 기기에서든 같은 일기가 이어져요.",
|
|
imageName: "help-diary"
|
|
),
|
|
HelpTopic(
|
|
symbol: "calendar.badge.plus",
|
|
title: "타임테이블에 일정·필터",
|
|
body: "첫 페이지 타임테이블 카드의 오른쪽 위 캘린더 버튼으로 그날의 캘린더 일정을 골라 함께 보여줄 수 있어요 — 일정은 점선 테두리라 행동과 바로 구분돼요. 필터 버튼으로는 그날 기록된 행동 중 타임테이블에 올릴 것만 고르고, '이 날의 목표' 카드의 필터로는 보고 싶은 목표만 남겨요. 이 선택들은 날짜마다 따로 저장되고, 타임테이블 선택은 일기를 내보낼 때도 그대로 담겨요.\n애플 건강의 수면·운동 시간도 실제 잔 시간·운동한 시간 그대로 옅은 블록으로 깔려요 — 기본은 수면 남보라·운동 주황이고, 색이 꼬리표와 헷갈리면 설정 → 건강 데이터 → '타임테이블 표시 색'에서 바꿀 수 있어요. 필터의 '건강 데이터' 토글로 켜고 끌 수 있고(기록 탭 타임테이블에도 함께 적용), 건강 데이터가 없는 맥에서는 보이지 않아요.\n매일 같은 선택을 되풀이하기 싫다면 달력 화면 오른쪽 위의 '기본 표시 설정'을 써 보세요. 캘린더 일정을 기본으로 넣을지(모든 캘린더/선택한 캘린더만), 어떤 목표·행동을 기본으로 숨길지 한 번만 정하면 모든 날짜에 적용돼요. 날짜별 필터로 다르게 고른 날은 그 선택이 우선하고, '기본값으로 되돌리기'로 언제든 돌아갈 수 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "applepencil",
|
|
title: "펜슬 노트 페이지",
|
|
body: "페이지를 넘기면 자유 노트가 이어져요. 애플 펜슬로 마음껏 쓰고 그리세요 — 손가락은 페이지 넘기기와 확대·축소를 맡아요. 두 손가락으로 벌려 확대하면 작은 글씨도 또박또박 쓸 수 있고, 줄 노트를 켜면 줄 간격도 고를 수 있어요. 페이지가 여러 장이면 오른쪽 위 ⋯ 메뉴의 '페이지 순서 변경'으로 차례를 바꿔요.\n아이폰에서는 도구 줄의 '그리기'를 켠 동안 손가락으로 그려지고, 끄면 손가락이 다시 페이지 넘기기·확대에 쓰여요. 맥에서는 키보드 입력이 기본이고, 마찬가지로 '그리기'를 켠 동안에만 마우스·트랙패드로 그려져요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "square.on.circle",
|
|
title: "사진·도형·텍스트 꾸미기",
|
|
body: "노트 페이지 도구 줄에서 '사진'·'도형'·'텍스트'를 더한 뒤 '배치 모드'에서 꾸며요 — 끌어서 옮기고, 두 손가락으로 오므리거나 벌려 크기를(모양 비율은 그대로), 돌려서 회전을 바꿔요. 요소를 선택하면 손잡이가 나타나요. 사각형은 꼭짓점을 끌면 그 모서리만 움직이고, 원은 상하좌우 손잡이로 늘리고 눌러 타원을 만들고, 화살표·선은 양 끝점을 끌어 길이와 방향을 함께 바꿔요. 조절하다 정사각형·정원이 되는 순간 손잡이가 노랗게 변하며 살짝 붙잡아 줘요. 텍스트 상자는 선택된 채 한 번 더 누르면 그 자리에서 바로 키보드 입력·줄바꿈이 되고, '스타일'에서 글자 색·크기·굵기·정렬·테두리(색·굵기까지)를 바꿔요. 도형은 '도형 수정'에서 색·선 굵기·채우기·모서리 둥글기·회전을 다듬어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "doc.text.image",
|
|
title: "나만의 양식(속지)",
|
|
body: "달력 화면 오른쪽 위의 양식 버튼에서 PDF나 사진을 노트의 배경 양식(속지)으로 가져올 수 있어요. 가져온 양식은 페이지를 더할 때 빈 캔버스·줄 노트와 나란히 고를 수 있고, 여러 쪽짜리 PDF는 원하는 쪽만 골라 써요. 양식은 필기 아래에 깔리고, 확대해도 흐려지지 않아요. 양식을 지우면 그 양식을 쓰던 페이지는 빈 캔버스로 보이지만 필기는 그대로 남아요.\n양식이 깔린 페이지의 펜 색은 라이트·다크 모드와 상관없이 고른 색 그대로 고정돼요 — 양식은 늘 밝은 배경이라, 어느 기기 어느 모드에서 봐도 필기가 같은 색으로 보이게 하기 위해서예요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "square.and.arrow.up.on.square",
|
|
title: "일기 내보내기",
|
|
body: "달력 화면 오른쪽 위의 내보내기 버튼에서 기간(며칠부터 며칠까지)이나 여러 날짜를 골라 PDF나 이미지로 저장해요. 요약 페이지와 노트 페이지가 보이는 그대로 담겨요.\n파일을 만든 다음에는 '내보낸 날짜의 일기 삭제'로 방금 내보낸 일기들을 앱에서 지워 저장 공간을 되찾을 수 있어요. 필기와 사진이 함께 지워지고 iCloud 동기화 중이면 다른 기기에서도 지워지니, 공유로 파일부터 저장해 뒀는지 꼭 확인해 주세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "lock.fill",
|
|
title: "일기 잠금",
|
|
body: "설정 → 일기에서 '일기 잠금'을 켜면 일기 탭을 열 때마다 Face ID·Touch ID나 기기 암호로 풀어야 해요. 기기가 지원하는 방식이 알아서 쓰이고, 앱을 나갔다 돌아오면 다시 잠겨요. 이 설정은 켠 기기에만 적용돼요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: iPhone 전용 — 화면 구성
|
|
|
|
private var iphoneUI: HelpGroup {
|
|
HelpGroup(title: "화면 구성 (아이폰)", topics: [
|
|
HelpTopic(
|
|
symbol: "squares.leading.rectangle",
|
|
title: "탭바 구성과 더보기",
|
|
body: "설정 → '탭바 구성'에서 아래 탭바에 바로 둘 탭(최대 3개)을 골라요. 나머지 탭은 '더보기'에서 열면 돼요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "circle.hexagongrid.fill",
|
|
title: "글래스 버블 메뉴",
|
|
body: "설정 → '내비게이션 방식'에서 '글래스 버블 메뉴'를 고르면 탭바 대신 화면 아래 가운데 버튼 하나로 모든 탭을 열어요. 버튼을 누르면 유리 구슬들이 부채꼴로 피어나고, 구슬 순서도 설정에서 바꿀 수 있어요. '두 번 눌러 바로 이동'을 켜 두면, 메뉴가 닫혀 있을 때 버튼을 빠르게 두 번 눌러 정해 둔 탭으로 곧장 갈 수 있어요.",
|
|
imageName: "help-radial"
|
|
),
|
|
HelpTopic(
|
|
symbol: "square.grid.2x2.fill",
|
|
title: "홈 화면·잠금화면 위젯 (프리미엄)",
|
|
body: "홈 화면을 길게 눌러 '하루 다님' 위젯을 더해 보세요. 행동 실행(눌러서 시작·+1), 현재 진행 중(실시간 타이머와 종료 버튼), 목표 진행률, 다짐 진행률(원형 링과 누적값), 다짐 현황, 행동 통계 그래프, 그리고 잠금화면용 목표 달성률까지 있어요. 위젯을 길게 눌러 '위젯 편집'을 열면 보여줄 행동·목표·다짐과 기간, 테마를 고를 수 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "bolt.horizontal.circle",
|
|
title: "다이나믹 아일랜드·잠금화면",
|
|
body: "시간을 재는 동안에는 다이나믹 아일랜드와 잠금화면에 진행 시간이 떠 있어요. 여러 개를 동시에 재면 설정의 '대표 시간 기준'(먼저/나중에 시작한 행동)에 따라 하나가 대표로 보이고 나머지는 +N으로 표시돼요. 잠금화면 배너의 노란 정지 버튼을 누르면 앱을 열지 않고도 대표 측정이 바로 끝나요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "switch.2",
|
|
title: "제어 센터에서 실행 (프리미엄)",
|
|
body: "제어 센터를 편집해 '하루 다님'의 '행동 실행' 컨트롤을 더하면, 화면을 켜자마자 행동을 실행할 수 있어요. 시간형은 시작/종료가 번갈아 되고, 횟수형은 누를 때마다 +1이에요. 잠금화면 아래 버튼이나 액션 버튼에 둘 수도 있어요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: iPhone 전용 — 애플워치
|
|
|
|
private var watch: HelpGroup {
|
|
HelpGroup(title: "애플워치 (프리미엄)", topics: [
|
|
HelpTopic(
|
|
symbol: "applewatch",
|
|
title: "워치에서 기록하기",
|
|
body: "워치 앱을 열면 꼬리표 목록이 보여요. 꼬리표를 누르면 그 안의 행동들이 나오고, 행동을 누르면 시간형은 측정 시작·종료, 횟수형은 +1이 남아요. 아이폰에서 즐겨찾기한 행동은 첫 화면 맨 위 '즐겨찾기'에서 한 번에 열 수 있어요. 측정 중일 때는 첫 화면 맨 위에 측정 중인 행동과 시간이 보이고, 그 줄을 누르면 바로 끝나요. 기록은 아이폰과 자동으로 맞춰져요.",
|
|
imageName: "help-watch"
|
|
),
|
|
HelpTopic(
|
|
symbol: "watchface.applewatch.case",
|
|
title: "컴플리케이션 추가",
|
|
body: "워치 페이스를 길게 눌러 '편집' → 컴플리케이션 자리에서 하루 다님을 골라요. 현재 측정 중인 행동, 목표의 달성률, 다짐의 진행률, 행동의 누적 기록을 페이스에서 바로 볼 수 있어요. 목표·다짐 달성률 목록에는 목표를 만들거나 수정할 때 '애플워치에서 보기'를 켠 목표와 그 다짐들만 하루·주간·월간으로 나타나요 — 기본은 꺼져 있고, 완료된 목표는 목록에서 알아서 사라져요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "applewatch.watchface",
|
|
title: "행동 기록 컴플리케이션",
|
|
body: "행동의 누적 기록을 워치 페이스에 두고 싶다면, 아이폰의 행동 편집에서 '애플워치 컴플리케이션'을 켜고 표시 기간(하루·이번 주·이번 달·지난 7일·지난 30일)을 골라 주세요. 그러면 페이스 편집의 '행동 기록' 목록에 그 행동이 나타나요. 측정 중일 때는 컴플리케이션이 노란 타이머로 바뀌고, 컴플리케이션을 누르면 워치 앱의 그 행동 화면이 열려요 — 화면의 행동 아이콘을 누르면 바로 시작·종료(횟수형은 +1)되고, 뒤로 가면 워치 앱 첫 화면이에요. 페이스의 숫자는 몇 분 간격으로 갱신되니 방금 누른 기록이 바로 안 보여도 잠시만 기다려 주세요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "arrow.triangle.2.circlepath",
|
|
title: "워치와 폰이 안 맞을 때",
|
|
body: "워치와 아이폰은 서로 가까이 있을 때 자동으로 맞춰져요. 값이 다르게 보이면 워치 앱을 한 번 열어 두거나, 아이폰에서 앱을 열어 주세요. 모음 탭의 새로고침 버튼도 도움이 돼요."
|
|
),
|
|
])
|
|
}
|
|
|
|
// MARK: 공통 — 프리미엄
|
|
|
|
private var premiumHelp: HelpGroup {
|
|
HelpGroup(title: "프리미엄", topics: [
|
|
HelpTopic(
|
|
symbol: "crown.fill",
|
|
title: "무료와 프리미엄의 차이",
|
|
body: "무료로는 행동 10개·목표 2개·목표당 다짐 3개까지 만들 수 있어요. 프리미엄에서는 개수 제한이 풀리고 위젯, 애플워치 앱, 시리 단축어, 기기 간 동기화, 일기(아이폰·아이패드·맥), CSV 가져오기, 건강 다짐을 쓸 수 있어요. 월·년 구독이나 한 번만 결제하는 평생 이용권 중에 고르면 돼요. 구독이 끝나도 기록한 데이터는 그대로 남고, 이미 만든 건강 다짐도 계속 보이고, 쓴 일기도 계속 열람할 수 있어요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "mic.fill",
|
|
title: "시리·단축어로 기록하기",
|
|
body: "단축어 앱에서 '하루 다님'을 찾으면 측정 시작·종료, 횟수 추가, 행동 누적값 가져오기, 목표·다짐 진행률 가져오기 동작으로 나만의 자동화를 만들 수 있어요. \"시리야, 하루 다님에서 측정 시작\"처럼 말로도 되고, 어떤 행동인지 물으면 이름으로 답하면 돼요. 진행률 동작은 값을 돌려주니 다른 단축어와 이어 붙이기 좋아요."
|
|
),
|
|
HelpTopic(
|
|
symbol: "arrow.counterclockwise.circle",
|
|
title: "구매 복원과 구독 관리",
|
|
body: "기기를 바꿨거나 앱을 다시 깔았다면 설정 → 프리미엄에서 '구매 복원'을 눌러 주세요. 구독 해지나 플랜 변경은 '구독 관리'에서 언제든 할 수 있고, 해지해도 이미 결제한 기간이 끝날 때까지는 그대로 쓸 수 있어요."
|
|
),
|
|
])
|
|
}
|
|
}
|