모바일 네이티브 앱 개발 기술 스택 안내

# 모바일 네이티브 앱 개발 기술 스택 안내

Canonical URL: https://duolabs.co.kr/docs/%EB%AA%A8%EB%B0%94%EC%9D%BC-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-%EC%95%B1-%EA%B0%9C%EB%B0%9C-%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%83%9D-%EC%95%88%EB%82%B4
Author: Duolabs (https://duolabs.co.kr)
License: Creative Commons Attribution 4.0 International (https://creativecommons.org/licenses/by/4.0/)
Last modified: 2026-07-31T21:58:01.970Z
Tags: android, docs, ios, native-mobile, public-doc

# 모바일 네이티브 앱 개발 기술 스택 안내

## 문서 개요

모바일 네이티브 앱은 운영체제가 공식 지원하는 언어와 UI 프레임워크로 iOS와 Android 앱을 각각 개발하는 방식입니다.

- iOS: Swift와 SwiftUI
- Android: Kotlin과 Jetpack Compose

두 플랫폼의 코드를 별도로 운영하는 대신, 최신 운영체제 기능과 기기 API를 빠르게 적용하고 각 플랫폼의 사용 경험을 세밀하게 다룰 수 있습니다. 다만 모든 앱에 네이티브 방식이 필요한 것은 아닙니다. 제품 요구사항, 팀 구성, 출시 일정, 플랫폼별 기능의 깊이를 함께 검토해 선택합니다.

## 문서 범위

이 문서는 다음과 같은 모바일 네이티브 앱 영역을 다룹니다.

- iOS 및 Android 앱 화면과 사용자 흐름
- 앱 상태 관리와 API 연동
- 기기 내 데이터 저장과 보안 저장소
- 푸시 알림 수신과 백그라운드 작업
- 앱 테스트, 빌드, 스토어 배포

다음 영역은 이 문서의 네이티브 앱 범위에 포함하지 않습니다.

- Flutter 또는 React Native 기반 크로스플랫폼 앱
- 반응형 웹, PWA, Flutter Web, React Native Web
- 신규 백엔드 API와 데이터베이스 설계
- 관리자 웹, 홈페이지, 운영 대시보드

크로스플랫폼 앱은 [모바일 앱 개발 기술 스택 안내](https://docs.duolabs.co.kr/모바일-앱-개발-기술-스택-안내)에서 별도로 설명합니다.

## iOS 네이티브 개발 스택

### 기본 구성

| 영역 | 기술 | 역할 |
|---|---|---|
| 개발 언어 | Swift | iOS 앱 로직 구현 |
| UI | SwiftUI | 선언형 화면 구성과 상태 기반 UI 갱신 |
| 화면 이동 | NavigationStack | 화면 계층과 탐색 경로 관리 |
| 상태 구조 | Observation 또는 단방향 데이터 흐름 | 화면 상태를 예측 가능하게 관리 |
| 비동기 처리 | Swift Concurrency | async/await와 Task를 이용한 비동기 작업 |
| 네트워크 | URLSession | HTTPS API 요청과 응답 처리 |
| 로컬 데이터 | SwiftData 또는 Core Data | 구조화된 앱 데이터 저장 |
| 보안 저장 | Keychain Services | 로그인 토큰 등 민감한 소량 데이터 보관 |
| 푸시 알림 | APNs, UserNotifications | 원격 알림 수신과 사용자 알림 표시 |
| 백그라운드 작업 | BackgroundTasks | 운영체제 정책 안에서 지연 가능한 작업 수행 |
| 테스트 | XCTest | 단위 테스트와 UI 테스트 |
| 배포 | Xcode, TestFlight, App Store Connect | 서명, 테스트 배포, App Store 제출 |

### 권장 구조

```text
SwiftUI View
↓ 사용자 동작
화면 상태 · 도메인 로직
↓
Repository 또는 Service
├─ URLSession → 외부 API
├─ SwiftData/Core Data → 로컬 데이터
└─ Keychain → 인증 정보
```

화면은 표현과 사용자 입력에 집중하고, 네트워크·저장·도메인 규칙은 별도 계층으로 분리합니다. Swift Concurrency를 이용해 비동기 흐름을 명확히 표현하고, UI를 갱신하는 상태는 메인 실행 컨텍스트에서 안전하게 관리합니다.

## Android 네이티브 개발 스택

### 기본 구성

| 영역 | 기술 | 역할 |
|---|---|---|
| 개발 언어 | Kotlin | Android 앱 로직 구현 |
| UI | Jetpack Compose | 선언형 화면 구성과 상태 기반 UI 갱신 |
| 화면 이동 | Jetpack Navigation | 화면 목적지와 탐색 흐름 관리 |
| 상태 구조 | ViewModel, StateFlow, 단방향 데이터 흐름 | 생명주기를 고려한 화면 상태 관리 |
| 비동기 처리 | Kotlin Coroutines, Flow | 비동기 작업과 데이터 스트림 처리 |
| 네트워크 | Retrofit/OkHttp 또는 Ktor | HTTPS API 요청과 응답 처리 |
| 로컬 데이터 | Room | SQLite 기반 구조화 데이터 저장 |
| 설정 저장 | DataStore | 사용자 설정과 소규모 상태 저장 |
| 보안 저장 | Android Keystore | 암호화 키와 민감 정보 보호 |
| 의존성 주입 | Hilt | 규모가 커진 앱의 객체 생성과 의존 관계 관리 |
| 백그라운드 작업 | WorkManager | 지연 가능하고 완료 보장이 필요한 작업 예약 |
| 푸시 알림 | Firebase Cloud Messaging | Android 푸시 메시지 수신 |
| 테스트 | JUnit, Compose UI Test | 단위 테스트와 UI 테스트 |
| 배포 | Gradle, Play Console | 빌드, 서명, 테스트 배포, Google Play 제출 |

### 권장 구조

```text
Compose UI
↓ 사용자 동작
ViewModel · StateFlow
↓
Repository
├─ Network data source → 외부 API
├─ Room data source → 로컬 데이터
└─ DataStore/Keystore → 설정·보안 정보
```

UI는 상태를 받아 화면을 그리고 이벤트를 위로 전달하는 단방향 데이터 흐름으로 구성합니다. ViewModel은 화면 상태를 보관하고, Repository는 네트워크와 로컬 데이터의 출처를 조정합니다. 오래 걸리거나 앱이 종료된 뒤에도 이어져야 하는 지연 작업은 WorkManager에 맡깁니다.

## iOS와 Android 구성 비교

| 구분 | iOS 네이티브 | Android 네이티브 |
|---|---|---|
| 언어 | Swift | Kotlin |
| 선언형 UI | SwiftUI | Jetpack Compose |
| 화면 상태 | Observation 기반 상태 관리 | ViewModel + StateFlow |
| 비동기 처리 | Swift Concurrency | Coroutines + Flow |
| 네트워크 | URLSession | Retrofit/OkHttp 또는 Ktor |
| 로컬 DB | SwiftData 또는 Core Data | Room |
| 보안 저장소 | Keychain Services | Android Keystore |
| 푸시 | APNs | Firebase Cloud Messaging |
| 백그라운드 작업 | BackgroundTasks | WorkManager |
| 테스트 배포 | TestFlight | Play Console 테스트 트랙 |

기술 이름은 다르지만 핵심 원칙은 같습니다. UI와 비즈니스 규칙을 분리하고, 앱 상태를 한 방향으로 흐르게 하며, 네트워크·저장소·기기 기능을 교체 가능한 경계 뒤에 둡니다.

## 네이티브 개발이 잘 맞는 경우

다음 조건이 중요할수록 네이티브 앱이 유리합니다.

- 카메라, Bluetooth, NFC, 센서, 위치 등 기기 기능을 깊게 사용해야 하는 경우
- 새 운영체제 기능과 공식 SDK를 빠르게 적용해야 하는 경우
- 플랫폼별 디자인과 접근성 경험을 세밀하게 구현해야 하는 경우
- 기존 Swift 또는 Kotlin 코드와 네이티브 SDK 자산이 충분한 경우
- iOS와 Android의 기능 및 출시 주기를 독립적으로 운영해야 하는 경우
- 장기적으로 플랫폼별 전문 개발팀을 운영할 계획인 경우

화면과 비즈니스 로직을 많이 공유해야 하고, 하나의 팀이 두 플랫폼을 빠르게 제공하는 것이 더 중요하다면 Flutter 또는 React Native가 더 적합할 수 있습니다.

## 공통 보안 및 품질 원칙

- 앱 코드에 API 비밀키나 관리자 권한을 포함하지 않습니다.
- 로그인 세션과 민감 정보는 Keychain 또는 Keystore를 이용해 보호합니다.
- 서버 통신은 HTTPS를 사용하고, 입력값과 서버 응답을 모두 검증합니다.
- 카메라, 위치, 연락처 같은 권한은 실제 기능에 필요한 시점에 최소 범위로 요청합니다.
- 백그라운드 실행은 각 운영체제의 수명 주기와 제한을 따릅니다.
- 단위 테스트와 UI 테스트를 함께 구성하고 실제 기기에서도 검증합니다.
- 개발·스테이징·운영 환경을 분리하고 운영 로그에 개인정보를 남기지 않습니다.
- Apple 및 Google 개발자 계정, 인증서, 서명 키의 소유권과 접근 권한을 명확히 관리합니다.

## 백엔드와의 연결

네이티브 앱은 사용자 기기에서 실행되는 클라이언트입니다. 데이터 저장, 권한 검증, 결제 확인, 알림 발송처럼 신뢰가 필요한 로직은 앱이 아니라 백엔드에서 처리해야 합니다.

```text
iOS 앱 (Swift · SwiftUI) ─┐
├─ HTTPS API ─ 백엔드 ─ 데이터베이스
Android 앱 (Kotlin · Compose) ─┘
```

백엔드는 기존 시스템을 연동하거나 별도 범위로 구축할 수 있습니다. 예를 들어 Vercel Functions와 Supabase를 기본 구성으로 사용하고, 필요할 때 Upstash Redis, QStash, Resend 같은 서비스를 추가할 수 있습니다. 이러한 서비스는 네이티브 앱 자체의 기술 스택이 아니라 앱이 연결하는 서버 측 구성입니다.

## 운영 단계에서 추가로 검토할 항목

- 로그인 및 계정 복구 정책
- 앱 링크와 딥링크
- 푸시 알림 권한과 발송 정책
- 오프라인 상태와 동기화 충돌 처리
- 접근성, 다국어, 시간대
- 앱 오류 및 성능 모니터링
- 개인정보 처리와 계정 삭제 흐름
- App Store 및 Google Play 심사 기준
- 최소 지원 운영체제와 기기 범위

## 참고 문서

- [Apple SwiftUI](https://developer.apple.com/documentation/swiftui)
- [Apple Swift Concurrency](https://developer.apple.com/documentation/swift/concurrency)
- [Apple URLSession](https://developer.apple.com/documentation/foundation/urlsession)
- [Apple Keychain Services](https://developer.apple.com/documentation/security/keychain-services/)
- [Android 앱 아키텍처 권장사항](https://developer.android.com/topic/architecture/recommendations)
- [Android Jetpack Compose 아키텍처](https://developer.android.com/develop/ui/compose/architecture)
- [Android Room](https://developer.android.com/training/data-storage/room)
- [Android WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
- [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging)

기술 선택은 앱의 핵심 기능, 플랫폼별 요구사항, 운영 조직, 출시 전략을 기준으로 결정합니다. 구체적인 버전과 라이브러리는 프로젝트 시작 시점의 공식 지원 상태와 장기 유지보수 가능성을 확인한 뒤 확정합니다.