# 가이드라인 2.5.4 백그라운드 모드 리젝 해결

> 쓰지 않는 백그라운드 모드를 선언하면 리젝돼요. 키를 지우거나 소리, 위치, 통화 기능을 리뷰어에게 보여 주세요.

원본 페이지: [가이드라인 2.5.4 백그라운드 모드 리젝 해결](https://devoria.fr/ko/blog/guideline-2-5-4-background-mode-rejection)
작성자: [Mehdi Azizi](https://devoria.fr/ko/mehdi-azizi)
게시일: 2026-11-04
최종 내용 수정: 2026-11-04


가이드라인 2.5.4는 백그라운드 모드를 원래 용도로만 쓰도록 제한해요. 원래 용도는 소리, 위치, VoIP 통화, 작업 마무리, 로컬 알림이에요. Info.plist에 이런 모드를 선언했는데 리뷰어가 그 모드가 필요한 기능을 하나도 찾지 못하면 리젝이 나와요. **아무것도 쓰지 않는다면 키를 지우고, 쓴다면 리뷰어가 30초 안에 그 기능을 확인할 수 있게 해 주세요.**

저는 Expo로 제 iOS 앱을 직접 출시하고 있어요. 미니게임 알람 앱인 Solys는 audio 모드를 선언하고 있는데요, 한 번 지웠다가 다른 이유로 다시 넣었어요. 이 가이드는 Apple의 문서, 다른 개발자들이 공개한 리젝 사례, 그리고 제 프로젝트를 바탕으로 썼어요. 리젝 사유 전체를 한눈에 보고 싶다면 [Apple이 앱을 리젝하는 이유](https://devoria.fr/ko/blog/app-store-rejection-reasons-real-cases)를 읽어 보세요.

## 가이드라인 2.5.4는 무슨 내용인가요?

규칙은 한 문장이에요. [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.4)의 섹션 2 "Performance", 2.5 "Software Requirements"에 있어요. "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"예요.

기본적으로 앱은 백그라운드로 가면 일시 정지돼요. 계속 실행되려면 Info.plist의 `UIBackgroundModes` 키에 모드를 하나 이상 선언해야 해요. [백그라운드 모드에 관한 Apple 문서](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)는 배터리 때문에 이 모드를 아껴 쓰고, 다른 방법이 있다면 그쪽을 쓰라고 권해요. **선언한 모드 하나하나가 리뷰어가 확인할 수 있는 약속이에요.**

## 백그라운드 모드와 원래 용도

| 모드                | 키                    | 원래 용도                  |
| ------------------- | --------------------- | -------------------------- |
| Audio, AirPlay, PiP | `audio`               | 백그라운드에서 들리는 소리 |
| 위치                | `location`            | 지속적인 위치              |
| VoIP                | `voip`                | CallKit을 쓰는 통화        |
| 가져오기            | `fetch`               | 주기적인 네트워크 콘텐츠   |
| 처리                | `processing`          | 예약된 작업                |
| 원격 알림           | `remote-notification` | 새 콘텐츠 푸시             |

이 표는 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년 12월 스레드](https://developer.apple.com/forums/thread/771202)에서 Apple은 직원 위치 추적 말고는 상시 위치가 필요한 기능을 찾지 못했고, 그 용도만으로는 적절하지 않다고 답했어요.

제 해석은 이래요. **리뷰어는 코드를 읽지 않고 기능을 찾아요.** 기능을 실행하고, 앱을 백그라운드로 보낸 뒤, 계속 동작하는지 확인할 수 있어야 해요.

반대 경우도 있어요. [2026년 5월 스레드](https://developer.apple.com/forums/thread/826849)에서는 `audio` 모드를 실제로 쓰던 텍스트 읽기 앱이 여러 번 리젝됐어요. 리뷰어가 소리를 재생시키지 못했거든요. 다른 개발자는 자기 경우엔 영상을 첨부한 덕분에 풀린 것 같다고 썼어요. 경험담일 뿐 Apple의 규칙은 아니에요.

## 직접 추가하지 않았는데 키는 어디서 왔을까요?

Expo에서는 prebuild 때 config plugin이 Info.plist를 채워요. **그래서 직접 정하지 않은 백그라운드 모드가 바이너리에 들어갈 수 있어요.**

### 기본값으로 설정된 expo-audio 플러그인

[expo-audio 문서](https://docs.expo.dev/versions/latest/sdk/audio/)에 나와 있어요. `enableBackgroundPlayback` 옵션의 기본값은 `true`이고, iOS에서는 `audio` 모드를 추가해요. 그러니 플러그인을 `"expo-audio"`라는 짧은 형태로 선언하기만 해도 모드가 선언돼요.

TradaZen을 처음 제출하기 전에 다시 살펴보다가 발견한 게 바로 이거예요. 포그라운드에서 짧은 UI 사운드만 쓰는데 플러그인은 짧은 형태로 선언돼 있었어요. 수정은 `app.json` 한 곳이면 돼요.

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

다른 패키지들도 각자 방식으로 모드를 추가해요. [expo-location](https://docs.expo.dev/versions/latest/sdk/location/)의 `isIosBackgroundLocationEnabled` 옵션은 켰을 때만 `location`을 추가해요. 반면 [expo-background-task](https://docs.expo.dev/versions/latest/sdk/background-task/)는 설치하기만 하면 prebuild 때 `processing`을 추가해요.

### 예전 키를 그대로 가진 ios/ 폴더

두 번째 함정은 2026년 7월 Solys에서 겪었어요. `app.json`에서 `audio`를 지웠는데, 예전에 생성된 `ios/Solys/Info.plist`에는 키가 남아 있었어요. `--clean` 없는 prebuild는 프로젝트를 새로 만들지 않고 수정만 하고, 플러그인은 키를 추가만 할 뿐 지우지는 않아요. 로컬 빌드였다면 키가 그대로 들어갔을 거예요. 클라우드의 EAS 빌드는 `ios/`가 git에서 무시될 때 새 prebuild부터 시작하는데, 제 경우가 그랬어요.

빌드할 때마다 실제로 들어갈 내용을 확인해요.

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

첫 번째 명령은 prebuild가 Info.plist에 쓸 모드를 보여 줘요. 두 번째는 `ios/` 폴더를 지우고 로컬 빌드용 네이티브 프로젝트를 다시 만들어요. Solys에서는 첫 번째 명령이 `"UIBackgroundModes":["audio"]`를 보여 주고, TradaZen에서는 아무것도 안 나와요. 둘 다 의도한 결과예요.

모드를 추가하거나 지우면 Info.plist, 즉 바이너리가 바뀌어요. **새 빌드가 필요하고, 원격 업데이트로는 안 돼요.** [EAS Update 문서](https://docs.expo.dev/eas-update/introduction/)는 이런 변경을 새 바이너리가 필요한 경우로 분류해요. [ITMS-90683](https://devoria.fr/ko/blog/itms-90683-missing-purpose-string-expo)과 마찬가지예요.

## Solys: 진짜 이유가 있는 audio 모드

Solys는 알람 앱이지만 `audio` 모드는 알람을 울리는 데 쓰지 않아요. **알람은 AlarmKit으로 울려요.** iOS 26부터 쓸 수 있는 Apple의 알람 서비스예요([AlarmKit 문서](https://developer.apple.com/documentation/alarmkit)). 무음 모드에서도 앱이 아니라 시스템이 알람을 울려요.

키의 이력을 정리해 볼게요. 코드 한 줄보다 판단 과정이 더 중요하니까요.

1. **2026년 7월 말, 키를 지웠어요.** 백그라운드에서 소리를 내는 게 없었어요. 미니게임 효과음은 포그라운드에서만 나고, 알람은 앱에 의존하지 않아요.
2. **이틀 뒤, 수면 소리 듣기 기능과 함께 다시 넣었어요.** 이 옵션은 마이크로 밤사이 소리를 녹음하고 iPhone 안에서 분석해요. 화면이 잠겨도 녹음이 계속돼야 하는데, expo-audio 문서에 따르면 백그라운드 녹음 옵션도 `audio` 모드를 추가해요.

정당화의 성격이 바뀐 거예요. **이 모드는 재생이 아니라 녹음에 쓰여요.** 앱에서 볼 수 있는 안전장치는 세 가지예요.

- 듣기 기능은 기본으로 꺼져 있는 옵션이고, 설정이나 저녁 루틴에서 켤 수 있어요.
- 모든 녹음에 대해 [규칙 2.5.14](https://developer.apple.com/app-store/review/guidelines/#2.5.14)가 요구하는 것처럼 별도의 동의 화면이 있고, 데이터는 휴대폰 밖으로 나가지 않아요.
- 듣기와 알람이 서로 방해하지 않도록 마이크는 알람 10분 전에 꺼져요.

리뷰어가 이 선언을 항상 받아들일 거라고 장담할 수는 없어요. 다만 각 요소가 무엇에 쓰이고 어디서 확인할 수 있는지는 설명할 수 있어요.

### 앱을 깨어 있게 하던 알람 앱들

AlarmKit 이전에는 서드파티 알람 앱이 Apple 알람처럼 울릴 수 없었어요. 그래서 일부 라이브러리는 앱을 깨어 있게 했어요. Flutter 패키지 [alarm2](https://pub.dev/packages/alarm2) 문서는 알람 시간까지 무음 오디오 플레이어를 돌리는 방식을 설명해요. 하지만 무음은 아무것도 들려주지 않아요. **iOS 26부터는 AlarmKit 덕분에 이런 우회가 필요 없어요.**

## 모드를 유지할지 지울지: 판단표

| 내 상황                | 할 일                     |
| ---------------------- | ------------------------- |
| 포그라운드 짧은 사운드 | `audio` 제거              |
| 음악이나 오디오북      | 유지하고 보여 주기        |
| 긴 녹음                | 유지 + 동의               |
| 알람이나 타이머        | AlarmKit (iOS 26)         |
| 가끔 필요한 위치       | 중요 위치 변경 서비스     |
| 급하지 않은 동기화     | `fetch` 또는 `processing` |
| 음성 또는 영상 통화    | CallKit과 함께 `voip`     |

위치의 경우, Apple 문서는 `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 규칙을 지켜야 한다고 강조해요. **원격 업데이트는 수정용으로만 쓰고, 리뷰어가 보지 못한 기능을 배포하는 데는 절대 쓰지 마세요.** 리뷰와 관련된 수정은 새 빌드로 내야 해요. [가이드라인 2.1](https://devoria.fr/ko/blog/guideline-2-1-app-store-rejection-fix) 가이드에서 설명했어요.

## 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/)할 수 있어요. 경우는 두 가지예요.

- **모드가 아무 데도 안 쓰인다면**: 지우고, 다시 빌드하고, introspection으로 확인한 뒤 두 문장으로 답하세요.
- **모드가 실제 기능에 쓰인다면**: 정확한 경로와 짧은 영상으로 답하고, 버전마다 리뷰 노트에 같은 내용을 넣으세요.

제가 쓸 템플릿이에요. 상황에 맞게 고쳐 쓰세요(앱에 알람이 없다면 알람 문장은 지우세요).

```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 introspection에 의도한 모드만 나오고, 각 모드를 쓰는 기능을 말할 수 있다.
- expo-audio처럼 기본으로 모드를 추가하는 플러그인을 짧은 형태로 선언하지 않았다.
- 로컬 `ios/` 폴더에 예전 키가 남아 있지 않거나, 깨끗한 prebuild에서 빌드한다.
- 숨은 설정 없이 기능이 빠르게 실행되고, 리뷰 노트에 어떤 모드가 무엇에 쓰이며 어떻게 테스트하는지 적혀 있다.
- 모든 녹음은 명시적 동의를 받고 눈에 보이는 표시를 띄운다. 권한 요청 규칙은 [가이드라인 5.1.1](https://devoria.fr/ko/blog/guideline-5-1-1-app-store-rejection-fix) 가이드에 있어요.
- 알람 앱이라면 앱에서 재생하는 소리가 아니라 AlarmKit으로 알람을 울린다.

## 제출 전에 내 앱 점검하기

[Review Kit](https://devoria.fr/ko/kits/app-review)에는 제출 전 체크리스트, 리뷰어용 노트 템플릿, 프로젝트를 검토해 주는 Claude Code skills가 들어 있어요. 사람의 눈으로 보고 싶다면 [저와 한 시간 예약하세요](https://devoria.fr/ko/coaching). 화상으로 Apple 메시지와 Info.plist를 함께 읽어 봐요. 전체 과정은 [Apple에 리젝된 앱](https://devoria.fr/ko/expertise/app-rejected-by-apple) 페이지에 있어요.

첫 출시를 준비 중인가요? [무료 진단을 받아 보세요](https://devoria.fr/ko/diagnostic). 단계를 순서대로 정리해 주고, 제 Apple 리젝 방지 체크리스트를 보내 드려요.

Apple이 앱을 승인할 거라고 누구도 장담할 수 없어요. 하지만 제대로 정당화된 백그라운드 모드는 30초 만에 설명할 수 있어요.

## 자주 묻는 질문

### "Guideline 2.5.4 - Performance - Software Requirements"는 무슨 뜻인가요?

Info.plist의 백그라운드 모드가 원래 용도로 쓰이지 않는다고 Apple이 판단했을 때 붙는 리젝 제목이에요. 메시지에는 해당 모드가 적혀 있고, 그 모드를 쓰는 기능을 보여 주거나 키를 지우라고 안내해요.

### 2.5.4 리젝 후에 새 빌드가 필요한가요?

모드를 지우거나 바꾼다면 필요해요. 키가 Info.plist, 즉 바이너리에 있으니까요. 모드가 정당하다면 정확한 경로와 영상을 담은 답장만으로 충분할 수 있어요.

### UI 사운드 몇 개 때문에 audio 모드를 유지해도 되나요?

안 돼요. 포그라운드에서 재생하는 짧은 사운드에는 필요 없어요. Expo에서는 expo-audio 플러그인의 `enableBackgroundPlayback`을 `false`로 설정하세요.

### 알람 앱에 audio 모드가 필요한가요?

iOS 26부터 쓸 수 있는 AlarmKit을 쓴다면 알람을 울리는 데는 필요 없어요. 알람은 시스템이 재생해요. Solys에서 `audio` 모드는 화면이 잠긴 상태로 녹음하는 수면 소리 듣기 기능에 쓰여요.

### 아무것도 선언하지 않았는데 왜 Apple이 2.5.4를 언급하나요?

플러그인이 대신 선언했을 수 있어요. expo-audio는 기본으로 `audio` 모드를 추가하고, 예전 `ios/` 폴더에는 설정에서 지운 키가 남아 있을 수 있어요. `npx expo config --type introspect`로 확인하세요.


## 내 프로젝트

[Review Kit](https://devoria.fr/ko/kits/app-review): 제 App Store 심사 체크리스트, 수정해서 통과한 Apple 리젝 사례, Google Play 체크리스트, Claude Code 스킬 3개를 담았어요. ₩73,000.

[iOS & Android Kit](https://devoria.fr/ko/kits/ios): Claude Code로 iPhone·Android 앱을 만들어 보세요. 제 앱들의 시작 코드, 스토어 출시까지의 과정, 모든 키트를 담았어요. ₩148,000.

[진단: 내 아이폰 앱까지 남은 거리](https://devoria.fr/ko/diagnostic): 7개 질문, 60초. 아이폰 앱 출시를 진짜 가로막는 게 뭔지, 4단계 로드맵, 나에게 맞는 키트까지 알려드려요.
