# Guideline 2.5.4: Apple відхилила фоновий режим

> Guideline 2.5.4: Apple відхиляє фоновий режим, якщо жодна функція його не використовує. Прибери ключ або покажи рецензенту звук, геолокацію чи дзвінок.

Оригінальна сторінка: [Guideline 2.5.4: Apple відхилила фоновий режим](https://devoria.fr/uk/blog/guideline-2-5-4-background-mode-rejected)
Автор: [Mehdi Azizi](https://devoria.fr/uk/mehdi-azizi)
Опубліковано: 2026-11-04
Останнє оновлення змісту: 2026-11-04


Guideline 2.5.4 обмежує фонові режими їхнім передбаченим призначенням: звук, геолокація, VoIP-дзвінки, завершення завдання, локальні сповіщення. Відмова приходить, коли твій Info.plist оголошує один із цих режимів, а рецензент не знаходить жодної функції, якій він потрібен. **Прибери ключ, якщо його ніщо не використовує, інакше покажи рецензенту функцію за тридцять секунд.**

Я публікую власні iOS-застосунки з Expo. Solys, мій будильник із міні-іграми, оголошує режим audio: я його прибрав, а потім повернув з іншої причини. Цей гайд спирається на текст Apple, на відмови, які опублікували інші розробники, і на мої проєкти. Загальну картину причин дивись у статті [чому Apple відхиляє застосунок](https://devoria.fr/uk/blog/vidmova-apple-app-store-prychyny).

## Що каже guideline 2.5.4?

Правило вміщується в одне речення, у розділі 2 «Performance», підрозділ 2.5 «Software Requirements», [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.4): «Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.»

Простими словами: фоновий сервіс слугує лише тому, для чого він існує. Звідси назва «Guideline 2.5.4 - Performance - Software Requirements».

За замовчуванням застосунок, що пішов у фон, призупиняється. Щоб працювати далі, він оголошує один або кілька режимів у ключі `UIBackgroundModes` свого Info.plist. [Документація Apple про фонові режими](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes) просить використовувати їх ощадливо через батарею і обирати інше рішення, коли воно є. **Кожен оголошений режим це обіцянка, яку рецензент може перевірити.**

## Фонові режими та їхнє призначення

| Режим                 | Ключ                  | Призначення                |
| --------------------- | --------------------- | -------------------------- |
| Audio, AirPlay, PiP   | `audio`               | Чутний звук у фоні         |
| Геолокація            | `location`            | Безперервна геолокація     |
| Voice over IP         | `voip`                | Дзвінки з CallKit          |
| Background fetch      | `fetch`               | Регулярний мережевий вміст |
| Background processing | `processing`          | Заплановані завдання       |
| Віддалені сповіщення  | `remote-notification` | Push нового вмісту         |

Ця таблиця підсумовує сторінку Apple. У відмовах, опублікованих на форумах, найчастіше трапляються `audio`, `location` і `voip`.

## Що означає повідомлення про відмову 2.5.4?

Повідомлення називає проблемний режим. Два приклади, які розробники опублікували на форумах Apple:

- **Audio**: «Your app still declares support for audio in the UIBackgroundModes key in your Info.plist but did not include features that require persistent audio.» Далі уточнюється, що ключ `audio` призначений для застосунків, які відтворюють чутний вміст у фоні, як-от музичний плеєр. Пропонуються два виходи: додати такий вміст або прибрати ключ ([тред на форумі](https://developer.apple.com/forums/thread/95216)).
- **Геолокація**: у [треді з грудня 2024](https://developer.apple.com/forums/thread/771202) Apple не знайшла жодної функції, крім відстеження працівників, яка потребує постійної геолокації, і написала, що одного цього використання недостатньо.

Як я це бачу: **рецензент не читає твій код, він шукає функцію.** Він має змогу її запустити, перевести застосунок у фон і побачити, що той працює далі.

Буває й навпаки. У [треді з травня 2026](https://developer.apple.com/forums/thread/826849) застосунок для читання вголос, який справді використовував режим `audio`, відхиляли кілька разів: рецензент не міг запустити звук. Інший розробник пише там, що, на його думку, його випадок розблокувало прикріплене відео. Це свідчення, а не правило Apple.

## Звідки береться ключ, якщо ти його не додавав?

В Expo Info.plist під час prebuild заповнюють плагіни конфігурації. **Тож фоновий режим може потрапити в твій бінарник без твого рішення.**

### Плагін expo-audio з налаштуваннями за замовчуванням

[Документація expo-audio](https://docs.expo.dev/versions/latest/sdk/audio/) про це каже: опція `enableBackgroundPlayback` за замовчуванням дорівнює `true` і на iOS додає режим `audio`. Тож достатньо оголосити плагін у короткій формі, `"expo-audio"`, щоб оголосити режим.

Саме це я знайшов, перечитуючи TradaZen перед першим поданням: короткі звуки інтерфейсу на передньому плані, але плагін, оголошений у короткій формі. Виправлення вміщується в `app.json`:

```json
{
  "expo": {
    "plugins": [["expo-audio", { "enableBackgroundPlayback": false }]]
  }
}
```

Інші пакети додають режим по-своєму. Опція `isIosBackgroundLocationEnabled` у [expo-location](https://docs.expo.dev/versions/latest/sdk/location/) додає `location`, лише якщо ти її ввімкнеш. А [expo-background-task](https://docs.expo.dev/versions/latest/sdk/background-task/) додає `processing` під час prebuild одразу після встановлення.

### Тека ios/, яка зберігає старий ключ

Друга пастка, у яку я потрапив на Solys у липні 2026. Я прибрав `audio` з `app.json`, але ключ лишився в `ios/Solys/Info.plist`, згенерованому раніше. Prebuild без `--clean` змінює цей проєкт замість того, щоб створити його заново, а плагін додає ключ, але ніколи не прибирає. Локальний build узяв би його з собою. Build EAS у хмарі починає з нового prebuild, коли `ios/` ігнорується git, і в мене було саме так.

Перед кожним build я перевіряю, що насправді піде:

```bash
npx expo config --type introspect --json | grep -o '"UIBackgroundModes":\[[^]]*\]'
npx expo prebuild --clean --platform ios
```

Перша команда показує режими, які prebuild запише в Info.plist. Друга створює нативний проєкт заново для локального build, видаляючи теку `ios/`. На Solys перша показує `"UIBackgroundModes":["audio"]`, на TradaZen нічого: обидва результати навмисні.

Додавання чи видалення режиму змінює Info.plist, а отже бінарник: **потрібен новий build, віддаленого оновлення недостатньо.** [Документація EAS Update](https://docs.expo.dev/eas-update/introduction/) відносить такі зміни до тих, що потребують нового бінарника, як і у випадку [ITMS-90683](https://devoria.fr/uk/blog/itms-90683-missing-purpose-string-expo).

## Solys: оголошений режим audio зі справжньою причиною

Solys це будильник, але режим `audio` не потрібен, щоб будильник дзвонив: **дзвінок іде через AlarmKit**, сервіс будильників Apple, доступний з iOS 26 ([документація AlarmKit](https://developer.apple.com/documentation/alarmkit)). Дзвонить система, навіть у беззвучному режимі, а не застосунок.

Історія ключа, бо міркування важливіше за сам рядок:

1. **Наприкінці липня 2026 я його прибираю.** Ніщо не грало звук у фоні: звукові ефекти міні-ігор лишаються на передньому плані, а будильник не залежить від застосунку.
2. **Через два дні я його повертаю** разом із нічним прослуховуванням. Ця опція записує звуки твоєї ночі мікрофоном і аналізує їх на iPhone. Запис має тривати при заблокованому екрані, а документація expo-audio вказує, що опція фонового запису теж додає режим `audio`.

Суть обґрунтування змінилася: **режим потрібен для запису, а не для відтворення.** Три запобіжники, видимі в застосунку:

- прослуховування це опція, вимкнена за замовчуванням, яка вмикається з налаштувань або з вечірнього ритуалу;
- у неї власний екран згоди, як вимагає [правило 2.5.14](https://developer.apple.com/app-store/review/guidelines/#2.5.14) для будь-якого запису, і ніщо не залишає телефон;
- мікрофон вимикається за десять хвилин до будильника, щоб прослуховування і дзвінок ніколи не заважали одне одному.

Я не можу гарантувати, що рецензент завжди прийме це оголошення. Але для кожного елемента я можу сказати, навіщо він і де його побачити.

### Будильники, які тримали застосунок активним

До AlarmKit сторонній будильник не міг дзвонити, як будильник Apple. Тому деякі бібліотеки тримали застосунок активним: документація Flutter-пакета [alarm2](https://pub.dev/packages/alarm2) описує беззвучний аудіоплеєр, що працює до будильника. Але беззвучний звук нічого не відтворює чутно. **З iOS 26 AlarmKit робить цей обхід непотрібним.**

## Залишити чи прибрати режим: таблиця рішень

| Твоя ситуація                     | Що робити                 |
| --------------------------------- | ------------------------- |
| Короткі звуки на передньому плані | Прибрати `audio`          |
| Музика чи аудіокнига              | Залишити, показати        |
| Довгий запис                      | Залишити + згода          |
| Будильник чи таймер               | AlarmKit (iOS 26)         |
| Геолокація час від часу           | Значні зміни розташування |
| Синхронізація без поспіху         | `fetch` або `processing`  |
| Аудіо- чи відеодзвінки            | `voip` з CallKit          |

Щодо геолокації, сторінка Apple називає сервіс значних змін розташування (significant-change) альтернативою режиму `location`.

## Інші пункти 2.5: 2.5.1 і 2.5.2

### 2.5.1: публічні API і фреймворки за призначенням

«Apps may only use public APIs and must run on the currently shipping OS.» Застосунок використовує лише публічні API, працює на поточній версії системи й відмовляється від застарілого. Як і з 2.5.4, кожен фреймворк слугує своєму призначенню, згаданому в описі: HealthKit для здоров'я, HomeKit для розумного дому. Якщо бібліотека викликає приватний API, відмову отримує твій застосунок.

### 2.5.2: жодного завантаженого коду, що змінює застосунок

Застосунок лишається самодостатнім у своєму пакеті. Він не може «download, install, or execute code which introduces or changes features or functionality of the app». Обмежений виняток мають лише освітні застосунки, що навчають програмувати, з кодом, який користувач повністю бачить і може змінювати.

В Expo це стосується EAS Update, документація якого нагадує, що оновлення мають відповідати правилам App Store. **Використовуй віддалені оновлення для виправлень, ніколи для доставки функції, якої рецензент не бачив.** Виправлення, пов'язане з рецензією, йде через новий build, як я пояснюю в гайді про [guideline 2.1](https://devoria.fr/uk/blog/guideline-2-1-app-store-vidmova).

## Як відповісти на відмову 2.5.4?

Розмова ведеться в розділі App Review твого застосунку, де ти [відповідаєш на повідомлення App Review](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/). Два випадки:

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

Шаблон, який я б використав, підлаштуй під себе (прибери речення про будильник, якщо в твоєму застосунку його немає):

```text
Hello,

The "audio" background mode is used only by [feature], an
optional feature that [records / plays] audio while the
device is locked. It is off by default.

How to test:
1. Open [screen] and turn on [feature].
2. Accept the microphone permission if asked.
3. Tap [button], then lock the device.
   [What the reviewer will hear or see.]

Our alarm does not use this mode: it is scheduled with
AlarmKit and rings through the system.

Attached: a short screen recording of these steps.

Best regards,
```

## Чекліст 2.5.4 перед поданням

- Інтроспекція Expo показує лише потрібні режими, і ти можеш назвати функцію кожного.
- Жоден плагін не оголошений у короткій формі, якщо він за замовчуванням додає режим, як expo-audio.
- Твоя локальна тека `ios/` не зберігає жодного старого ключа, або ти збираєш із чистого prebuild.
- Функція запускається швидко, без прихованих налаштувань, а нотатки для рецензії кажуть, який режим для чого і як його перевірити.
- Будь-який запис просить явну згоду й показує видимий індикатор. Правила щодо запитів дозволів є в гайді про [guideline 5.1.1](https://devoria.fr/uk/blog/guideline-5-1-1-app-store-rejection-fix).
- Для будильника дзвінок іде через AlarmKit, а не через звук, який відтворює застосунок.

## Перевір свої матеріали перед відправкою

[Review Kit](https://devoria.fr/uk/kits/app-review) містить мій чекліст перед відправкою, шаблони нотаток для тестувальника і skills для Claude Code, які перечитують твій проєкт. Якщо потрібен погляд людини, [забронюй годину зі мною](https://devoria.fr/uk/coaching): ми разом прочитаємо повідомлення Apple і твій Info.plist по відеозв'язку. Повний підхід описано на сторінці [застосунок відхилено Apple](https://devoria.fr/uk/expertise/app-rejected-by-apple).

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

Ніхто не може гарантувати, що Apple прийме твій застосунок. А от добре обґрунтований фоновий режим захищається за тридцять секунд.

## Поширені запитання

### Що означає «Guideline 2.5.4 - Performance - Software Requirements»?

Це назва відмови, коли Apple вважає, що фоновий режим у твоєму Info.plist не використовується за призначенням. Повідомлення називає режим і пропонує показати функцію, яка його використовує, або прибрати ключ.

### Чи потрібен новий build після відмови 2.5.4?

Якщо ти прибираєш або змінюєш режим, так: ключ лежить в Info.plist, а отже в бінарнику. Якщо режим обґрунтований, може вистачити відповіді з точним шляхом і відео.

### Чи можна залишити режим audio заради кількох звуків інтерфейсу?

Ні. Коротким звукам на передньому плані він не потрібен. В Expo встанови `enableBackgroundPlayback` у `false` у плагіні expo-audio.

### Чи потрібен будильнику режим audio?

Не для дзвінка, якщо він спирається на AlarmKit, доступний з iOS 26: будильник відтворює система. У Solys режим `audio` потрібен для нічного прослуховування, яке записує при заблокованому екрані.

### Чому Apple посилається на 2.5.4, хоча я нічого не оголошував?

Можливо, це зробив за тебе плагін: expo-audio за замовчуванням додає режим `audio`, а стара тека `ios/` може зберігати ключ, який ти прибрав із конфігурації. Перевір командою `npx expo config --type introspect`.


## Твій проєкт

[Review Kit](https://devoria.fr/uk/kits/app-review): Мій чекліст для перевірки в App Store, виправлені відмови Apple, чекліст для Google Play і три скіли для Claude Code. 2 499 ₴.

[iOS & Android Kit](https://devoria.fr/uk/kits/ios): Створи свій застосунок для iPhone і Android з Claude Code: стартовий код моїх застосунків, шлях до публікації в сторах і всі кіти. 4 999 ₴.

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