Django + Next.js 웹앱을 iOS 앱으로 배포하기 — 2026 App Store / TestFlight 실전 가이드
Django + Next.js 웹앱을 iOS 앱으로 배포하기 — 2026 App Store / TestFlight 실전 가이드
Django + Next.js로 웹앱을 이미 잘 만들고 있는데, iOS 앱도 필요해지는 순간이 옵니다.
“iOS는 TWA 같은 거 없나?”
“웹앱 그대로 감싸서 App Store에 올릴 수 있나?”
결론부터 말하면, iOS는 Android(TWA)처럼 ‘Chrome 기반 전체화면’ 배포가 없습니다.
대신 현실적인 선택지는 크게 두 가지입니다.
- PWA로 끝내기(스토어 미배포): Safari “홈 화면에 추가”로 설치 유도. 빠르고 싸지만 App Store에는 올라가지 않음.
- 웹앱을 iOS 앱으로 래핑해서 App Store 배포: 보통 Capacitor(iOS WKWebView) 로 감싸서 배포.
이 글은 Django + Next.js 웹앱을 Capacitor로 iOS 앱으로 만든 뒤 TestFlight → App Store까지 배포하는 과정을 “처음 해보는 기준”으로 아주 상세히 정리합니다.
0. iOS 배포에서 가장 중요한 현실 체크
0.1 Mac이 사실상 필수
iOS 앱을 App Store에 올리려면 Xcode로 아카이브/서명/업로드를 해야 하는데, Xcode는 macOS에서만 동작합니다.
- 개인 Mac / 회사 Mac: 가장 편함
- Mac 빌드 서버(클라우드 Mac): 가능하지만 서명/키체인 등 난이도가 올라감
0.2 Apple Developer Program 비용
App Store 배포를 위해서는 Apple Developer Program 가입이 필요합니다.
- 연 $99(연간 구독)
(Apple 공식 안내:https://developer.apple.com/support/compare-memberships)
0.3 2026년 SDK/Xcode 요구사항
Apple은 특정 시점 이후 App Store Connect에 업로드하는 앱은 특정 Xcode/SDK로 빌드해야 한다는 요구사항을 둡니다.
2026년 4월 28일 이후에는 Xcode 26+ 및 해당 플랫폼 SDK(iOS 26 등)로 빌드해야 업로드가 가능하다고 공지되어 있습니다.
- 참고:
https://developer.apple.com/news/upcoming-requirements/?id=02032026a
사용자의 최소 지원 iOS 버전(예: iOS 16+)과는 다른 이야기입니다. “빌드에 사용하는 SDK” 요구사항이라고 이해하면 됩니다.
1. 방법 선택: “원격 URL” vs “정적 번들” (Capacitor)
Capacitor로 iOS 앱을 만들 때 Next.js를 어떻게 넣을지 먼저 결정해야 합니다.
1.1 원격 URL 방식(추천: SSR 유지)
앱이 https://app.example.com 같은 웹 URL을 WKWebView로 로딩합니다.
- 장점
- Next.js SSR / Server Actions / API Route를 그대로 사용 가능
- 웹 배포 = 앱 화면 즉시 반영 (스토어 심사 없이 UI 수정 가능)
- 단점
- 오프라인 경험은 제한적
- 네트워크 품질이 UX에 직접 영향
1.2 정적 번들 방식(주의: SSR 포기)
Next.js를 output: 'export'로 정적 빌드(out/)해서 앱에 번들링합니다.
- 장점
- 초기 로딩이 안정적
- 네트워크가 느려도 “앱 껍데기”는 뜸
- 단점
- Next.js의 SSR, API Route 등 서버 기능을 쓸 수 없음(별도 백엔드 호출로 전환 필요)
- 웹 UI 수정 시 앱을 다시 빌드/업로드해야 할 가능성이 큼
이 글에서는 Django + Next.js 조합에서 가장 현실적인 “원격 URL 방식”을 메인으로 설명하고, 정적 번들은 “선택지”로만 덧붙입니다.
2. 앱 패키징(웹→iOS): Capacitor 기본 셋업
2.1 Next.js 쪽 준비(공통)
- HTTPS 배포(필수)
- 모바일 화면 대응(뷰포트, 폰트, 터치 영역)
- 로그인/결제 등 앱 내 플로우에서 Safari 외부로 튀지 않도록 링크 처리
그리고 Django API 도메인과 Next.js 프론트 도메인은 분리해두는 것이 좋습니다.
Next.js: https://app.example.com
Django API: https://api.example.com
2.2 Capacitor 설치
npm install @capacitor/core @capacitor/cli
2.3 초기화(원격 URL 방식)
npx cap init "내서비스" "com.example.myapp"
capacitor.config.ts를 만들고, 서버 URL을 지정합니다.
// capacitor.config.ts
import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = {
appId: "com.example.myapp",
appName: "내서비스",
webDir: "out", // 원격 URL이면 사실상 사용 비중 낮음
server: {
url: "https://app.example.com",
cleartext: false,
},
};
export default config;
개발 중에는
server.url을 로컬/프리뷰 URL로 바꿔서 빠르게 테스트할 수 있습니다.
2.4 iOS 플랫폼 추가
npm install @capacitor/ios
npx cap add ios
이제 iOS 프로젝트(ios/)가 생성됩니다.
2.5 Xcode로 열기
npx cap open ios
Xcode가 열리면 좌측 프로젝트 네비게이터에서 App 타겟을 선택하고:
- Bundle Identifier:
com.example.myapp(Play와 마찬가지로 바꾸기 어렵습니다) - Version / Build:
1.0.0/1 - Team: Apple Developer Program 팀 선택
- Automatically manage signing: 켜기(초보자에게 강력 추천)
3. Django + Next.js에서 iOS용으로 꼭 챙길 것
3.1 인증: 쿠키 기반 세션 vs JWT
WKWebView 안에서 쿠키 세션도 가능하지만, 실제 운영에서는 JWT(토큰) 방식이 더 예측 가능할 때가 많습니다.
- 쿠키 세션: CSRF, SameSite, 도메인 분리 시 난이도 상승
- JWT: 모바일(웹뷰)에서 저장/갱신 흐름을 명확히 만들기 쉬움
어떤 방식을 쓰든 “app.example.com”과 “api.example.com” 사이의 인증/쿠키 정책을 iOS WebView 환경에서 한 번은 꼭 점검하세요.
3.2 CORS
원격 URL 방식이면 브라우저와 동일하게 동작합니다.
# settings.py
CORS_ALLOWED_ORIGINS = [
"https://app.example.com",
]
3.3 딥링크(앱 내부 링크) 전략
iOS에서 알림이나 링크 클릭 시 앱 특정 화면으로 보내고 싶으면 대체로:
- 웹 딥링크 URL을 통일(예:
/orders/123) - 앱은 그 URL을 그대로 WebView에 로딩
이 구조가 Django/Next.js 조합에서는 가장 단순하고 유지보수성이 좋습니다.
4. App Store Connect 준비: “앱 정보”가 심사의 절반
App Store 심사는 코드만 보는 게 아니라 “메타데이터”와 “정책 대응”이 큰 비중을 차지합니다.
4.1 App Store Connect에서 앱 생성
- App Store Connect 로그인
- My Apps → New App
- 플랫폼 iOS 선택, 번들 ID 선택, SKU 입력
4.2 Privacy Policy URL은 ‘무조건’ 필요
Apple은 모든 앱에 Privacy Policy URL을 요구합니다.
- 공식 문서:
https://developer.apple.com/help/app-store-connect/manage-app-information/manage-app-privacy/ - App Privacy Details 안내:
https://developer.apple.com/app-store/app-privacy-details/
기능이 단순하고 개인정보를 “수집하지 않는다” 하더라도, URL 자체는 필수입니다.
4.3 App Privacy(“영양성분표”) 작성
App Store Connect에서 앱이 수집하는 데이터 유형, 추적 여부 등을 선언해야 합니다.
여기서 거짓말하면 리젝/퇴출 리스크가 큽니다(서드파티 SDK 포함).
- 참고:
https://developer.apple.com/app-store/app-privacy-details/
4.4 스크린샷 규격(2026)
App Store Connect는 스크린샷 사이즈를 엄격히 봅니다. 다행히 “큰 사이즈 1세트”만 올리면 자동 스케일되는 구조가 있어졌습니다.
- 공식 스펙(6.9"/6.5" 등):
https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications - 업로드 안내:
https://developer.apple.com/help/app-store-connect/manage-app-information/upload-app-previews-and-screenshots
가장 안전한 추천(아이폰):
- iPhone 6.9" 스크린샷(예: 1320×2868, 1290×2796 등) 1~10장
- 6.9"를 못 올리면 6.5" 세트가 대체로 요구됨(공식 스펙에 명시)
iPad도 지원한다면 iPad 스크린샷도 요구될 수 있습니다. (Universal 앱이면 특히)
5. Xcode 아카이브 & 업로드(가장 많이 막히는 구간)
5.1 왜 “아카이브(Archive)”가 필요한가
App Store에 올릴 바이너리는 그냥 Run 빌드가 아니라, Distribution용 Archive를 만들어야 합니다.
Xcode 메뉴:
- 상단 Scheme을 “Any iOS Device (arm64)” 같은 디바이스 계열로 선택
- Product → Archive
5.2 서명(Signing): 초보자에게는 “자동 서명” 추천
대부분은 Xcode에서 아래만 제대로 맞추면 자동으로 풀립니다.
- Team이 올바른가?
- Bundle Identifier가 App Store Connect의 App ID와 일치하는가?
- Automatically manage signing이 켜져 있는가?
Apple은 자동 서명을 권장합니다(코드 사인 관련 기본 안내).
- 참고(자동 서명 개념):
https://developer.apple.com/library/archive/qa/qa1814/_index.html
5.3 App Store Connect 업로드
Archive가 생성되면 Organizer가 뜹니다.
- Distribute App → App Store Connect → Upload
업로드 후 App Store Connect에서 빌드가 “Processing” 상태로 몇 분~수십 분 걸릴 수 있습니다.
6. TestFlight 배포(실제 기기 검증 루프)
App Store에 바로 올리기 전에 TestFlight로 베타 배포를 강력 추천합니다.
6.1 내부/외부 테스터 차이
Apple 공식 TestFlight 문서 기준:
- Internal testers: 최대 100명
- External testers: 최대 10,000명, 첫 빌드는 Beta App Review가 필요할 수 있음
참고:
- TestFlight overview:
https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview/ - TestFlight 소개:
https://developer.apple.com/testflight/
6.2 가장 빠른 루트(추천)
- App Store Connect에 빌드 업로드
- TestFlight → Internal Testing 그룹 생성
- 팀원(Users and Access)을 내부 테스터로 추가
- TestFlight에서 설치 후 실제 로그인/결제/푸시 등 확인
외부 테스터까지 가는 건 “첫 출시 전 QA” 때만 열어도 됩니다.
7. App Store 출시(심사 통과를 위한 체크리스트)
7.1 앱 심사에서 자주 걸리는 포인트
웹앱 래핑(iOS WebView) 앱에서 특히 자주 걸리는 것들:
- 로그인 계정이 필요한데 심사팀이 접근 불가
→ App Review 정보에 테스트 계정/비밀번호 제공 - 결제/구독/디지털 상품 관련 정책 위반(웹 결제를 우회하거나, 기능 제한 설명이 불명확)
→ Apple 가이드 준수(이 주제는 별도 포스트로 분리 추천) - Privacy Policy / App Privacy 미작성 또는 부정확
- 앱 내 링크가 Safari로 튀어 UX가 깨짐
- 빈 화면/오프라인/서버 점검 시 크래시
7.2 제출 흐름
- App Store Connect에서 버전 생성
- 스크린샷/설명/키워드/카테고리/연령등급/Privacy 채우기
- 빌드 선택
- Submit for Review
8. 운영 전략: “웹 업데이트”와 “앱 업데이트”를 분리하자
원격 URL 방식(Capacitor WebView)으로 가면 운영이 이렇게 단순해집니다.
- 일상적인 UI/기능 개선: Next.js 배포 → iOS 앱 즉시 반영
- 앱 스토어 업데이트가 필요한 변경:
- 앱 아이콘/스플래시 변경
- 네이티브 플러그인 추가(카메라, 푸시 등)
- Bundle ID/Entitlements 변경
이 분리 전략이 Django + Next.js 개발자에게 iOS 배포 난이도를 크게 낮춰줍니다.
9. (선택) 정적 번들 방식으로 가고 싶다면
Next.js를 정적으로 export하고, 앱에 번들링하면 “초기 로딩”은 좋아질 수 있습니다. 하지만 Django + Next.js에서 SSR이나 API Route를 쓰고 있었다면 전환 비용이 큽니다.
요약:
next.config.ts에output: "export"적용- 빌드 산출물(out/)을 Capacitor가 iOS 앱에 포함
- SSR 로직은 Django API 호출로 재작성
이 경로는 “앱이 오프라인에서도 최소 화면을 보여줘야 한다” 같은 요구가 있을 때만 추천합니다.
10. 정리: Django + Next.js 개발자에게 가장 좋은 iOS 배포 루트
현실적인 우선순위는 보통 이렇습니다.
- App Store가 꼭 필요한가?
- 아니라면: PWA + 홈 화면 추가로도 충분한 경우가 많음
- App Store가 필요하다면: Capacitor(원격 URL) + TestFlight → App Store
- SSR 유지, 웹 업데이트 즉시 반영, 유지보수 비용 최소
- 카메라/푸시/파일 등 네이티브 기능이 늘어나면: Capacitor 플러그인을 단계적으로 추가
iOS는 Android보다 “서명/프로비저닝/메타데이터”가 진입장벽이지만, 한 번 파이프라인을 만들면 이후 릴리즈는 빠르게 반복할 수 있습니다.
참고 자료
- Apple Developer Program 가입/비용:
https://developer.apple.com/support/compare-memberships - SDK/Xcode 업로드 요구사항(2026):
https://developer.apple.com/news/upcoming-requirements/?id=02032026a - TestFlight 개요:
https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview/ - TestFlight 소개:
https://developer.apple.com/testflight/ - App Privacy(필수):
https://developer.apple.com/app-store/app-privacy-details/ - Privacy Policy URL 요구(필수):
https://developer.apple.com/help/app-store-connect/manage-app-information/manage-app-privacy/ - 스크린샷 스펙(공식):
https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications - 스크린샷 업로드 가이드:
https://developer.apple.com/help/app-store-connect/manage-app-information/upload-app-previews-and-screenshots