제어 센터/잠금화면 하단/액션 버튼에 배치할 수 있는 '행동 실행' 컨트롤: - 행동 하나를 골라(미선택 시 배치 첫 행동) 시간형은 시작/종료 토글, 횟수형은 탭마다 +1 (토글 표시는 꺼짐으로 복귀) - 전용 ToggleActionControlIntent(SetValueIntent + LiveActivityIntent) — 앱 프로세스 실행이라 제어 센터에서 시작해도 다이나믹 아일랜드가 바로 뜸. 단축어 앱에는 숨김(isDiscoverable=false), 프리미엄 게이트 적용 - DataChange.commit / IntentStore.performWrite에 ControlCenter.reloadAllControls() 추가 — 앱/위젯/시리/워치 어느 경로로 측정 상태가 바뀌어도 컨트롤 토글 표시가 따라온다 시뮬레이터에는 제어 센터에 컨트롤을 추가할 수단이 없어 빌드·인텐트 메타데이터 등록 확인까지 검증 (실기기에서 배치·토글 확인 필요). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
26 lines
1.0 KiB
Swift
26 lines
1.0 KiB
Swift
//
|
|
// DataChange.swift
|
|
// Haru_Danim
|
|
//
|
|
// 앱 안에서 데이터가 바뀌는 모든 Mutation의 끝단에서 호출하는 공통 갱신 지점.
|
|
// 주기적 백그라운드 새로 고침 대신 변경 이벤트 시점에만 위젯 타임라인을 갱신해
|
|
// WidgetKit 업데이트 예산을 아낀다. (시리/위젯 인텐트 경로는 IntentStore.commit()이 같은 역할)
|
|
//
|
|
|
|
import SwiftData
|
|
import WidgetKit
|
|
|
|
@MainActor
|
|
enum DataChange {
|
|
/// 저장을 즉시 확정(위젯 확장이 같은 App Group 저장소를 읽으므로 autosave를 기다리지 않음)하고
|
|
/// Live Activity → 위젯 타임라인 → 워치 스냅숏 순으로 동기화한다.
|
|
static func commit(context: ModelContext) {
|
|
try? context.save()
|
|
LiveActivityManager.sync(context: context)
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
// 제어 센터 컨트롤의 토글 상태(측정 중 여부)도 함께 갱신
|
|
ControlCenter.shared.reloadAllControls()
|
|
WatchSyncManager.shared.pushSnapshot()
|
|
}
|
|
}
|