- 실기기 판독: 진동은 끝까지 정시 = 앱 생존, 그러나 국면 라벨·횟수는 항상 4번째 전송(수축 2회차)에서 동결 + 진행바만 흐름 → 백그라운드 Activity.update를 시스템이 예산제로 폐기하는 것으로 확정. staleDate 재렌더도 미발화(시뮬 실측) - 설계 전환: ContentState = 세트 일정뿐, 시작 시 1회 등록(ensureStarted) 후 update 호출 0회. 화면은 시스템 렌더(국면 색 타임라인 바+플레이헤드+남은 시간)와 영원히 참인 정적 정보(수축·이완 범례, 세트 구성)만 — 동결할 데이터 자체가 없음 - 컴팩트 = 미니 타임라인+남은 시간, 미니멀 = 국면 두 색 점. 국면 라벨·횟수 텍스트는 LA에서 제거(국면=진동+플레이헤드 색, 횟수=앱) - 통계 타임라인 점별 시각 라벨 제거(겹침), 도움말·번역 갱신, CLAUDE.md 현행화 - 시뮬: 등록 후 갱신 없이 35초간 4:57→4:27 정확 진행·완주 시 DI 해제 확인 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPmp29DQHY6Ahfss5SRopT
37 lines
1.4 KiB
Swift
37 lines
1.4 KiB
Swift
//
|
||
// KegingActivityAttributes.swift
|
||
// Keging
|
||
//
|
||
// Live Activity(다이나믹 아일랜드) 상태 — 앱·위젯 두 타깃에 동일 파일로 컴파일.
|
||
//
|
||
// ⚠️설계 원칙(실기기 5차 확정): 백그라운드 Live Activity 갱신은 시스템이 예산제로
|
||
// 버리고(실측: 4번째부터), staleDate가 지나도 재렌더가 보장되지 않는다(시뮬 실측).
|
||
// 그래서 상태는 **세트 일정뿐** — 시작할 때 한 번 등록하면 갱신이 아예 필요 없고,
|
||
// 위젯은 전부 시스템 렌더 요소(타임라인 바·플레이헤드·남은 시간)로만 그린다.
|
||
// 애플 시계 앱 타이머와 같은 모델: 갱신할 데이터가 없으니 멈출 수도 없다.
|
||
//
|
||
|
||
#if canImport(ActivityKit)
|
||
import ActivityKit
|
||
import Foundation
|
||
|
||
nonisolated struct KegingActivityAttributes: ActivityAttributes {
|
||
nonisolated struct ContentState: Codable, Hashable {
|
||
// 자가 렌더링용 전체 일정 — 버튼 누른 시각부터 결정적
|
||
var sessionStart: Date
|
||
var prepSeconds: Int
|
||
var contractSeconds: Int
|
||
var relaxSeconds: Int
|
||
var totalReps: Int
|
||
|
||
var sessionEnd: Date {
|
||
sessionStart.addingTimeInterval(
|
||
Double(prepSeconds + totalReps * (contractSeconds + relaxSeconds))
|
||
)
|
||
}
|
||
}
|
||
|
||
var startedAt: Date = Date()
|
||
}
|
||
#endif
|