- 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>
38 lines
4.2 KiB
Markdown
38 lines
4.2 KiB
Markdown
<!-- domain-pack: ios-app · component: gotchas · core -->
|
|
<!-- verified 2026-05-12 against Apple Developer docs + App Store Review Guidelines. -->
|
|
|
|
# iOS-app — gotchas ("ikke gjør dette")
|
|
|
|
Ting som ser riktige ut men ikke er det. Hver av disse har avvist en app eller krasjet en bygging.
|
|
|
|
## App Store-innsending
|
|
|
|
- **Manglende `NSUsageDescription` for en beskyttet ressurs.** Appen termineres *umiddelbart* (ingen dialog) når permission etterspørres, og innsendingen avvises (Guideline 5.1.1). Gjelder Core Location, kamera, mikrofon, foto-bibliotek, kontakter, kalender, Bluetooth, Face ID m.fl. **Gjelder IKKE notifikasjoner** — `UNUserNotificationCenter.requestAuthorization` trenger ingen Info.plist-nøkkel.
|
|
- **Manglende eller ufullstendig `PrivacyInfo.xcprivacy`.** Påkrevd siden 2024-05-01. Spesielt: ikke-deklarerte **required-reason-API-er** (file-timestamp, system-boot-time, disk-space, active-keyboard, user-defaults m.fl.) → avvisning (Guideline 5.3.4). Tredjeparts-SDK-er må levere *sin egen* privacy-manifest — sjekk dem.
|
|
- **`NSAllowsArbitraryLoads = true` uten begrunnelse.** App Review krever forklaring på brede ATS-unntak; "vi trengte det" holder ikke. Bruk `NSExceptionDomains` per-domene i stedet, og bare hvis nødvendig.
|
|
- **"Minimum functionality" (Guideline 4.2).** En ren web-wrapper, en app som er for tynn, eller en app som "ikke gjør nok native" avvises. En liten fokusert app er greit *hvis* den gjør noe meningsfullt nativt.
|
|
- **Unøyaktig metadata / villedende skjermbilder (Guideline 1.2 / 2.3).** Skjermbilder må vise faktisk UI. Beskrivelse må stemme med funksjonalitet.
|
|
- **Digitale varer utenfor IAP (Guideline 3.1.1).** Engangs-betalt app (paid-up-front) er greit; men låser appen opp digitalt innhold *etter* installasjon mot betaling, skal det gå via In-App Purchase.
|
|
- **Tredjeparts-AI / data-deling ikke deklarert (Guideline 5.1.2).** Sender appen brukerdata til en ekstern AI-tjeneste, må det fram i App Privacy Details — stricter håndhevet siden 2025.
|
|
- **Alders-spørreskjemaet ikke fullført.** Det reviderte alders-rating-systemet (4+/9+/12+/13+/16+/18+) krevde fullført spørreskjema innen 2026-01-31; nye innsendinger må ha det utfylt.
|
|
- **Glemt region-krav** (hvis du distribuerer der): EU DSA trader-status (verifisert kontaktinfo, ellers fjernes appen fra EU App Store); Kina ICP-filing-nummer (krever kinesisk juridisk enhet + server); Sør-Korea GRAC-rating for spill. Se `checklist.md`.
|
|
- **Eksport-compliance ikke besvart.** Bruk av kryptering (inkl. HTTPS via standard-API-er regnes vanligvis som unntatt, men spørsmålet *må* besvares) — `ITSAppUsesNonExemptEncryption` i Info.plist eller svar i App Store Connect.
|
|
|
|
## SwiftUI / SwiftData / extensions
|
|
|
|
- **Anta ikke sanntids-synk mellom app- og widget-prosess.** App Group-delt store er kilden, men oppdateringstiming er strammere på iOS 17 enn iOS 18+. Trigg `WidgetCenter.reloadTimelines` eksplisitt.
|
|
- **Glem ikke `NSSupportsLiveActivities = YES`** i *hoved-app-ens* Info.plist (ikke widget-extension-ens). Uten den fungerer ikke Live Activities — og det feiler stille.
|
|
- **Hopp ikke over SwiftData-migrasjonsplan.** En uplanlagt `@Model`-endring etter lansering kan tvinge destruktiv migrasjon (brukeren mister data).
|
|
- **Overskrid ikke extension-minnebudsjettet** (≈30 MB-klassen) i widget/Live-Activity-kode — store containere/tunge beregninger der crasher extension.
|
|
- **Bruk `if #available` for nyere API-er** — ellers krasjer appen på enheter med eldre deployment target.
|
|
|
|
## Lokasjon & permission
|
|
|
|
- **Be ikke om "Always"-lokasjon** når "When In Use" holder — review-friksjon og brukermistillit; Settings → Privacy avslører det.
|
|
- **Be ikke om permission ved første launch** uten kontekst — forklar på en onboarding-skjerm først (review forventer det; bedre conversion).
|
|
- **Etterlat ikke en tom/dead-end-skjerm** når permission nektes — ha en fallback (siste kjente posisjon / manuell input / degradert modus).
|
|
|
|
## Generelt
|
|
|
|
- **`iOS 19` finnes ikke.** Apple gikk fra iOS 18 til iOS 26 (WWDC 2025). Refererer en spec/brief "iOS 19", er det en feil — mener sannsynligvis iOS 26 (gjeldende) eller iOS 27 (høst 2026).
|
|
- **`UserDefaults` er ikke et hemmelig-lager.** Sensitiv data → Keychain (MASVS-STORAGE). Se `checklist-security-privacy.md`.
|