# ITMS-90338 javítása: Non-public API usage Expóval

> ITMS-90338: a buildod egy Apple szerint privát API-ra hivatkozik. Keresd meg a hibás függőséget, frissítsd, és buildeld újra.

Eredeti oldal: [ITMS-90338 javítása: Non-public API usage Expóval](https://devoria.fr/hu/blog/itms-90338-non-public-api-usage-expo)
Szerző: [Mehdi Azizi](https://devoria.fr/hu/mehdi-azizi)
Megjelenés: 2026-11-04
A tartalom utolsó frissítése: 2026-11-04


Az ITMS-90338 az Apple automatikus ellenőrzése, ami a buildodon fut le. Azt jelenti, hogy a binárisod olyan API-kra hivatkozik, amelyeket az Apple privátnak tart: Objective-C metódusokra, függvényekre vagy osztályokra. **A javítás: keresd meg az e-mailben megnevezett fájlt, kövesd vissza a nevet tartalmazó függőségig, frissítsd azt vagy nevezd át a saját metódusodat, aztán készíts új buildet.**

Expónál a név szinte mindig egy natív könyvtárból jön, ritkán a JavaScript-kódodból. 2026. október 15-én lefuttattam az útmutató elemző parancsait a Solys (az ébresztőórám minijátékokkal, Expo SDK 57) szimulátoros buildjén és a Xcode 26.2 iOS SDK-ján. Megmutatom, hogyan olvasd az e-mailt, hogyan találd meg a bűnöst, és hogyan ismerd fel a téves riasztást.

## Mit jelent az ITMS-90338 hiba?

Az üzenet címe: „ITMS-90338: Non-public API usage”. Három változata van, attól függően, mit talált az Apple a binárisodban:

- **„references non-public selectors”**: Objective-C metódusnevek, például `boldFontOfSize:`;
- **„references non-public symbols”**: alsó vonallal kezdődő függvények, például `__dyld_get_shared_cache_range`;
- **„contains or inherits from non-public classes”**: egy osztálynév.

Mindegyik változat megad egy elérési utat, utána a nevek listáját. A szöveg két tanácsot is ad: nevezd át a metódusaidat, ha a nevük egy privát API-val egyezik, és távolítsd el az őket tartalmazó statikus könyvtárat. Egy 2026 szeptemberi e-mail az `xcrun swift-demangle` parancsot is javasolja, hogy a kódolt Swift-nevek olvashatók legyenek.

Az ellenőrzés mögötti szabály a [2.5.1-es guideline](https://developer.apple.com/app-store/review/guidelines/#2.5.1): egy app csak nyilvános API-kat használhat. Az [Apple Developer Program licencszerződése](https://developer.apple.com/support/terms/apple-developer-program-license-agreement/) ezt a 3.3.1-es pontban megismétli: privát API hívása tilos. Ennek a szabálynak az emberi review-ját a [2.5.1-es guideline](https://devoria.fr/hu/blog/guideline-2-5-1-publikus-api-expo-sdk) útmutatója részletezi. Itt a feltöltési hibával foglalkozunk.

A többi ITMS-hibához hasonlóan senki nem nyitotta meg az appodat: az Apple a build feldolgozása közben elemezte a binárist. **Az Apple nem tesz közzé listát a privát API-król: az e-mailedben szereplő nevek az egyetlen megbízható lista.**

## Az elérési út: SDK vagy a futtatható fájlod?

A lista előtt álló elérési út megmondja, melyik fájlban keress.

- **`Frameworks/Nom.framework/Nom`**: a név egy beágyazott dinamikus frameworkben van, tehát egy konkrét SDK-ban. A Solys buildjében ez a mappa 14 frameworköt tartalmaz: Hermest, React Native-ot, előre lefordítva szállított Expo-modulokat és az SDWebImage képkönyvtárat.
- **Csak az appod neve**: a név a fő futtatható fájlban van. Expónál ez egyesíti a natív kódodat és a forrásból fordított podokat, amelyek alapértelmezésben statikusan linkelődnek. Ilyenkor bármelyik natív könyvtár lehet a hibás.

## A döntési fa: a megnevezett névtől a javításig

Haladj sorban a sorokon. Az első, ami illik az esetedre, megadja az irányt.

| Amit látsz                  | Hol keress                    | Javítás                   |
| --------------------------- | ----------------------------- | ------------------------- |
| `$s` vagy `_$s` kezdetű név | `xcrun swift-demangle`        | Kezdd újra a fát          |
| Nincs meg az IPA-ban        | `grep` a bundle-ön            | Küldj be újra egy buildet |
| Nyilvános név iOS-en        | Az iOS SDK fejlécei           | Küldj be újra egy buildet |
| `API_UNAVAILABLE(ios)`      | Az iOS SDK fejlécei           | Frissítsd a csomagot      |
| A `Frameworks/X` mappában   | Az X-et szállító SDK          | Frissítsd az SDK-t        |
| Szelektor, az appod         | Podok és natív modulok        | Prefixáld vagy frissítsd  |
| `_nom` szimbólum, az appod  | `nm -m`, aztán a podok        | Cseréld le a hívást       |
| Osztály, az appod           | A saját osztályaid és podjaid | Prefixáld az osztályt     |

A „Küldj be újra egy buildet” sorok téves riasztást jeleznek, erről lentebb lesz szó.

## 1. lépés: nyisd meg a beküldött buildet

A ténylegesen az Apple-nek elküldött fájlon dolgozz, ne a projekteden. Töltsd le az IPA-t a build oldaláról az expo.dev-en, aztán futtasd a Maceden:

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

A második sor kilistázza a beágyazott frameworköket. A harmadik közvetlen hivatkozást keres az Apple valamelyik privát frameworkjére: semmit nem szabad kiírnia. A Solysnál az `otool -L` nem talál privát frameworköt, sem a futtatható fájlban, sem a 14 frameworkben.

## 2. lépés: keresd meg a nevet tartalmazó fájlt

Kezdd tágan. Keresd a megnevezett nevet, az elején lévő alsó vonalak nélkül, a teljes bundle-ben:

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

A parancs kilistázza a szöveget tartalmazó fájlokat. Utána szűkíts a név típusa szerint (szelektor, szimbólum, osztály) a megtalált fájlon, amit itt `Binaire` jelöl:

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

**Szelektorhoz a `strings` parancsot használd, ne az `nm`-et.** A Solys React frameworkjén az `nm` az osztályukkal együtt mutatja a metódusokat, például `-[RCTRootView initWithBridge:moduleName:initialProperties:]`, de soha nem magában az `initWithBridge:` szelektort. A `strings` megtalálja.

Szimbólumnál a sor végét olvasd. A Solysnál az `nm -m` például ezt írja ki: `(undefined) external __dyld_get_image_name (from libSystem)`. A bináris meghívja a függvényt, de nem tartalmazza, a libSystem biztosítja. Ez a függvény nyilvános, ahogy a következő lépés megmutatja.

## 3. lépés: ellenőrizd, tényleg privát-e a név

Az iOS SDK fejlécei írják le a nyilvános API-kat. Pár másodperces kereséssel kiderül, szerepel-e bennük a megnevezett név, és mely platformokon. Szimbólumnál előbb vedd le a fordításkor hozzáadott alsó vonalat: a `_SCDynamicStoreCreate` így `SCDynamicStoreCreate` lesz.

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

2026. október 15-én, az iOS 26.2 SDK-val ezt adja négy név, amelyek valódi ITMS-90338-as e-mailekből származnak:

| Megnevezett név               | Az iOS SDK-ban       | Értelmezés             |
| ----------------------------- | -------------------- | ---------------------- |
| \_dyld_get_shared_cache_range | Nincs benne          | Privát API             |
| boldFontOfSize:               | Nincs benne          | Privát vagy névütközés |
| SCDynamicStoreCreate          | API_UNAVAILABLE(ios) | Csak macOS             |
| isMainFrame                   | WebKit-tulajdonság   | Nyilvános              |

**Ha a név benne van és iOS-en elérhető, az téves riasztásra utal. Ha nincs benne, az privát API-ra vagy névütközésre.** Két korlát: egy csak Swiftben nyilvános API nem jelenik meg ezekben a fejlécekben, és egy olyan accessornál, mint a `setDelegate:`, a `delegate` tulajdonságra keress.

## 4. lépés: kövesd vissza a csomagig

Ha az elérési út frameworköt nevez meg, a neve elvezet a podhoz, onnan az npm-csomaghoz:

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

Az `npm explain` megmondja, melyik függőség telepítette, ha te magad sosem adtad hozzá.

Ha az elérési út a futtatható fájlt nevezi meg, keresd a nevet a natív forrásokban, aztán a podokban:

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

Igazítsd a mappák listáját: a `modules` a helyi Expo-modulok mappája. Az `ios/Pods` mappa az `npx expo prebuild -p ios` után jelenik meg, ami Macen a podokat is telepíti. Figyelem: ez újra létrehozhatja az `ios` mappát. Ha kézzel módosítottad, egy másolaton dolgozz.

**Az `ios/Pods` mappában keresni ugyanolyan fontos, mint a forrásokban.** A Solysnál ez a mappa 15, előre lefordítva szállított frameworköt tartalmaz `.xcframework` formátumban: Expo-modulokat, Hermest, React Native-ot és harmadik féltől származó SDK-kat. A csak forrásfájlokra szűkített keresés elmenne a kódjuk mellett.

## A tipikus okok

**Egy harmadik féltől származó SDK, ami túl régi vagy túl új.** 2026 szeptemberében egy Flutter-fejlesztő [egy biztonsági SDK miatti elutasítást jelzett](https://github.com/talsec/Free-RASP-Flutter/issues/236): a 8.2.3-as verzió meghívta a `__dyld_get_shared_cache_range` függvényt. A 8.2.2-es átment, és a fejlesztő cég azt tanácsolta, hogy térjenek vissza rá, amíg nincs javítás.

**Egy natív modul, ami nem dokumentált API-t hív.** A saját modulod, egy plugin vagy egy kis könyvtár használhat egy fórumon talált belső UIKit-metódust. Az ellenőrzés a neve alapján kiszúrja.

**Névütközés.** A metódusod vagy az osztályod véletlenül egy privát Apple API nevét viseli. Az üzenet számol ezzel, és arra kér, hogy nevezd át. Az Apple azt ajánlja, hogy [prefixáld az osztályaihoz hozzáadott metódusokat](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html), például három kisbetűvel és egy alsó vonallal.

**Egy API, ami macOS-en nyilvános, iOS-en nem.** 2024-ben egy .NET MAUI appot [a `_SCDynamicStoreCreate` miatt utasítottak el](https://github.com/dotnet/runtime/issues/103949). Az Apple dokumentálja ezt a függvényt, de [csak macOS-re](https://developer.apple.com/documentation/systemconfiguration/1437828-scdynamicstorecreate), és az iOS SDK fejléce `API_UNAVAILABLE(ios, tvos, watchos)` jelöléssel látja el.

## Javítás kerülőutak nélkül

1. **Frissítsd a függőséget.** Az Expo által követett csomagoknál az `npx expo install --check` jelzi azokat, amelyek nem illenek az SDK-dhoz, az [Expo CLI dokumentációja](https://docs.expo.dev/more/expo-cli/) szerint. A többinél olvasd el a változásnaplót.
2. **Térj vissza az előző verzióra**, ha az új hozta be a nevet, és szólj a fejlesztőnek.
3. **Cseréld le vagy távolítsd el** az elhagyott könyvtárat.
4. **Nevezd át** a metódusodat vagy az osztályodat, egy prefixszel.

**Ne rejtsd el a nevet.** Ha szétdarabolod a stringet, vagy kerülőúton hívod meg a metódust, azzal elrejted a használatot, de nem javítod. Továbbra is tiltja a 2.5.1-es szabály és a szerződés, és ilyenkor a fiókod kerül veszélybe.

Utána készíts új buildet új [buildszámmal](https://devoria.fr/hu/blog/app-store-connect-build-number-verzio-buildszam). A távoli frissítés nem elég: a név a lefordított natív kódban van. Beküldés előtt futtasd le újra a 2. lépést az új IPA-n. A név nem szerepelhet benne.

## Amikor téves riasztásról van szó

Az Apple ellenőrzése néha téved. 2022. június 6-án React Native és Flutter appok kaptak ITMS-90338-at nyilvános WebKit-nevek miatt, mint a `setNavigationDelegate:` vagy az `isMainFrame`, még szinte változatlan frissítéseknél is. Másnap egy Apple-mérnök azt írta, hogy a problémát a validáció oldalán megoldották, és arra kért mindenkit, hogy küldje be újra a buildjeit. A szál megmaradt az [Expo GitHub-repójában](https://github.com/expo/expo/issues/17768).

Ha ez a három jel együtt áll fenn, az téves riasztásra utal:

- a build hasonlít az utolsó elfogadott buildre;
- a 2. lépés nem találja a nevet, vagy a 3. lépés szerint iOS-en nyilvános;
- más fejlesztők ugyanazon a napon ugyanezt a hibát jelzik az Apple fórumain.

Ilyenkor nézd meg az [Apple szolgáltatásainak állapotát](https://developer.apple.com/system-status/), aztán küldj be újra egy buildet új számmal. Ha a hiba megmarad, írj az [Apple fejlesztői supportjának](https://developer.apple.com/contact/) a teljes e-maillel. A névütközés viszont az Apple szemében nem téves riasztás: nevezd át.

## A következő beküldés előtt

A többi ITMS-hibának is megvan a saját útmutatója: [ITMS-90725](https://devoria.fr/hu/blog/itms-90725-sdk-version-issue-javitasa-expo) a Xcode-verzióhoz, [ITMS-91053](https://devoria.fr/hu/blog/itms-91053-missing-api-declaration-expo) az adatvédelmi manifesthez és [ITMS-90034](https://devoria.fr/hu/blog/itms-90034-missing-or-invalid-signature-javitasa) az aláíráshoz. Ha a buildet elfogadták, telepítsd [TestFlighttal](https://devoria.fr/hu/blog/testflight-iphone-app-tesztelese) a review előtt.

A reviewer általi elutasítások több rálátást igényelnek: a teendőket az [Apple által elutasított app](https://devoria.fr/hu/expertise/apple-altal-elutasitott-alkalmazas) oldalon találod, a leggyakoribb okokat pedig a [miért utasítja el az Apple az appodat](https://devoria.fr/hu/blog/apple-elutasitas-miert-utasitottak-el-az-appodat) cikkben.

Ha beküldés előtt ellenőriznéd az anyagodat, a [Review Kit](https://devoria.fr/hu/kits/app-review) tartalmazza a checklistemet és Claude Code skilleket, amelyek átnézik a projektedet. Ha elakadt a beküldésed, és emberi szemre van szükséged, [foglalj velem egy órát](https://devoria.fr/hu/coaching): videóhívásban, a te képernyődön nézzük át a projektedet. Ha pedig az első megjelenésedre készülsz, [csináld meg az ingyenes diagnosztikát](https://devoria.fr/hu/diagnostic): sorba rakja a lépéseket, és elküldi neked az Apple-elutasítás elleni checklistemet.

## Gyakori kérdések

### Az ITMS-90338 az App Review elutasítása?

Nem. Ez egy automatikus ellenőrzés, ami a build feldolgozása közben fut, még minden emberi review előtt. Az elutasított build nem kerül se TestFlightba, se review-ra. Ha egy privát API-t később egy reviewer szúr ki, az a 2.5.1-es guideline alá tartozik.

### Javítható az ITMS-90338 távoli frissítéssel?

Nem. A megnevezett nevek a bináris lefordított natív kódjában vannak. A távoli frissítés csak a JavaScriptet és az erőforrásokat változtatja meg. Javítsd a függőséget, készíts új buildet, és küldd be újra.

### Miért említ az Apple olyan metódusokat, amelyeket sosem írtam?

Mert egy beágyazott könyvtárból származnak, vagy névütközésről van szó: egy függőség olyan metódust deklarál, ami egy privát API nevét viseli. Az Apple a binárisban lévő neveket olvassa, nem a forráskódodat. Kövesd vissza a csomagig a `grep` és az `npm explain` segítségével.

### Honnan tudhatom, hogy egy API nyilvános-e iOS-en?

Keresd a nevét az iOS SDK fejléceiben (az elérési útjukat az `xcrun --sdk iphoneos --show-sdk-path` adja meg), és nézd meg az elérhetőségét. Az Apple dokumentációs oldala is jelzi. Egy csak macOS-re dokumentált függvény iPhone-on nem nyilvános.

### Meg kell változtatni a buildszámot a javítás után?

Igen. Hagyd, hogy az EAS növelje: egy ugyanahhoz a verzióhoz már beküldött számot ITMS-90189 hibával elutasíthatnak.


## A projekted

[Review Kit](https://devoria.fr/hu/kits/app-review): Az App Store review checklistem, a javított Apple-elutasításaim, a Google Play checklist és három Claude Code skill. 17 990 Ft.

[iOS & Android Kit](https://devoria.fr/hu/kits/ios): Készítsd el iPhone- és Android-appodat Claude Code-dal: az appjaim kezdőkódja, az út a store-okig és az összes kit. 35 990 Ft.

[Diagnózis: mi választ el az iPhone-appodtól](https://devoria.fr/hu/diagnostic): 7 kérdés, 60 másodperc: megtudod, mi akadályoz valójában abban, hogy kiadd az iPhone-appodat, megkapod a 4 lépéses utadat és a hozzád illő kitet.
