# ITMS-90338: oprava „Non-public API usage“ v Expo

> ITMS-90338: tvoj build obsahuje metódu, funkciu alebo triedu, ktorú Apple považuje za súkromnú. Nájdi príslušnú závislosť, aktualizuj ju a sprav nový build.

Pôvodná stránka: [ITMS-90338: oprava „Non-public API usage“ v Expo](https://devoria.fr/sk/blog/itms-90338-non-public-api-usage-expo)
Autor: [Mehdi Azizi](https://devoria.fr/sk/mehdi-azizi)
Zverejnenie: 2026-11-04
Posledná revízia obsahu: 2026-11-04


ITMS-90338 je automatická kontrola tvojho buildu zo strany Apple. Hovorí, že tvoj binárny súbor odkazuje na API, ktoré Apple považuje za súkromné: metódy Objective-C, funkcie alebo triedy. **Oprava: nájdi súbor uvedený v e-maile, dostaň sa k závislosti, ktorá ten názov obsahuje, aktualizuj ju alebo premenuj svoju metódu a potom sprav nový build.**

V Expo pochádza ten názov takmer vždy z natívnej knižnice, len zriedka z tvojho JavaScriptu. 15. októbra 2026 som spustil analytické príkazy z tohto návodu na simulátorovom builde Solys, môjho budíka s minihrami (Expo SDK 57), a na iOS SDK z Xcode 26.2. Ukážem ti, ako čítať e-mail, nájsť vinníka a rozpoznať falošný poplach.

## Čo znamená chyba ITMS-90338?

Správa má názov „ITMS-90338: Non-public API usage“. Existuje v troch variantoch podľa toho, čo Apple v tvojom binárnom súbore našiel:

- **„references non-public selectors“**: názvy metód Objective-C, napríklad `boldFontOfSize:`;
- **„references non-public symbols“**: funkcie, zapísané s podčiarkovníkom na začiatku, napríklad `__dyld_get_shared_cache_range`;
- **„contains or inherits from non-public classes“**: názov triedy.

Každý variant uvádza cestu a potom zoznam názvov. Text pridáva dve rady: premenovať svoje metódy, ak sa ich názov zhoduje so súkromným API, a odstrániť statickú knižnicu, ktorá ich obsahuje. E-mail zo septembra 2026 navrhuje aj `xcrun swift-demangle` na sprehľadnenie zakódovaných Swift názvov.

Pravidlo za touto kontrolou je [guideline 2.5.1](https://developer.apple.com/app-store/review/guidelines/#2.5.1): aplikácia smie používať iba verejné API. [Licenčná zmluva Apple Developer Program](https://developer.apple.com/support/terms/apple-developer-program-license-agreement/) to opakuje v článku 3.3.1: žiadne volanie súkromného API. Ľudskú kontrolu tohto pravidla podrobne rozoberá návod ku [guideline 2.5.1](https://devoria.fr/sk/blog/guideline-2-5-1-verejne-api-sdk-expo). Tu riešime chybu pri odosielaní.

Rovnako ako pri iných chybách ITMS tvoju appku nikto neotvoril: Apple analyzoval binárny súbor počas spracovania buildu. **Apple nezverejňuje žiadny zoznam súkromných API: názvy v tvojom e-maile sú jediný spoľahlivý zoznam.**

## Čítanie cesty: SDK, alebo tvoj spustiteľný súbor?

Cesta pred zoznamom ti povie, v ktorom súbore hľadať.

- **`Frameworks/Nom.framework/Nom`**: názov je v pribalenom dynamickom frameworku, teda v konkrétnom SDK. V builde Solys obsahuje tento priečinok 14 frameworkov: Hermes, React Native, predkompilované moduly Expo a knižnicu na obrázky SDWebImage.
- **Iba názov tvojej appky**: názov je v hlavnom spustiteľnom súbore. V Expo spája tvoj natívny kód a pody skompilované zo zdrojákov, predvolene linkované staticky. Vinníkom tak môže byť ktorákoľvek natívna knižnica.

## Strom: od uvedeného názvu k oprave

Choď po riadkoch v poradí. Prvý, ktorý sedí na tvoj prípad, ti dá stopu.

| Čo vidíš                     | Kde hľadať                | Oprava                         |
| ---------------------------- | ------------------------- | ------------------------------ |
| Názov s `$s` alebo `_$s`     | `xcrun swift-demangle`    | Prejdi strom znova             |
| Nenájdený v tvojom IPA       | `grep` v bundli           | Pošli build znova              |
| Verejný názov na iOS         | Hlavičky iOS SDK          | Pošli build znova              |
| `API_UNAVAILABLE(ios)`       | Hlavičky iOS SDK          | Aktualizuj balík               |
| V `Frameworks/X`             | SDK, ktoré dodáva X       | Aktualizuj SDK                 |
| Selektor, tvoja appka        | Pody a natívne moduly     | Pridaj prefix alebo aktualizuj |
| Symbol `_nazov`, tvoja appka | `nm -m`, potom pody       | Nahraď volanie                 |
| Trieda, tvoja appka          | Tvoje triedy a tvoje pody | Pridaj triede prefix           |

Riadky „Pošli build znova“ označujú falošný poplach, ktorému sa venujem nižšie.

## Krok 1: otvor odoslaný build

Pracuj so súborom, ktorý si naozaj poslal Apple, nie so svojím projektom. Stiahni IPA zo stránky buildu na expo.dev a na Macu spusti:

```bash
unzip -q MyApp.ipa -d ipa
ls ipa/Payload/MyApp.app/Frameworks
otool -L ipa/Payload/MyApp.app/MyApp | grep PrivateFrameworks
```

Druhý riadok vypíše pribalené frameworky. Tretí hľadá priamy odkaz na súkromný framework Apple: nesmie nič vypísať. Pri Solys `otool -L` nenájde žiadny súkromný framework, ani v spustiteľnom súbore, ani v 14 frameworkoch.

## Krok 2: nájdi súbor, ktorý obsahuje názov

Začni zoširoka. Hľadaj uvedený názov bez úvodných podčiarkovníkov v celom bundli:

```bash
grep -rl "dyld_get_shared_cache_range" ipa/Payload/MyApp.app
```

Príkaz vypíše súbory, ktoré tento text obsahujú. Potom hľadanie spresni podľa typu názvu (selektor, symbol, trieda) v nájdenom súbore, označenom ako `Binaire`:

```bash
strings -a Binaire | grep -x "boldFontOfSize:"
nm -m Binaire | grep "_dyld_get_shared_cache_range"
nm -m Binaire | grep '_OBJC_CLASS_$_NomDeClasse'
```

**Na selektor použi `strings`, nie `nm`.** Vo frameworku React v Solys `nm` zobrazuje metódy aj s triedou, napríklad `-[RCTRootView initWithBridge:moduleName:initialProperties:]`, nikdy samotný selektor `initWithBridge:`. `strings` ho nájde.

Pri symbole čítaj koniec riadka. V Solys `nm -m` zobrazí napríklad `(undefined) external __dyld_get_image_name (from libSystem)`: binárny súbor funkciu volá, ale neobsahuje ju, dodáva ju libSystem. Táto konkrétna funkcia je verejná, ako ukazuje ďalší krok.

## Krok 3: over, či je názov naozaj súkromný

Hlavičky iOS SDK opisujú verejné API. Pár sekúnd hľadania ti povie, či v nich uvedený názov je a na ktorých platformách. Pri symbole najprv odstráň podčiarkovník pridaný pri kompilácii: z `_SCDynamicStoreCreate` bude `SCDynamicStoreCreate`.

```bash
SDK=$(xcrun --sdk iphoneos --show-sdk-path)
grep -rn "SCDynamicStoreCreate" "$SDK/usr/include" "$SDK"/System/Library/Frameworks/*/Headers
```

15. októbra 2026 s iOS SDK 26.2 dali štyri názvy zo skutočných e-mailov ITMS-90338 tento výsledok:

| Uvedený názov                 | V iOS SDK            | Výklad                 |
| ----------------------------- | -------------------- | ---------------------- |
| \_dyld_get_shared_cache_range | Chýba                | Súkromné API           |
| boldFontOfSize:               | Chýba                | Súkromné alebo kolízia |
| SCDynamicStoreCreate          | API_UNAVAILABLE(ios) | Iba macOS              |
| isMainFrame                   | Vlastnosť WebKitu    | Verejné                |

**Názov, ktorý tam je a je dostupný na iOS, ukazuje na falošný poplach. Chýbajúci názov ukazuje na súkromné API alebo kolíziu.** Dve obmedzenia: verejné API dostupné iba vo Swifte sa v týchto hlavičkách neobjaví a pri accessore ako `setDelegate:` hľadaj vlastnosť `delegate`.

## Krok 4: dostaň sa k balíku

Ak cesta uvádza framework, jeho názov ťa dovedie k podu a potom k npm balíku:

```bash
grep -n "NomDuFramework" ios/Podfile.lock
npm explain nom-du-paquet
```

`npm explain` ti povie, ktorá závislosť ho nainštalovala, ak si ho nikdy nepridal sám.

Ak cesta uvádza spustiteľný súbor, hľadaj názov v natívnych zdrojákoch a potom v podoch:

```bash
grep -rl --include='*.m' --include='*.mm' --include='*.swift' --include='*.h' \
  "boldFontOfSize" node_modules modules
grep -rl "boldFontOfSize" ios/Pods
```

Zoznam priečinkov si uprav: `modules` je priečinok lokálnych modulov Expo. Priečinok `ios/Pods` sa objaví po `npx expo prebuild -p ios`, ktorý na Macu nainštaluje aj pody. Pozor: tento príkaz môže priečinok `ios` vytvoriť nanovo. Ak si ho upravoval ručne, pracuj na kópii.

**Hľadanie v `ios/Pods` je rovnako dôležité ako hľadanie v zdrojákoch.** V Solys obsahuje tento priečinok 15 predkompilovaných frameworkov vo formáte `.xcframework`: moduly Expo, Hermes, React Native a SDK tretích strán. Hľadanie obmedzené na zdrojové súbory by ich kód minulo.

## Typické príčiny

**SDK tretej strany, príliš staré alebo príliš nové.** V septembri 2026 jeden Flutter vývojár [nahlásil zamietnutie kvôli bezpečnostnému SDK](https://github.com/talsec/Free-RASP-Flutter/issues/236): jeho verzia 8.2.3 volala `__dyld_get_shared_cache_range`. Verzia 8.2.2 prešla a vydavateľ odporučil vrátiť sa k nej, kým nebude oprava.

**Natívny modul, ktorý volá nezdokumentované API.** Tvoj vlastný modul, plugin alebo malá knižnica môže používať internú metódu UIKitu nájdenú na fóre. Kontrola ju odhalí podľa názvu.

**Kolízia názvov.** Tvoja metóda alebo trieda náhodou nesie názov súkromného API Apple. Správa s tým počíta a žiada ťa ju premenovať. Apple odporúča [pridávať prefix k metódam pridaným do jeho tried](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html), napríklad tri malé písmená a za nimi podčiarkovník.

**API verejné na macOS, nie na iOS.** V roku 2024 bola appka v .NET MAUI [zamietnutá kvôli `_SCDynamicStoreCreate`](https://github.com/dotnet/runtime/issues/103949). Apple túto funkciu dokumentuje, ale [iba pre macOS](https://developer.apple.com/documentation/systemconfiguration/1437828-scdynamicstorecreate), a hlavička iOS SDK ju označuje `API_UNAVAILABLE(ios, tvos, watchos)`.

## Oprav to, neobchádzaj

1. **Aktualizuj závislosť.** Pri balíkoch, ktoré Expo sleduje, `npx expo install --check` upozorní na tie, ktoré nesedia s tvojím SDK, podľa [dokumentácie Expo CLI](https://docs.expo.dev/more/expo-cli/). Pri ostatných si prečítaj changelog.
2. **Vráť sa k predchádzajúcej verzii**, ak názov priniesla tá nová, a daj vedieť vydavateľovi.
3. **Nahraď alebo odstráň** opustenú knižnicu.
4. **Premenuj** svoju metódu alebo triedu a pridaj jej prefix.

**Názov neskrývaj.** Rozdelenie reťazca alebo volanie metódy oklukou použitie skryje, ale neopraví. Stále ho zakazuje pravidlo 2.5.1 aj zmluva, a riziku je potom vystavený tvoj účet.

Potom sprav nový build s novým [číslom buildu](https://devoria.fr/sk/blog/app-store-connect-build-number-verzia-cislo-buildu). Aktualizácia na diaľku nestačí: názov je v skompilovanom natívnom kóde. Pred odoslaním spusti krok 2 znova na novom IPA. Názov sa už nesmie objaviť.

## Keď ide o falošný poplach

Kontrola Apple sa niekedy mýli. 6. júna 2022 dostali React Native a Flutter appky ITMS-90338 kvôli verejným názvom z WebKitu, ako `setNavigationDelegate:` alebo `isMainFrame`, a to aj pri takmer nezmenených aktualizáciách. Na druhý deň inžinier Apple napísal, že problém je na strane validácie vyriešený, a vyzval na opätovné odoslanie buildov. Vlákno je uložené v [GitHub repozitári Expo](https://github.com/expo/expo/issues/17768).

Na falošný poplach ukazujú tri indície naraz:

- build sa podobá na posledný prijatý build;
- krok 2 názov nenájde alebo krok 3 ukáže, že je na iOS verejný;
- ostatní vývojári hlásia v ten istý deň rovnakú chybu na fórach Apple.

V takom prípade pozri [stav služieb Apple](https://developer.apple.com/system-status/) a potom pošli build znova s novým číslom. Ak chyba pretrváva, napíš [podpore pre vývojárov Apple](https://developer.apple.com/contact/) a prilož celý e-mail. Kolízia názvov však v očiach Apple falošný poplach nie je: premenuj.

## Pred ďalším odoslaním

Aj ostatné chyby ITMS majú svoj návod: [ITMS-90725](https://devoria.fr/sk/blog/itms-90725-sdk-version-issue-expo) pre verziu Xcode, [ITMS-91053](https://devoria.fr/sk/blog/itms-91053-missing-api-declaration-expo) pre privacy manifest a [ITMS-90034](https://devoria.fr/sk/blog/itms-90034-missing-or-invalid-signature-oprava) pre podpis. Keď je build prijatý, pred kontrolou si ho nainštaluj cez [TestFlight](https://devoria.fr/sk/blog/testflight-otestovat-iphone-aplikaciu).

Zamietnutia od reviewera si vyžadujú viac nadhľadu: postup nájdeš na stránke [appka zamietnutá Apple](https://devoria.fr/sk/expertise/aplikacia-zamietnuta-apple) a najčastejšie dôvody v článku [prečo Apple zamieta appky](https://devoria.fr/sk/blog/zamietnutie-aplikacie-apple-pricina).

Na kontrolu tvojich podkladov pred odoslaním je tu [Review Kit](https://devoria.fr/sk/kits/app-review): obsahuje môj checklist a skills pre Claude Code, ktoré prejdú tvoj projekt. Ak sa ti odosielanie zasekne a chceš ľudský pohľad, [rezervuj si so mnou hodinu](https://devoria.fr/sk/coaching): prejdeme tvoj projekt cez videohovor, na tvojej obrazovke. A ak chystáš svoje prvé vydanie, [sprav si bezplatnú diagnostiku](https://devoria.fr/sk/diagnostic): zoradí kroky do správneho poradia a pošle ti môj checklist proti zamietnutiu od Apple.

## Často kladené otázky

### Je ITMS-90338 zamietnutie od App Review?

Nie. Je to automatická kontrola počas spracovania buildu, ešte pred akoukoľvek ľudskou kontrolou. Zamietnutý build sa nedostane ani do TestFlightu, ani na kontrolu. Súkromné API, ktoré neskôr odhalí reviewer, spadá pod guideline 2.5.1.

### Dá sa ITMS-90338 opraviť aktualizáciou na diaľku?

Nie. Uvedené názvy sú v skompilovanom natívnom kóde binárneho súboru. Aktualizácia na diaľku mení iba JavaScript a zdroje. Oprav závislosť, sprav nový build a pošli ho znova.

### Prečo Apple uvádza metódy, ktoré som nikdy nenapísal?

Pretože pochádzajú z pribalenej knižnice alebo z kolízie: niektorá závislosť deklaruje metódu s názvom súkromného API. Apple číta názvy v binárnom súbore, nie tvoj zdrojový kód. K balíku sa dostaneš cez `grep` a `npm explain`.

### Ako zistím, či je API na iOS verejné?

Vyhľadaj jeho názov v hlavičkách iOS SDK, ktorých cestu ti dá `xcrun --sdk iphoneos --show-sdk-path`, a pozri si jeho dostupnosť. Uvádza ju aj stránka dokumentácie Apple. Funkcia zdokumentovaná iba pre macOS nie je na iPhone verejná.

### Treba po oprave zmeniť číslo buildu?

Áno. Nechaj EAS, nech ho zvýši: číslo, ktoré už bolo pre tú istú verziu odoslané, môže byť zamietnuté s chybou ITMS-90189.


## Tvoj projekt

[Review Kit](https://devoria.fr/sk/kits/app-review): Môj checklist na App Store review, moje opravené zamietnutia od Apple, checklist pre Google Play a tri skilly pre Claude Code. 49 €.

[iOS & Android Kit](https://devoria.fr/sk/kits/ios): Vytvor si appku pre iPhone a Android s Claude Code: štartovací kód mojich appiek, cesta až do obchodov a všetky kity. 99 €.

[Diagnostika: čo ťa delí od tvojej iPhone appky](https://devoria.fr/sk/diagnostic): 7 otázok, 60 sekúnd: zistíš, čo ti naozaj bráni zverejniť tvoju iPhone appku, dostaneš cestu v 4 krokoch a kit, ktorý ti sedí.
