- domain-packs/ios-app/: komplett referanse-pakke (8 komponenter) — pack.json med components-map, conventions.md, 4 patterns/, gotchas.md, checklist.md splittet i 3 (App Store-submission + security-privacy/MASVS 2.1 + accessibility/WCAG 2.2 AA), 3 scaffold/-maler (PrivacyInfo.xcprivacy-plist, NSUsageDescription-inventar, ASC-metadata), eksempel-feature-brief i Voyage strict-mode-format, glossary.md. Hver teknisk påstand verifisert mot Apple Developer / W3C WAI / OWASP MAS. - domain-packs/claude-code-plugin/: stub — pack.json + conventions.md + gotchas.md + checklist.md + glossary.md ferdige (ekstrahert fra ktg-privat-konvensjoner); patterns/scaffold/examples er stubs. - docs/domain-pack-spec.md: § D2/D3/D4/D7 + restrisiko oppdatert — pack.json components-felt, core/supplementary låst til manifestet, checklist-splitt-konvensjon, snapshot-materialiserings-mekanikk presisert, iOS-versjons-korreksjon (iOS 26, ikke "iOS 18/19"), D7 → "forfattet i S6". - prototype-run/friksjon.md: #9 (Akashic-briefen refererer "iOS 19" som ikke finnes — rettes i S7) + S6-prosessnotater (checklist-splitt bekreftet nødvendig, components-gap fylt, verifiserings-asymmetri ios-app vs claude-code-plugin notert). - CLAUDE.md: peker til domain-packs/ under § Status. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
29 lines
2.6 KiB
Markdown
29 lines
2.6 KiB
Markdown
<!-- domain-pack: ios-app · component: patterns · supplementary -->
|
|
<!-- verified 2026-05-12 against WidgetKit / ActivityKit docs (Live Activities iOS 16.1+). -->
|
|
|
|
# Pattern: app + widget + Live Activity deler én datamodell
|
|
|
|
**Når:** funksjonalitet vises på hjemskjerm-widget, låseskjerm og/eller Dynamic Island — som *presentasjonslag på samme kjerne-data*, ikke fire uavhengige delsystemer.
|
|
|
|
## Arkitektur-prinsipp
|
|
|
|
Modeller én gang. App, widget-extension og Live Activity leser **samme delte tilstand** via en **App Group**-container. Widgeten og Live Activity-en eier *ikke* egen kopi av forretningslogikken — de rendrer et snapshot.
|
|
|
|
## Mekanikk
|
|
|
|
- **App Group:** legg til App Group-capability (`group.<bundle-id>`) på *både* app-target og widget-extension-target.
|
|
- **Delt SwiftData-store:** `ModelConfiguration(... , groupContainer: .identifier("group.<bundle-id>"))` → samme `ModelContainer` i begge targets. Widgeten legger `.modelContainer(...)` på sin `WidgetConfiguration`. ([Hacking with Swift — SwiftData i widgets](https://www.hackingwithswift.com/quick-start/swiftdata/how-to-access-a-swiftdata-container-from-widgets)) Alternativ for enkle verdier: delt `UserDefaults(suiteName:)`.
|
|
- **Widget-refresh:** `WidgetCenter.shared.reloadTimelines(ofKind:)` fra appen når data endres; ellers timeline-baserte oppdateringer. Vær konservativ — WidgetKit-refresh-budsjettet er begrenset.
|
|
- **Live Activities (iOS 16.1+):** ActivityKit + en WidgetKit-extension. Krever `NSSupportsLiveActivities = YES` i **hoved-app-ens** Info.plist (ikke extension-ens). Vises på låseskjerm + Dynamic Island (Dynamic Island: iPhone 14 Pro+ / standard på iPhone 15+; eldre enheter får bare låseskjerm-presentasjonen). `ActivityAttributes` definerer statisk + dynamisk innhold; oppdater via `activity.update(...)`, avslutt via `activity.end(...)`. ([Live Activities — GitHub iOS16-Live-Activities](https://github.com/1998code/iOS16-Live-Activities))
|
|
- **Opt-in:** Live Activities / Lock Screen-features bør være noe brukeren slår på, ikke noe som dukker opp uoppfordret.
|
|
|
|
## Fallgruver
|
|
|
|
- **Ikke** dupliser forretningslogikk inn i extension — beregn i appen / et delt framework, del bare resultatet.
|
|
- **Ikke** anta sanntids-synk app↔extension; oppdateringstiming er strammere på iOS 17 enn iOS 18+.
|
|
- **Ikke** overskrid extension-minnebudsjettet (≈30 MB-klassen) — hold widget/Live-Activity-koden lett.
|
|
- **Glem ikke** `NSSupportsLiveActivities` — uten den fungerer ikke Live Activities, og det feiler stille.
|
|
|
|
## App-brief-signal
|
|
|
|
"Widget på hjemskjerm", "Live Activities / låseskjerm-countdown", "samme kjerne-datamodell", "Dynamic Island".
|