app-creator/domain-packs/ios-app/patterns/widget-live-activities-shared-model.md
Kjell Tore Guttormsen 2011507ea1 design(app-creator): S6 — forfatt ios-app referanse-domain-pack + start claude-code-plugin-pakke
- 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>
2026-05-12 14:06:54 +02:00

2.6 KiB

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) 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)
  • 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".