가이드라인 2.5.1: Expo 앱의 공개 API와 최신 SDK 대응
글: Mehdi Azizi
게시, 9분
가이드라인 2.5.1은 공개 API만 쓰고, 현재 iOS에서 동작하며, 프레임워크를 원래 용도로 쓰라는 규칙이에요. Expo 앱이라면 네이티브 모듈부터 점검하세요.
가이드라인 2.5.1은 네 가지를 요구해요. 공개 API만 사용할 것, 현재 iOS 버전에서 동작할 것, Apple이 지원 중단(deprecated)한 기능은 걷어낼 것, 그리고 각 프레임워크를 원래 용도대로 쓸 것. Expo 앱이라면 위험은 JavaScript 코드에서 오는 경우가 드물어요. 설치한 네이티브 모듈과 빌드에 쓰는 SDK에서 와요.
저는 Solys, TradaZen, Nolera를 Expo SDK 57로 출시하고 있어요. Solys는 사용 조건이 엄격한 프레임워크인 Apple의 Screen Time API를 사용해요. 이 글은 심사 규칙을 다뤄요. 빌드 업로드 때 받는 오류는 ITMS-90338 가이드를 읽어 보세요. 같은 섹션에 있는 백그라운드 모드는 가이드라인 2.5.4 가이드에서 다뤄요.
가이드라인 2.5.1은 무엇을 말하나요?
이 규칙은 App Review Guidelines의 2.5 섹션 "Software Requirements"에 있어요. "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."
정리하면 네 가지 의무예요.
- 공개 API만 사용, 즉 Apple이 문서화한 API만 써야 해요.
- 현재 iOS 버전에서 동작하는 앱이어야 해요. 2026년 9월부터는 iOS 27이에요.
- 곧 사라질 지원 중단 기능은 쓰지 않기: Apple이 지원 종료를 예고한 건 교체해야 해요.
- 각 프레임워크는 제자리에, 그리고 설명에 명시: HomeKit은 스마트 홈용, HealthKit은 건강과 운동용으로 건강 앱과 연동돼야 해요.
그래서 거절 제목이 "Guideline 2.5.1 - Performance - Software Requirements"인 거예요.
공개 API: Expo 앱에서 위험이 숨어 있는 곳
비공개 API는 Apple이 문서화하지 않은 시스템 함수예요. Apple은 그 동작도, 다음 iOS 버전에 남아 있을지도 보장하지 않아요. 그래서 금지돼요.
JavaScript 코드는 iOS를 직접 건드리지 않아요. 네이티브 모듈을 거치죠. Expo SDK의 모듈은 Expo 팀이 관리해요. 나머지 모듈에는 내가 쓰지 않은 코드가 들어 있고, Apple은 그 코드를 내 코드처럼 심사해요. ITMS-90683 가이드에서도 권한 설명 문구로 같은 원리를 보여 줘요. Apple은 앱이 실제로 하는 일이 아니라 빌드에 들어 있는 코드를 기준으로 판단해요.
2026년 10월 15일 기준, Solys에는 iOS 네이티브 코드를 포함한 직접 의존성이 42개 있고, 그중 14개가 Expo SDK 밖에 있어요. RevenueCat, Sentry, AppsFlyer, 그리고 Screen Time API 브리지인 react-native-device-activity가 여기에 해당해요.
비공개 API는 두 시점에 걸릴 수 있어요. 업로드 때 App Store Connect 자동 분석이 ITMS-90338 오류를 반환할 수 있고, 심사 중에는 리뷰어가 2.5.1을 인용해요.
지원 중단 API: UIWebView에서 UIScene까지
가장 유명한 예는 웹을 표시하던 옛 컴포넌트 UIWebView예요. Apple은 2020년 4월에 신규 앱, 2020년 12월에 업데이트에서 UIWebView를 더 이상 받지 않았어요. 아직 UIWebView를 참조하던 오래된 라이브러리 하나 때문에 업로드가 막혔죠. Solys에서는 아래 체크리스트의 검색을 돌려도 참조가 하나도 나오지 않아요.
다음 변화는 이미 예고돼 있어요. Apple 기술 노트 TN3187에 이렇게 적혀 있어요. "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." 즉, 씬 기반 생명주기 없이 iOS 27 SDK로 빌드한 앱은 실행되지 않아요.
연결해서 봐야 할 날짜가 세 개 있어요.
- 2026년 4월부터 Apple은 Xcode 26을 요구해요. ITMS-90725 가이드에서 다루는 내용이에요.
- 2027년 4월에는 iOS 27 SDK가 필수라고 Apple 제출 페이지에서 예고하고 있어요.
- Expo SDK 58은 2026년 9월 15일부터 베타이고, Expo 발표에 따르면 이미 씬 처리를 생성해요.
Expo SDK 57과 Xcode 26 조합이라면 아직 iOS 26 SDK로 빌드하니까 지금 당장 깨지는 건 없어요. 다만 AppDelegate를 수정하는 모듈은 2027년 4월 전에 대응해야 해요.
원래 용도에서 벗어나 쓰인 프레임워크
리뷰어는 민감한 프레임워크가 눈에 보이는 기능에 쓰이는지, 그리고 스토어 페이지에 그 내용이 적혀 있는지 확인해요.
- HealthKit은 건강과 운동용이에요. Apple 인터페이스 가이드라인에도 나와 있어요. "If your app doesn't provide health and fitness functionality, don't request access to people's private health data."
- HomeKit은 스마트 홈용이고, 그 외 용도는 안 돼요.
- PushKit은 VoIP 통화용이에요. PushKit 문서는 분명해요. "If you are unable to support CallKit in your app, you cannot use PushKit to handle push notifications." 통화 없이 앱을 깨우는 VoIP 알림은 용도 위반이에요.
- Family Controls, 즉 Screen Time API는 특별 권한이 필요해요. 문서에 이렇게 적혀 있어요. "Before submitting your app to the App Store, you must request permission to use the entitlement."
Solys의 경우 2026년 9월 23일에 이 배포 권한을 신청했고, Apple이 당일에 승인해 줬어요. 용도도 프레임워크에 딱 맞아요. 사용자가 일시 정지할 앱을 고르면, Solys가 기상 후 30분, 45분 또는 60분 동안 그 앱들을 차단해요. 스토어 설명에도 한 문장으로 적어 뒀어요. "Solys는 Apple의 Screen Time 권한을 사용해 선택한 앱을 일시 정지합니다." 이게 바로 2.5.1 마지막 부분이 요구하는 것, 설명에 연동 내용을 명시하는 거예요.
베타 버전: TestFlight는 OK, App Store는 안 돼요
App Store Connect 릴리스 노트를 보면 실제 규칙이 보여요. 2026년 10월 14일, Xcode 27.2 베타 3으로 만든 빌드는 "for internal and external testing", 즉 TestFlight용으로 허용돼요. 10월 5일에는 Xcode 27.1 RC 빌드가 "for the App Store"로 허용됐어요.
Xcode 베타로 빌드한 앱은 TestFlight로는 가지만, 심사에는 절대 못 가요. 제출하려면 정식 버전이나, Apple이 App Store용으로 열어 준 RC가 필요해요.
Expo 앱 기준으로 두 가지를 덧붙일게요.
- Expo 베타는 Apple 베타가 아니에요. Apple이 확인하는 건 Xcode와 iOS SDK 버전이지 Expo 버전이 아니에요. SDK 58 발표에는 Xcode 27이 들어간 EAS 이미지가 곧 나온다는 내용도 있었어요.
- iOS 26 SDK로 빌드하더라도 현재 iOS에서 테스트하는 건 필수예요. 최신 버전의 iPhone이나 시뮬레이터에서 앱을 콜드 스타트로 실행해 보세요.
체크리스트: 제출 전 네이티브 의존성 점검
프로덕션 빌드마다 돌려 보세요. 명령어는 Expo 프로젝트 루트에서 실행해요.
npx expo-doctor
npx expo install --check
grep -rlw "UIWebView" node_modules --include='*.m' --include='*.mm' --include='*.swift' --include='*.h'
npx expo-doctor에서 실패 항목이 없어요. Solys에서 2026년 10월 15일에 돌렸을 때 21개 중 20개를 통과했어요. 실패 원인은 패치 버전이 하나씩 뒤처진 Expo 패키지 13개였고,npx expo install --check로 맞췄어요.- Expo SDK 밖의 모든 모듈이 React Native Directory에 등록돼 있어요. Expo 문서에 나와 있듯이 Expo Doctor가 기본으로 이 검사를 해요. 모르는 패키지라면 iOS 코드를 직접 읽어 볼 만해요.
- 모든 네이티브 모듈이 내 React Native 버전을 따라가요. Expo 버전 표에서 SDK 57은 React Native 0.86과 짝을 이뤄요. 여러 버전째 릴리스가 없는 모듈은 경고 신호예요.
- UIWebView 검색 결과가 없어요. Apple이 지원 종료를 예고한 다른 API도 똑같이 검색하세요.
- 민감한 프레임워크마다 눈에 보이는 기능이 있어요: 건강, Screen Time, 통화, 스마트 홈. 설명에 그 기능이 적혀 있고, 특별 권한도 승인됐어요.
- 빌드는 정식 Xcode로 만들어졌어요. EAS 빌드 로그에서 버전을 확인하세요.
- 현재 iOS 버전에서 새 계정으로 앱이 콜드 스타트돼요.
- AppDelegate를 건드리는 모듈이 UIScene 지원을 발표했어요. iOS 27 SDK로 넘어가기 전에 확인하세요.
2.5.1 거절에는 어떻게 답하나요?
거절 메시지에는 보통 문제가 된 API나 프레임워크 이름이 적혀 있어요. 경우는 두 가지예요.
- 프레임워크가 눈에 보이는 기능에 쓰이지 않는 경우: 모듈이나 capability를 제거하고, 다시 빌드한 뒤, 두 문장으로 답하세요.
- 프레임워크가 실제 기능에 쓰이는 경우: 정확한 경로, 스크린샷이나 짧은 영상을 제공하고, 스토어 설명에 연동 내용을 적어 두세요.
네이티브 모듈을 제거하면 바이너리가 바뀌어요. 원격 업데이트로는 안 돼요. 리뷰어가 왜 번들된 코드만 보는지는 가이드라인 2.1 가이드에서 설명해요. 이후 대화는 App Store Connect에서 이어져요. App Review에 답하기 가이드를 참고하세요.
업로드 전에 프로젝트 점검하기
Review Kit에는 제가 업로드 전에 쓰는 체크리스트, 직접 해결한 거절 사례, Expo 프로젝트를 검토해 주는 Claude Code 스킬이 들어 있어요. 사람이 직접 봐 주길 원하면 저와 한 시간 상담을 예약하세요. Apple 메시지와 의존성을 함께 읽어 봐요. 전체 과정은 Apple 앱 거절 페이지에 정리돼 있어요.
첫 출시를 준비 중인가요? 무료 진단을 받아 보세요. 제 Apple 거절 방지 체크리스트를 보내 드려요.
자주 묻는 질문
"Guideline 2.5.1 - Performance - Software Requirements"는 무슨 뜻인가요?
Apple이 앱에서 비공개 API, 지원 중단된 기술, 또는 원래 용도에서 벗어난 프레임워크를 사용한다고 판단했을 때 붙는 거절 제목이에요. 메시지에는 보통 문제가 된 요소가 적혀 있어요.
가이드라인 2.5.1과 ITMS-90338 오류는 뭐가 다른가요?
ITMS-90338은 빌드 업로드 때 분석이 비공개 심볼을 찾으면 자동으로 받는 오류예요. 2.5.1은 사람이 적용하는 심사 규칙이고, 용도를 벗어난 프레임워크와 지원 중단 기술까지 다뤄요.
Xcode 베타로 빌드한 앱을 제출할 수 있나요?
아니요. App Store Connect는 그런 빌드를 TestFlight용으로만 받아요. 심사를 받으려면 정식 Xcode나, Apple이 릴리스 노트에서 App Store용으로 열어 준 RC로 빌드하세요.
Expo 앱이 모르는 사이에 비공개 API를 쓸 수 있나요?
네, 서드파티 네이티브 모듈을 통해서요. JavaScript 코드는 iOS를 직접 호출하지 않지만, 네이티브 패키지마다 Objective-C나 Swift 코드가 들어 있어요. 버전을 낼 때마다 Expo SDK 밖의 모듈 목록을 살펴보세요.
Expo SDK 58로 바로 올려야 하나요?
2026년 10월 15일 기준 2.5.1 때문이라면 아니에요. SDK 57은 아직 허용되는 iOS 26 SDK로 빌드해요. 다만 Apple이 iOS 27 SDK와 씬 기반 생명주기를 요구하는 2027년 4월 전에 업그레이드를 계획하세요.

