Activity.request()는 성공한다. 반환된 activity의 상태는 active고, 시스템에 등록된 Activity 개수도 1이다. 그런데 잠금화면에도 Dynamic Island에도 아무것도 안 뜬다. 몇 초 뒤 조용히 dismissed로 바뀐다. Xcode 콘솔은 깨끗하다.
위젯 익스텐션이 크래시하고 있었고, 범인은 GeometryReader 한 줄이었다.
왜 콘솔이 깨끗한가
이 문제가 오래 걸린 이유가 여기 있다. 위젯 익스텐션 크래시는 메인 앱의 Xcode 콘솔에 나타나지 않는다. 별도 프로세스이기 때문이다. 앱 입장에서는 API 호출이 전부 성공했으므로 잘못됐다는 신호가 어디에도 없다.
실제로 무슨 일이 벌어지는지는 두 군데를 봐야 보인다.
xcrun simctl spawn <UDID> log show \
--predicate 'process == "WidgetRenderer_Activities"'
여기서 이 두 줄이 반복되고 있으면 확정이다.
Archive was nil. LiveActivity will be empty Couldn't find a placeholder to show
그리고 ~/Library/Logs/DiagnosticReports/에 위젯 익스텐션 이름으로 된 .ips 크래시 리포트가 쌓여 있다. 스택은 이렇게 끝난다.
_assertionFailure → LayoutSubview.place(at:anchor:dimensions:) → GeometryReaderLayout.placeSubviews()
연쇄가 이렇게 이어진다
- 진행 바를 그리는 뷰에서
GeometryReader를 쓴다 - iOS 26 위젯 렌더링 컨텍스트에서
GeometryReaderLayout.placeSubviews()가 assertion failure를 낸다 - 위젯 익스텐션 프로세스가 죽는다
- 시스템이 렌더링 결과 아카이브를 만들지 못한다 (Archive was nil)
- 빈 Live Activity → 시스템이 자동으로 dismiss
앱 쪽에서 보이는 증상(“떴다가 사라진다”)과 실제 원인(“레이아웃 assertion”) 사이의 거리가 이렇게 멀어서, 증상만 보고는 절대 못 찾는다.
고치기
부모 폭을 읽어서 자식 폭을 계산하던 걸, scaleEffect로 비율만 주는 방식으로 바꿨다. 부모 크기를 알 필요가 없어진다.
// Before — 크래시
GeometryReader { geo in
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: 2).fill(Color.white.opacity(0.12))
RoundedRectangle(cornerRadius: 2).fill(color.opacity(0.8))
.frame(width: geo.size.width * progress)
}
}
// After — 정상
RoundedRectangle(cornerRadius: 2).fill(Color.white.opacity(0.12))
.overlay(alignment: .leading) {
RoundedRectangle(cornerRadius: 2).fill(color.opacity(0.8))
.scaleEffect(x: progress, anchor: .leading)
}
.clipShape(RoundedRectangle(cornerRadius: 2))
나중에는 이것도 걷어내고 시스템 ProgressView로 갔다. 커스텀 진행 바는 진행률을 직접 계산해야 하는데, 그 계산이 또 다른 문제를 낳았기 때문이다 — 그 이야기는 카운트다운 네 가지를 다 써본 글에 적었다.
남기는 규칙
- Live Activity 위젯 안에서
GeometryReader를 쓰지 않는다. 부모 크기가 필요해 보이면overlay+scaleEffect, 아니면 시스템 컴포넌트로 돌아간다. - “LiveActivity가 떴다가 사라진다”는 곧 위젯 프로세스 크래시를 의심하라는 신호다. 앱 콘솔이 아니라
WidgetRenderer_Activities시스템 로그와DiagnosticReports를 본다. - 위젯은 앱과 다른 렌더링 컨텍스트에서 돈다. 앱 화면에서 멀쩡한 뷰 코드가 위젯에서 멀쩡하리라는 보장이 없다.
이 글에서 다룬 서비스
아이벤트
아이의 등하교와 학원 일정을 한 화면에 모아주는 iOS 앱입니다. 종이 알림장은 사진 한 장으로 정리되고, 등하원 시간이 다가오면 잠금화면에 실시간 카운트다운이 뜹니다. 완전 무료입니다.