# Guideline 2.5.1: публичные API и актуальный SDK в Expo

> Guideline 2.5.1: только публичные API, работа на текущей iOS, фреймворки строго по назначению. В Expo сначала проверь свои нативные модули.

Оригинальная страница: [Guideline 2.5.1: публичные API и актуальный SDK в Expo](https://devoria.fr/ru/blog/guideline-2-5-1-public-api-sdk-expo)
Автор: [Mehdi Azizi](https://devoria.fr/ru/mehdi-azizi)
Опубликовано: 2026-11-04
Последняя правка контента: 2026-11-04


У guideline 2.5.1 четыре требования: использовать только публичные API, работать на текущей версии iOS, отказываться от того, что Apple объявляет устаревшим, и применять каждый фреймворк по назначению. **В Expo риск редко исходит от твоего JavaScript-кода: он исходит от нативных модулей, которые ты ставишь, и от SDK, с которым ты собираешь приложение.**

Я публикую Solys, TradaZen и Nolera на Expo SDK 57. Solys работает через API Screen Time от Apple, а это фреймворк с ограниченным использованием. В этом гайде речь о правиле ревью. Если ошибка пришла при загрузке билда, читай гайд про [ITMS-90338](https://devoria.fr/ru/blog/itms-90338-non-public-api-usage-expo). Про фоновые режимы из того же раздела есть гайд по [guideline 2.5.4](https://devoria.fr/ru/blog/guideline-2-5-4-background-mode-rejected).

## Что говорит guideline 2.5.1?

Правило находится в разделе 2.5, «Software Requirements», в [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.1): «Apps may only use public APIs and must run on the currently shipping OS. Keep your apps up-to-date and make sure you phase out any deprecated features, frameworks or technologies that will no longer be supported in future versions of an OS. Apps should use APIs and frameworks for their intended purposes and indicate that integration in their app description.»

Если по-простому, обязательств четыре:

1. **Только публичные API**, то есть задокументированные Apple.
2. **Приложение работает на текущей версии iOS**, с сентября 2026 года это iOS 27.
3. **Ничего устаревшего, что скоро исчезнет**: то, что Apple объявляет снятым с поддержки, ты заменяешь.
4. **Каждый фреймворк на своём месте и упомянут в описании**: HomeKit для умного дома, HealthKit для здоровья и спорта, со связью с приложением «Здоровье».

Отсюда и заголовок отказа: «Guideline 2.5.1 - Performance - Software Requirements».

## Публичные API: где прячется риск в Expo-приложении

Приватный API: это системная функция, которую Apple не документирует. Apple не гарантирует ни её поведение, ни то, что она останется в следующей версии iOS, поэтому она и запрещена.

Твой JavaScript-код никогда не обращается к iOS напрямую: он идёт через нативные модули. Модули из SDK Expo поддерживает команда Expo. **Остальные несут код, который писал не ты, и Apple проверяет его как твой собственный.** Гайд про [ITMS-90683](https://devoria.fr/ru/blog/itms-90683-missing-purpose-string-expo) показывает тот же механизм на строках запроса разрешений: Apple оценивает код, который есть в билде, а не то, что приложение делает.

В Solys на 15 октября 2026 года 42 прямые зависимости содержат нативный iOS-код, из них 14 не входят в SDK Expo. Среди них RevenueCat, Sentry, AppsFlyer и `react-native-device-activity`, мост к API Screen Time.

Приватный API могут заметить на двух этапах. При загрузке автоматическая проверка App Store Connect может вернуть ошибку ITMS-90338. Во время ревью ревьюер ссылается на 2.5.1.

## Устаревшие API: от UIWebView до UIScene

Самый известный пример: UIWebView, старый компонент для показа веб-страниц. Apple [перестала его принимать](https://developer.apple.com/news/?id=12232019b) в новых приложениях в апреле 2020 года, а в обновлениях в декабре 2020 года. Старая библиотека, которая ещё на него ссылалась, блокировала загрузку. В Solys поиск из чек-листа ниже не находит ни одной ссылки.

Следующее изменение уже анонсировано. В технической заметке Apple [TN3187](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle) написано: «In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won't launch.» Проще говоря, приложение, собранное с SDK iOS 27 без жизненного цикла на сценах, не запустится.

Три даты, которые надо связать:

- **С апреля 2026 года** Apple требует Xcode 26: об этом гайд про [ITMS-90725](https://devoria.fr/ru/blog/itms-90725-sdk-version-issue-expo).
- **В апреле 2027 года**, согласно [странице Apple о загрузке](https://developer.apple.com/app-store/submitting/), SDK iOS 27 станет обязательным.
- **SDK Expo 58**, в бете с 15 сентября 2026 года, уже генерирует поддержку сцен, судя по [анонсу Expo](https://expo.dev/changelog/sdk-58-beta).

С SDK Expo 57 и Xcode 26 ты пока собираешь с SDK iOS 26: сегодня ничего не ломается. **Модулям, которые меняют AppDelegate, придётся подтянуться до апреля 2027 года.**

## Фреймворки не по назначению

Ревьюер проверяет, что чувствительный фреймворк обслуживает видимую функцию и что твоя страница в App Store об этом говорит.

- **HealthKit** нужен для здоровья и спорта. В [рекомендациях Apple по интерфейсу](https://developer.apple.com/design/human-interface-guidelines/healthkit) сказано: «If your app doesn't provide health and fitness functionality, don't request access to people's private health data.»
- **HomeKit** нужен для умного дома, и больше ни для чего.
- **PushKit** нужен для VoIP-звонков. [Документация PushKit](https://developer.apple.com/documentation/pushkit/responding-to-voip-notifications-from-pushkit) однозначна: «If you are unable to support CallKit in your app, you cannot use PushKit to handle push notifications.» VoIP-уведомление, которое будит приложение без звонка, это злоупотребление.
- **Family Controls**, API Screen Time, требует специального разрешения. В его [документации](https://developer.apple.com/documentation/familycontrols) уточняется: «Before submitting your app to the App Store, you must request permission to use the entitlement.»

Для Solys я запросил это разрешение на дистрибуцию 23 сентября 2026 года, и Apple выдала его в тот же день. Использование соответствует фреймворку: пользователь выбирает приложения для паузы, и Solys блокирует их на 30, 45 или 60 минут после пробуждения. В описании на странице это сказано одной фразой: «Solys использует разрешение Screen Time от Apple, чтобы ставить на паузу выбранные приложения». **Именно этого требует конец 2.5.1: упомянуть интеграцию в описании.**

## Бета-версии: TestFlight да, App Store нет

[Заметки о выпуске App Store Connect](https://developer.apple.com/help/app-store-connect/release-notes/) показывают правило на практике. 14 октября 2026 года билды, собранные в Xcode 27.2 beta 3, принимаются «for internal and external testing», то есть для TestFlight. 5 октября билды из Xcode 27.1 RC принимаются «for the App Store».

**Билд, собранный в бете Xcode, уходит в TestFlight, но никогда на ревью.** Для отправки нужна финальная версия или RC, которую Apple открыла для App Store.

Два уточнения для Expo-приложения:

- **Бета Expo не равна бете Apple.** Apple контролирует версию Xcode и SDK iOS, а не версию Expo. В анонсе SDK 58 ещё говорилось, что образы EAS с Xcode 27 скоро появятся.
- **Тестировать на текущей iOS всё равно обязательно**, даже если собираешь с SDK iOS 26. Запусти приложение с холодного старта на обновлённом iPhone или симуляторе.

## Чек-лист: нативные зависимости перед отправкой

Проходи его перед каждым продакшен-билдом. Команды запускаются в корне Expo-проекта:

```bash
npx expo-doctor
npx expo install --check
grep -rlw "UIWebView" node_modules --include='*.m' --include='*.mm' --include='*.swift' --include='*.h'
```

1. **`npx expo-doctor` не показывает ни одной ошибки.** В Solys 15 октября 2026 года прошли 20 проверок из 21. Ошибка была из-за 13 пакетов Expo, отстававших на один патч, их выравнивает `npx expo install --check`.
2. **Каждый модуль вне SDK Expo есть в React Native Directory.** Expo Doctor делает эту проверку по умолчанию, как указано в [документации Expo](https://docs.expo.dev/versions/latest/config/package-json/). Незнакомый пакет стоит проверить, прочитав его iOS-код.
3. **Каждый нативный модуль поддерживает твою версию React Native.** [Таблица версий Expo](https://docs.expo.dev/versions/latest/) связывает SDK 57 с React Native 0.86. Модуль без релизов на протяжении нескольких версий: это тревожный сигнал.
4. **Поиск UIWebView ничего не находит.** Сделай то же для любого API, который Apple объявляет снятым с поддержки.
5. **У каждого чувствительного фреймворка есть видимая функция**: здоровье, Screen Time, звонки, дом. Описание её упоминает, а специальное разрешение выдано.
6. **Билд собран в финальном Xcode.** Проверь версию в логах сборки EAS.
7. **Приложение запускается с холодного старта на текущей версии iOS**, с новым аккаунтом.
8. **Модули, которые трогают AppDelegate, заявляют поддержку UIScene** до твоего перехода на SDK iOS 27.

## Как ответить на отказ по 2.5.1?

В сообщении обычно названы проблемный API или фреймворк. Два варианта:

- **Фреймворк не обслуживает ничего видимого**: удали модуль или capability, пересобери билд и ответь в двух фразах.
- **Фреймворк обслуживает реальную функцию**: укажи точный путь, приложи скриншот или короткое видео и упомяни интеграцию в описании на странице.

**Удаление нативного модуля меняет бинарник: обновления по воздуху тут недостаточно.** Гайд по [guideline 2.1](https://devoria.fr/ru/blog/guideline-2-1-app-store-otkaz) объясняет, почему ревьюер видит только встроенный код. Дальше переписка идёт в App Store Connect, как в гайде о том, как [отвечать App Review](https://devoria.fr/ru/blog/resolution-center-apple-reply-app-review-rejection).

## Проверь проект перед отправкой

[Review Kit](https://devoria.fr/ru/kits/app-review) включает мой чек-лист перед отправкой, мои исправленные отказы и skills для Claude Code, которые проверяют твой Expo-проект. Если нужен взгляд живого человека, [забронируй час со мной](https://devoria.fr/ru/coaching): вместе прочитаем сообщение Apple и твои зависимости. Весь процесс описан на странице [приложение отклонено Apple](https://devoria.fr/ru/expertise/app-rejected-by-apple).

Готовишь свой первый релиз? [Пройди бесплатную диагностику](https://devoria.fr/ru/diagnostic): она пришлёт тебе мой чек-лист против отказов Apple.

## Частые вопросы

### Что значит «Guideline 2.5.1 - Performance - Software Requirements»?

Это заголовок отказа, когда Apple считает, что твоё приложение использует непубличный API, устаревшую технологию или фреймворк не по назначению. В сообщении обычно названо, что именно не так.

### Чем guideline 2.5.1 отличается от ошибки ITMS-90338?

ITMS-90338: это автоматическая ошибка при загрузке билда, когда проверка находит непубличный символ. 2.5.1: это правило ревью, которое применяет человек, и оно охватывает ещё и фреймворки не по назначению и устаревшие технологии.

### Можно ли отправить приложение, собранное в бете Xcode?

Нет. App Store Connect принимает такие билды только для TestFlight. Для ревью собирай в финальной версии Xcode или в RC, которую Apple открыла для App Store в заметках о выпуске.

### Может ли Expo-приложение использовать приватный API, а ты об этом не знаешь?

Да, через сторонний нативный модуль. Твой JavaScript-код сам iOS не вызывает, но каждый нативный пакет несёт код на Objective-C или Swift. Просматривай список модулей вне SDK Expo перед каждой версией.

### Нужно ли переходить на SDK Expo 58 прямо сейчас?

Ради 2.5.1 на 15 октября 2026 года нет: SDK 57 собирает с SDK iOS 26, который ещё принимается. Запланируй обновление до апреля 2027 года, когда Apple потребует SDK iOS 27 и жизненный цикл на сценах.


## Твой проект

[Review Kit](https://devoria.fr/ru/kits/app-review): Мой чек-лист для ревью в App Store, исправленные отказы Apple, чек-лист для Google Play и три скилла для Claude Code. 55 $.

[iOS & Android Kit](https://devoria.fr/ru/kits/ios): Создай своё приложение для iPhone и Android с Claude Code: стартовый код моих приложений, путь до публикации в сторах и все киты. 109 $.

[Диагностика: что отделяет тебя от твоего iPhone-приложения](https://devoria.fr/ru/diagnostic): 7 вопросов, 60 секунд: ты узнаешь, что на самом деле мешает тебе опубликовать iPhone-приложение, получишь путь из 4 этапов и подходящий тебе кит.
