- 모음 탭 왼쪽 위 새로고침 버튼(RefreshButton/AppRefresh): 루트 뷰 identity 리셋으로 모든 @Query를 재조회(앱 재시작과 같은 효과) + 라이브 액티비티· 위젯·워치 스냅숏 동기화. 다른 기기의 iCloud 변경이 화면에 늦게 보일 때 재시작 없이 반영. iPhone·iPad 공통, Release(스토어) 빌드에도 포함 - 설정 → 지원 → 도움말(HelpView): 기본 개념/모음 탭/목표/기록·통계/동기화/ 프리미엄 공통 + iPhone은 화면 구성(탭바·버블 메뉴·다이나믹 아일랜드)과 애플워치(기록·컴플리케이션·동기화) 섹션, iPad는 일기 섹션. 접이식 주제별 구성, 새 문자열 59개 en/ja 번역 - 검증 인자: -helpPreview YES Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
65 lines
2.1 KiB
Swift
65 lines
2.1 KiB
Swift
//
|
|
// AppRefresh.swift
|
|
// Haru_Danim
|
|
//
|
|
// 수동 새로고침 (모음 탭 버튼)
|
|
// - iCloud 동기화로 다른 기기에서 바뀐 데이터가 화면에 바로 안 보일 때, 앱을 껐다 켜는
|
|
// 대신 쓰는 버튼. token을 바꾸면 루트 뷰 identity가 리셋되어 모든 @Query가 스토어에서
|
|
// 다시 조회된다 (재시작과 같은 효과, 데이터는 그대로).
|
|
// - 원격 변경 자동 반영(CloudSyncMonitor)은 위젯·워치·라이브 액티비티만 갱신한다.
|
|
// 화면 전체 리셋은 입력 중인 시트를 닫아버릴 수 있어 수동 버튼으로만 한다.
|
|
//
|
|
|
|
import Foundation
|
|
import Observation
|
|
import SwiftData
|
|
import WidgetKit
|
|
|
|
@MainActor
|
|
@Observable
|
|
final class AppRefresh {
|
|
static let shared = AppRefresh()
|
|
|
|
/// RootNavigationView가 .id로 사용 — 바뀌면 화면 전체가 다시 만들어진다
|
|
private(set) var token = UUID()
|
|
private(set) var isRefreshing = false
|
|
|
|
func refreshNow() {
|
|
guard !isRefreshing else { return }
|
|
isRefreshing = true
|
|
token = UUID()
|
|
Task { @MainActor in
|
|
// 화면 재구성과 함께 파생 상태도 최신 데이터로 맞춘다
|
|
LiveActivityManager.sync(context: DataStore.shared.mainContext)
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
WatchSyncManager.shared.pushSnapshot()
|
|
// 버튼이 눌렸다는 피드백이 보일 만큼만 잠깐 유지
|
|
try? await Task.sleep(for: .milliseconds(700))
|
|
isRefreshing = false
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - 새로고침 버튼 (모음 탭 툴바)
|
|
|
|
import SwiftUI
|
|
|
|
/// 다른 기기에서 바뀐 데이터를 다시 불러오는 작은 툴바 버튼
|
|
struct RefreshButton: View {
|
|
private let refresh = AppRefresh.shared
|
|
|
|
var body: some View {
|
|
Button {
|
|
refresh.refreshNow()
|
|
} label: {
|
|
if refresh.isRefreshing {
|
|
ProgressView()
|
|
} else {
|
|
Image(systemName: "arrow.clockwise")
|
|
}
|
|
}
|
|
.disabled(refresh.isRefreshing)
|
|
.accessibilityLabel(Text("새로고침"))
|
|
}
|
|
}
|