Guideline 2.3.1: skryté funkce a OTA aktualizace
Autor: Mehdi Azizi
Publikováno , 9 min
Guideline 2.3.1: Apple odmítne každou skrytou, spící nebo v poznámkách k revizi nepopsanou funkci. Co můžeš měnit na dálku a co vyžaduje nový build.
Guideline 2.3.1 zakazuje skryté, spící nebo nezdokumentované funkce: všechno, co tvoje appka dělá, musí vidět uživatel i reviewer. Každou novinku musíš přesně popsat v poznámkách k revizi. Aktualizace na dálku může opravit to, co Apple viděl, ale nikdy nesmí přidat nic, co Apple neviděl.
Svoje iOS appky vydávám přes Expo a každá má EAS Update už od prvního buildu, abych mohl posílat opravy. Moje pravidlo: žádná aktualizace na dálku, dokud je verze v revizi. Tenhle návod vychází z textu Applu, jeho licence, dokumentace Expa a zveřejněných zamítnutí.
Co říká guideline 2.3.1?
Pravidlo 2.3.1 otevírá část 2.3 „Accurate Metadata“ v App Review Guidelines, v sekci 2 „Performance“. Text začíná takhle: „Don't include any hidden, dormant, or undocumented features in your app; your app's functionality should be clear to end users and App Review.“ Jinými slovy: nic skrytého, spícího ani nezdokumentovaného.
Další část se týká každého odeslání: „All new features, functionality, and product changes must be described with specificity in the Notes for Review section of App Store Connect (generic descriptions will be rejected) and accessible for review.“ Každou novinku musíš přesně popsat v poznámkách k revizi a reviewer se k ní musí dostat. „Opravy chyb a vylepšení“ tedy nestačí.
Stejný odstavec míří i na klamavý marketing: slibovat obsah nebo službu, která v appce není, nebo uvádět falešnou cenu, ať už v App Storu, nebo jinde.
Tahle část se mi hodila u Nolery. Když jsem před vydáním znovu četl její stránku v obchodě, našel jsem dvě neověřitelné věty: „rozhraní pouze ve francouzštině“, což už neplatilo, a „nejoblíbenější balíček“ u appky, která nikdy nevyšla. Poznámky pro reviewera navíc popisovaly zastaralý stav produktu. Přesně na tohle tahle část míří. Pravidlo 2.3.10 se naopak týká hlavně stránky v obchodě.
Co znamená zpráva o zamítnutí 2.3.1?
Zamítnutí má název „Guideline 2.3.1 - Performance“, někdy s dovětkem „Hidden Features“. Dvě zprávy, které zveřejnili vývojáři v React Native:
- Březen 2024, v GitHub issue u CodePush: „The app contains hidden features.“, bez dalšího upřesnění. Vývojář požádá o podrobnosti a dostane doplnění s odkazem na 2.5.2: „Your app, extension, or linked framework appears to contain code designed explicitly with the capability to change the app's behavior or functionality after App Review approval.“ Z issue není jasné, jestli appka nakonec prošla.
- Únor 2023, v jiném issue, Apple míří na „CodePush-related remote code downloading/updating support“ v binárce.
Jak to čtu já: reviewer nevidí tvoje aktualizace, vidí kód, který je umí přijmout. Oba případy se týkají CodePush. Žádné nedávné veřejné zamítnutí kvůli EAS Update jsem nenašel, což ale nic nedokazuje.
Aktualizace na dálku: co dovoluje 2.5.2 a licence
Pravidlo 2.5.2, o kterém píšu i v návodu k režimům na pozadí, zakazuje appce „download, install, or execute code which introduces or changes features or functionality of the app“.
Článek 3.3.1(B) Apple Developer Program License Agreement zakazuje stažený spustitelný kód, ale upřesňuje: „Interpreted code may be downloaded to an Application“. Za tří podmínek: tento kód nemění hlavní účel appky, neobchází podpis, sandbox ani bezpečnostní prvky systému a nevytváří obchod s jinými appkami.
JavaScript v Expo appce je interpretovaný kód: podle mě do tohoto rámce EAS Update spadá. Jeho dokumentace připomíná, že aktualizace podléhají pravidlům App Storu a že „changes to your app's behavior need to be reviewed“. U kritické chyby Expo doporučuje opravu na dálku a pak nové odeslání, které ji obsahuje.
Moje hranice: opravovat a doladit to, co existuje, ano. Měnit, čím appka je nebo co prodává, ne.
Co můžeš změnit na dálku a co vyžaduje nový build
Tabulka, podle které se řídím, vychází ze stránek Applu a Expa, na které tu odkazuju. Řádek „zdarma se stává placeným“ a poslední dva řádky jsou můj výklad.
| Změna | Cesta | Proč |
|---|---|---|
| Chyba v JavaScriptu | Aktualizace na dálku | Použití, se kterým Expo počítá |
| Text, překlad, styl | Aktualizace na dálku | Použití, se kterým Expo počítá |
| Cena předplatného | App Store Connect | Žádná změna kódu |
| Propagační text | App Store Connect | Bez nového odeslání |
| Nákup už schváleného typu | Revize jen nákupu | Pravidlo App Store Connect |
| První nákup daného typu | Nová verze | Pravidlo App Store Connect |
| Nová funkce | Nová verze | 2.3.1 a 2.5.2 |
| Zdarma se stává placeným | Nová verze | Revidovat stránku a poznámky |
| Oprávnění, Info.plist | Nový build | Soubor v binárce |
| Nativní modul, Expo SDK | Nový build | Změněný nativní kód |
| Přepínač, který vypíná | Vzdálená konfigurace | Tolerováno, pokud dočasně |
| Přepínač, který odhaluje | Zakázáno | Funkce nikdy neprošla revizí |
Propagační text se dá změnit „without requiring an updated submission“, podle stránky Applu o informacích o verzi. První nákup každého typu jde s novou verzí, další už samostatně, podle nápovědy k odesílání nákupů. Expo řadí nativní kód, oprávnění a verzi SDK mezi věci, které vyžadují novou binárku, stejně jako u ITMS-90683. Přepínač, který vypne rozbitou funkci, nepřidává nic nového, pokud neodebírá to, za co předplatitelé zaplatili.
Přepínače na dálku bez zamítnutí
Přepínač na dálku neboli feature flag sám o sobě zakázaný není: záleží na tom, co skrývá. Moje pravidla:
- Všechno, co může přepínač zobrazit, je pro reviewera přítomné a zapnuté a uvedené v poznámkách k revizi.
- A/B test porovnává dvě varianty, které reviewer může vidět, nikdy jednu zrevidovanou a jednu nevídanou.
- Žádný kód nedetekuje revizi, aby se choval jinak. To je přímo definice skryté funkce.
- Paywall řízený na dálku ukazuje jen schválené produkty a každá varianta dodržuje pravidlo 3.1.2.
Demo režim a testovací účty
Guideline 2.1 vyžaduje demo účet, pokud má appka přihlášení, a k tomu běžící server. Pokud ti ho právní nebo bezpečnostní povinnosti nedovolí poskytnout, může ho nahradit vestavěný demo režim, ale jen „with prior approval by Apple“, a musí ukázat všechny funkce. Stránka Applu o informacích o verzi dodává: účet nesmí vypršet a další účty patří do poznámek, které mají limit 4 000 bajtů.
Souvislost s 2.3.1: demo režim nebo testovací účet, který otevírá jinak neviditelné obrazovky, musí být popsaný. Tajné gesto, kód nebo speciální účet, o kterém nikomu neřekneš, je skrytá funkce. Každý speciální přístup uveď v poznámkách i s tím, co otevírá.
Moje pravidlo: žádná aktualizace na dálku během revize
Proč mám EAS Update všude: v Solys, mém budíku, způsobila chyba v JavaScriptu, že appka ztichla, jakmile se jednou nepovedlo přehrát zvuk. Oprava měla tři řádky, ale k jejímu doručení byl potřeba celý build a revize. Od té doby mají všechny moje appky expo-updates od prvního buildu: je to nativní modul, takže binárka zkompilovaná bez něj nikdy nic nedostane. Moje konfigurace v app.json:
{
"expo": {
"runtimeVersion": { "policy": "fingerprint" },
"updates": { "fallbackToCacheTimeout": 0, "checkAutomatically": "ON_LOAD" }
}
}
S fingerprint se aktualizace dostane jen k binárkám, jejichž nativní kód odpovídá (runtime verze). Ale dokud verze čeká na revizi nebo v ní je, nevydávám nic. Ze dvou důvodů.
- Reviewer by opravu neviděl. S
fallbackToCacheTimeoutna 0 nová instalace startuje s vestavěným kódem a aktualizaci použije až při dalším spuštění (dokumentace expo-updates). Reviewer nainstaluje, jednou spustí a testuje binárku. Nolera byla zamítnutá, přestože oprava už byla doručená na dálku: popisuju to v návodu k 2.1. - To, co reviewer testuje, musí zůstat tím, co dostanou uživatelé. Změna chování během revize vytváří rozdíl mezi viděnou a doručenou verzí.
Přesné poznámky k revizi
Pravidlo 2.3.1 odmítá obecné popisy. Šablona, kterou bych použil, v angličtině:
What's new in this version:
- [Feature]: [where to find it, how to test it].
Remote configuration:
- "[flag]" controls [feature]. It is ON for review.
Over-the-air updates:
- The app uses expo-updates for bug fixes only.
No update will be published during this review.
Demo account: see Sign-in information. It never expires.
Jak odpovědět na zamítnutí 2.3.1?
Odpověz v App Store Connect, kde odpovídáš na zprávu od App Review.
- Zpráva je vágní: zeptej se, o jakou funkci jde, stejně jako vývojář v issue z roku 2024.
- Skutečná funkce je špatně popsaná: uveď přesnou cestu a krátké video, pak doplň poznámky.
- Přepínač odhaluje něco nového: odstraň ho, nebo ho zapni a popiš, a pak udělej nový build.
- Problém je v kódu pro aktualizace: vysvětli, že slouží k opravám v rámci článku 3.3.1(B). V issue z roku 2023 Apple žádal jeho odstranění.
Checklist 2.3.1 před odesláním
- Každá novinka verze je popsaná v poznámkách i s cestou k ní.
- Každý přepínač na dálku je pro revizi zapnutý a uvedený v poznámkách.
- Žádný kód nemění chování kvůli reviewerovi.
- Speciální přístupy jsou popsané: demo režim, testovací účet, gesto.
- Stránka v obchodě ani paywall neslibují nic, co build nedělá.
- Během revize nevydáváš žádnou aktualizaci na dálku.
Zkontroluj svoje podklady před odesláním
Review Kit obsahuje můj checklist před odesláním, šablony poznámek pro testera a Claude Code skills, které projdou tvůj projekt. Pokud chceš lidský pohled, zarezervuj si se mnou hodinu: projdeme spolu přes video tvoje poznámky k revizi a nastavení aktualizací. Celý postup najdeš na stránce appka zamítnutá Applem.
Chystáš své první vydání? Udělej si bezplatnou diagnostiku: seřadí ti kroky ve správném pořadí a pošle ti můj checklist proti zamítnutí od Applu.
Časté dotazy
Co znamená „Guideline 2.3.1 - Performance - Hidden Features“?
Apple usoudil, že tvoje appka obsahuje skrytou, spící nebo v poznámkách k revizi chybějící funkci. Zpráva může mířit i na kód, který umí appku po revizi změnit, někdy spolu se zamítnutím 2.5.2.
Povoluje Apple EAS Update?
Licence povoluje stažený interpretovaný kód, pokud nemění hlavní účel appky. Opravovat ano. Přidat funkci, která neprošla revizí, ne.
Dají se v iOS appce používat feature flagy?
Ano, pokud všechno, co mohou zobrazit, prošlo revizí. Pro revizi každý přepínač zapni a popiš ho v poznámkách.
Musím reviewerovi oznámit demo režim?
Ano. Vestavěný demo režim vyžaduje předchozí souhlas Applu a musí ukázat všechny funkce.
Můžu během revize vydat aktualizaci na dálku?
Černé na bílém to nikde zakázané není. Reviewer by ji ale při prvním spuštění neviděl a vzniká tím rozdíl oproti zrevidované verzi. Já se tomu vždycky vyhýbám.

