사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
네이티브 설정 흐름
Akan 네이티브 앱은 akanjs의 자체 런타임이 iOS·Android용으로, 그리고 macOS·Windows·Linux용으로도 만들어 내는 네이티브 셸 안에서 CSR 웹 앱을 실행한 것입니다. 페이지와 비즈니스 로직은 웹 앱이 맡습니다. 패키지 ID, 기기 권한, 플러그인, 네이티브 파일, 서명, 스토어 빌드는 셸이 맡으며, 모두 akan.config.ts에 선언합니다.
이 페이지에서 쓰는 말
용어설명
네이티브 런타임
akanjs 안에 들어 있는 @akanjs/native입니다. 웹 앱을 WebView 안에서 실행하고, 플러그인으로 기기 기능을 쓰게 해 줍니다.
CSR 번들
앱을 한 페이지짜리 웹 앱으로 빌드한 결과물입니다. 네이티브 앱에 이 번들이 들어가므로
web.csr을 끄면 안 됩니다.target
Akan 앱 하나에서 만드는 네이티브 앱 하나입니다.
native.targets의 키가 곧 --target에 넘기는 값입니다.appId
앱의 고정 ID입니다. Android에서는 package name, iOS에서는 bundle ID가 됩니다.
dist/native/<app>/<target>
실행할 때마다 target의 웹 루트와 빌드를 쓰는 곳입니다. 생성되고 git에서 제외되며, 고칠 Xcode 프로젝트는 없습니다.
플러그인
카메라, 푸시 같은 네이티브 런타임 모듈입니다. 권한이나
native.plugins가 이름을 대면 앱에 들어갑니다.네 단계
1. native 설정
akan.config.ts에서 앱 이름과 appId를 정하고, target과 권한을 고릅니다.2. 네이티브 플러그인
권한이 제 플러그인을 가져오고, 그 밖의 플러그인은
native.plugins에 적습니다.3. Android · iOS · Desktop
개발 도구를 설치하고 기기에서 앱을 띄운 뒤, 서명과 스토어 빌드를 준비합니다.
4. 확인
빌드 성공에서 멈추지 말고, 실제 기기에서 기능을 하나씩 확인합니다.
푸시 알림과 딥링크는 선택 기능입니다. 이 페이지를 끝낸 뒤, 앱에 필요할 때만 설정하세요.
native 설정
akan.config.ts의 native 블록이 네이티브 앱의 이름, ID, 버전, 권한을 정하고, 한 플랫폼만 읽는 값은 ios, android, desktop 아래에 둡니다. 네이티브 앱을 하나만 내는 앱은 이것으로 충분합니다:apps/myapp/akan.config.ts
appNamestring기본값 앱 이름
홈 화면 아이콘 아래에 보이는 이름입니다. 스토어 목록에는 다른 이름이 보일 수 있습니다.
appIdstring기본값 com.<repo>.<app>
Android package name이자 iOS bundle ID입니다. 스토어 콘솔과 Firebase에 등록할 때도 똑같이 씁니다.
versionstring기본값 0.0.1
사용자에게 보이는 버전입니다. Android
versionName과 iOS CFBundleShortVersionString에 들어갑니다.buildNumnumber기본값 1
스토어 빌드 번호입니다. Android
versionCode와 iOS CFBundleVersion에 들어가며, 스토어에 올릴 때마다 올립니다.permissionsNativePermission[]
준비할 기기 기능입니다.
camera, contacts, location, push, speech 다섯 가지뿐입니다.pluginsstring[]
더 싣는 런타임 플러그인이며,
iap 같은 내장 id나 절대 경로 폴더로 적습니다.indexPathstring기본값 /
앱의 홈 route입니다. 딥링크는 그 위에 열리고, Android 뒤로 가기는 앱을 닫기 전에 여기로 돌아옵니다.
basePathstring
다중 클라이언트 앱에서 열 클라이언트이며,
routes에 선언한 basePath입니다. basePath가 없으면 적지 않습니다.ios{ teamId?, infoPlist?, entitlements?, privacy?, files? }
iOS 전용입니다. universal link용 팀, Info.plist·entitlements 키, 개인정보 매니페스트, 번들 파일을 적습니다.
android{ googleServices?, push?, autoplay?, files?, manifest?, … }
Android 전용입니다. FCM용
googleServices, 푸시 표시, 앱 링크 fingerprint, 파일, manifest XML을 적습니다.desktop{ server?, recovery?, window?, screenCapture?, … }
데스크톱 전용입니다.
server는 앱의 서버를 싣고, 나머지는 지키는 사람이 없는 앱을 계속 돌게 합니다.targetsRecord<string, AkanNativeSettings>기본값 { default: {} }
네이티브 앱마다 항목 하나이며, 키가 곧
--target에 넘기는 이름입니다. 각각 위 필드를 받습니다.권한마다 들어가는 네이티브 설정
권한을 적으면 다음 실행 때 그 기능의 플러그인이 들어가고 네이티브 설정이 쓰입니다. 음성은 런타임에 아직 플러그인이 없어, 빌드가 그렇게 알리고 없이 빌드합니다. 그 권한을 맡은 lib는 자기 항목만 더합니다.
| 권한 | 플러그인 | Android | iOS |
|---|---|---|---|
| camera | camera | 없음. 시스템 카메라와 사진 선택기는 권한이 필요 없습니다 | 카메라·사진 보관함 사용 안내 문구 |
| contacts | contacts (읽기 전용) | READ_CONTACTS | 연락처 사용 안내 문구 |
| location | geolocation | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | 위치 사용 안내 문구 (항상 / 사용 중) |
| push | push | POST_NOTIFICATIONS와 FCM 모듈 (native.android.googleServices가 필요합니다) | 원격 알림 백그라운드 모드와 aps-environment entitlement |
| speech | 아직 없음. 없이 빌드됩니다 | lib 플러그인이 선언한 것 | lib 플러그인이 선언한 것 |
앱 하나로 네이티브 앱 여러 개 만들기
한 저장소에서 고객용, 관리자용, 파트너용 앱을 따로 낸다면
basePath로 클라이언트를 나누고 targets에 앱마다 키를 하나씩 둡니다. target은 native와 같은 필드를 받고 target의 값이 이깁니다. ios 같은 객체는 키마다 합치지만 목록은 통째로 바꾸므로, target의 permissions는 native의 목록을 대신합니다. appId를 따로 정한 target은 별개의 스토어 앱이 됩니다:apps/myapp/akan.config.ts
basePath는routes에 있어야 합니다. 클라이언트를 먼저 선언하세요. 방법은 다중 클라이언트 문서에 있습니다.- 실제 appId를 쓰세요.
example,myapp,test같은 단어가 들어간 ID는 Apple 포털에서 대개 이미 쓰이고 있어 실기기 서명이 실패합니다.akan doctor --ios가 이런 ID를 짚어 줍니다. - CSR 번들을 켜 두세요. 네이티브 앱에 이 번들이 들어가므로
web: { csr: false }와native블록은 함께 쓸 수 없습니다.


출시한 뒤에는 appId를 바꾸지 마세요. Android와 iOS는
appId가 다르면 완전히 다른 앱으로 봅니다.네이티브 플러그인
런타임은 target이 요청한 플러그인만 앱에 넣습니다. 모든 Akan 페이지가 쓰는 기본 묶음은 항상 들어가고,
permissions가 그 기능의 플러그인을 가져오며, 그 밖의 것은 native.plugins에 적습니다. 앱에 없는 플러그인을 호출하면 UNSUPPORTED로 거부됩니다.패키지
항상
권한으로
permissions
이름으로
native.plugins
모든 Akan 페이지가 쓰는 것
app
✓
앱 정보, Android 뒤로 가기, 딥링크 이벤트, 앱 종료를 다룹니다.
app-state
✓
앱이 앞·뒤로 오가는 변화를 알립니다.
device
✓
플랫폼, 기종, 기기 언어를 읽습니다.
keyboard
✓
키보드 높이를 알려 주어 화면이 따라 움직이게 합니다.
preferences
✓
기기 저장소이며, 로그인 토큰을 여기에 둡니다.
secure-storage
✓
비밀 값을 두는 키체인·키스토어입니다.
browser · opener
✓
앱 안 브라우저로 페이지를 열거나, 링크를 시스템에 넘깁니다.
auth-session
✓
OAuth 로그인이 여는 시스템 로그인 창입니다.
dialog · haptics
✓
시스템 알림창·액션 시트와 진동 피드백입니다.
기능별
camera
✓
카메라와 사진 선택입니다.
camera가 가져옵니다.geolocation
✓
현재 위치와 위치 추적입니다.
location이 가져옵니다.push
✓
iOS는 APNs, Android는 FCM입니다.
push가 가져옵니다.iap
✓
인앱 결제입니다. StoreKit 2와 Play Billing을 씁니다.
share · biometric · …
✓
런타임의 다른 플러그인은 id로, 직접 만든 플러그인 폴더는 절대 경로로 적습니다.
✓해당해당 없음
기본 묶음과 권한 밖의 플러그인은 앱이 실제로 호출하는 것만 적습니다. 예를 들어 인앱 결제에는 따로 권한이 없습니다:
apps/myapp/akan.config.ts
- package.json에는 아무것도 적지 않습니다. 플러그인은 akanjs 안에 들어 있으므로, 앱이 네이티브 패키지를 설치하거나 버전을 따로 고정하지 않습니다.
- lib가 권한을 맡을 수 있습니다.
native블록을 가진<name>.plugin.ts가 권한, 그 플러그인, 사용 안내 문구, Android 권한을 적으면 그 lib를 쓰는 모든 앱이 이를 받고, 그 권한의 기본 항목을 대신합니다. - 바꾼 뒤에는 다시 실행하세요. 권한이나
native를 바꾼 뒤에는start-ios,start-android, 빌드 명령 중 하나를 다시 실행합니다. 앱은 매번 새로 만들어집니다.
앱이 가진 플러그인
키오스크의 부팅 수신처럼 빌트인에 없는 장치 기능은 앱의
native/<id>/ 폴더에 플러그인으로 둡니다. 어디에도 적지 않습니다. 모든 target에 들어가고, 플랫폼마다 무엇이 도는지는 manifest가 정합니다. lib의 native/ 플러그인은 그 lib에 의존하는 앱에 들어갑니다.apps/myapp/native/kiosk
definePlugin은 akanjs/client/native에서, defineDesktopPlugin은 akanjs/native/desktop에서 가져옵니다. 런타임 패키지 자체는 앱의 작업 공간에 설치되지 않습니다. 플러그인 API는 webkit/ 훅이 ../native/kiosk/src에서 가져오고, 페이지는 그 훅을 부릅니다.Android 설정
Android 앱을 에뮬레이터나 폰에서 띄우는 과정입니다. 꼭 맞춰야 할 값은 하나입니다.
native.appId가 Android의 applicationId가 됩니다.준비물
- build-tools 35 이상이 설치된 Android SDK, 그리고 에뮬레이터나 USB 디버깅을 켠 폰. Android Studio가 둘 다 설치해 줍니다.
- JDK 17 이상. Android Studio에 들어 있는 것을 쓰며, 다른 JDK는
JAVA_HOME으로 고릅니다. Kotlin 컴파일러는 첫 빌드 때 받아 옵니다. com.acme.shop처럼 바뀌지 않을native.appId.
기기에서 실행하기
- SDK가 ~/Library/Android/sdk에 없다면 터미널이 그 위치를 쓰도록 설정합니다:Terminal
native.appId가 확정됐는지 확인하고(위 native 설정 참고) 개발 서버를 켭니다.--release없이 실행하면 앱이 이 서버에서 화면을 불러옵니다:Terminal- 두 번째 터미널에서 에뮬레이터나 연결한 폰으로 앱을 실행합니다:Terminal
- 앱이 target의
indexPath로 열리고, 저장하면 다시 빌드하지 않아도 반영되면 성공입니다. 폰은 USB 연결로 개발 서버에 닿습니다.
명령과 스토어 빌드
| 명령 | 기본 --env |
|---|---|
| ↳ 결과 | |
| start-android | local |
에뮬레이터나 폰에서 실행합니다. --release를 주면 개발 서버 대신 웹 빌드를 넣습니다. | |
| build-android | debug |
| 앱이 빌드되는지 확인하는, 로컬 debug 키로 서명한 APK를 만듭니다. | |
| release-android | main |
업로드 키로 서명한 Play Store용 AAB를 만듭니다. --assemble-type apk면 APK입니다. | |
앱이 빌드되는지 확인한 뒤, Play Store에 올릴 AAB를
main 백엔드로 만듭니다:Terminal
release-android는 환경 변수에서 읽은 업로드 키로 서명합니다. 이름 세 개를 두고, 키에 비밀번호가 따로 있으면 네 번째도 둡니다. 하나라도 없으면 빌드 전에 멈춥니다:Terminal
MYAPP_RELEASE_STORE_FILE은 앱 폴더 기준 경로입니다. keystore 파일은secrets/에 두고,public/에는 두지 마세요.- 비밀번호는 git에 올리지 마세요. CI에서는 같은 이름을 secret으로 넣습니다. 비밀번호는 명령줄이나 로그가 아니라 환경 변수로만 서명 도구에 전달됩니다.
- 결과물 위치.
dist/native/myapp/default/build/android에 생기며,release-android가 경로를 출력합니다.
네이티브 명령 플래그
--targetstring
native.targets의 키나 all입니다. target이 하나뿐이면 자동으로 고르며, start-*는 한 번에 하나만 실행합니다.--envlocal | debug | develop | main
앱이 연결할 백엔드 환경입니다. 기본값은 위 표처럼 명령마다 다릅니다.
--releaseboolean기본값 falsestart-*
웹 빌드를 담은 릴리스 빌드로 실행하므로 개발 서버가 필요 없습니다.
--devicestringstart-iosstart-android
시뮬레이터, 에뮬레이터, 기기의 id나 이름입니다. 페어링한 iPhone 이름을 주면 서명한 폰 빌드를 만듭니다.
-T, --teamstringstart-iosrelease-ios
Mac에 여러 팀의 프로필이 있을 때 서명에 쓸 Apple 팀 id입니다.
--debugboolean기본값 falsebuild-*
릴리스 대신 디버그 빌드를 만듭니다.
--ad-hocboolean기본값 falserelease-ios
App Store 프로필 대신 ad-hoc 프로필로 서명합니다.
--assemble-typeaab | apk기본값 aabrelease-android
aab는 Play Store 업로드용, apk는 파일을 직접 설치할 때 씁니다.-l, --allow-local-releaseboolean기본값 falserelease-*
릴리스 빌드에서
--env local을 허용합니다. 로컬 테스트용입니다.iOS 설정
bundle ID, 서명, 시뮬레이터 실행, 스토어 빌드를 준비하는 과정입니다. Xcode 프로젝트는 없습니다. 런타임이 Xcode의 도구로 앱을 컴파일하고, Xcode가 둔 서명을 읽습니다. 먼저 시뮬레이터에서 실행하고, 기기 전용 기능은 폰에서 확인합니다.
준비물
- Xcode 26 이상과 iOS 26 시뮬레이터 런타임 (Xcode › Settings › Components).
- bundle ID로 쓸, 바뀌지 않을
native.appId. - 폰 실행과 출시에 쓸 Apple 개발자 팀.
기기에서 실행하기
akan start myapp을 켜 둔 채 시뮬레이터에서 앱을 실행하거나, 페어링한 iPhone 이름을 줍니다:Terminal
--device로 기기를 고릅니다. 시뮬레이터 이름이나 UDID, 페어링한 iPhone 이름을 받습니다. 생략하면 켜져 있는 iPhone 시뮬레이터를 쓰고, 없으면 가장 최신 것을 띄웁니다.- 서명은 만들지 않고 찾습니다. 폰 실행과 출시는 맞는 인증서와 프로필을 골라 쓰고, 무엇을 썼는지 출력합니다. 여러 팀이 맞으면
--team으로 고릅니다. - 맞는 것이 없을 때. 오류가 그 bundle ID의 프로필마다 맞지 않는 이유를 보여 줍니다. 만료, 다른 팀, 푸시 같은 capability 누락, 폰이 빠진 프로필 등입니다.
서명에서 확인할 것
- Xcode(Settings › Accounts)에서 팀에 로그인하고 프로필을 내려받아, Mac에 Apple Development 인증서와 이 App ID의 프로필이 있게 합니다. 런타임은 Xcode의 프로필 폴더를 읽으며, 따로 열 프로젝트는 없습니다.
- 프로필의 App ID가
native.appId와 같아야 합니다. 와일드카드 ID는 앱이 푸시도 associated domains도 요청하지 않을 때만 씁니다. - 폰에서 실행하려면 development 프로필에 그 폰이 들어 있어야 합니다. 폰을 한 번 등록하고(Xcode에서 그 폰으로 빌드하거나 개발자 사이트에서 추가) 프로필을 다시 내려받습니다. 출시에는 Apple Distribution 인증서와 App Store(또는 ad-hoc) 프로필이 필요합니다.
- 먼저 시뮬레이터에서 실행하고, 기기 전용 기능은 폰으로 옮겨 확인합니다.
명령과 스토어 빌드
| 명령 | 기본 --env |
|---|---|
| ↳ 결과 | |
| start-ios | local |
시뮬레이터나 폰에서 실행합니다. --release를 주면 개발 서버 대신 웹 빌드를 넣습니다. | |
| build-ios | debug |
| 앱이 빌드되는지 확인하는 시뮬레이터용 앱을 만듭니다. | |
| release-ios | main |
App Store용으로 서명한 iPhone 앱과 그 .ipa를 만듭니다. | |
앱이 빌드되는지 확인한 뒤, App Store용 빌드를
main 백엔드로 만듭니다. release-ios는 기본으로 main을 씁니다:Terminal
데스크톱
같은 target은 데스크톱 앱으로도 실행되며, 브라우저 밖에서 변경을 가장 빨리 확인하는 방법입니다.
akan start-desktop은 데스크톱 앱이 자기 OS에서만 빌드되므로 지금 컴퓨터의 OS용으로 빌드하고, 폰 명령처럼 akan start에서 화면을 불러옵니다:Terminal
OS설명
macOS
Xcode command line tools (
xcode-select --install).Windows
Visual Studio 2022 Build Tools의 "Desktop development with C++".
Linux
C 컴파일러, pkg-config, WebKitGTK 4.1·GTK 3·libsoup 3 개발 패키지.
서버 싣기
native나 한 target에 desktop: { server: true }를 주면 앱의 서버가 데스크톱 앱 안에 실려, 다른 곳의 백엔드 없이 컴퓨터 한 대에서 동작합니다. database.modes에 single이 있어야 하며, akan start-desktop은 떠 있는 개발 서버가 없으면 akan start를 직접 띄웁니다:apps/myapp/akan.config.ts
- 네트워크 서버처럼 가드하세요. loopback 포트로 뜨며, 이 컴퓨터의 어떤 프로그램이든 그 포트를 부를 수 있습니다.
- 앱에 실린 것은 누구나 읽을 수 있습니다. 서버의
private/(lib의 것도),--env의env.server.<env>.ts, lib의 서버 env 기본값이 평문으로 실리므로 클라우드 키나 라이선스 파일은 두지 마세요. - 실행 중에 읽는 파일은
AKAN_APP_DIR기준입니다. 서버에는public/이 없고, 작업 폴더는 앱이 아니라 데이터 폴더입니다. - 켜고 끄려면 다시 설치해야 합니다. 설치된 앱은 서버를 더하거나 빼는 업데이트를 받지 않으며, 다시 설치해도 데이터는 옮겨지지 않습니다.
실행 파일과 파일
데스크톱 앱에는 이미지의
docker 단계가 들어가지 않습니다. 서버나 네이티브 플러그인이 실행하는 ffmpeg 같은 파일은 bin에 적습니다. 플랫폼마다 해시로 확인하는 다운로드나 로컬 파일을 적으면, 모든 데스크톱 빌드가 그것을 앱의 PATH 맨 앞에 둡니다.apps/myapp/akan.config.ts


정적 LGPL 빌드를 넣으세요. 공유 라이브러리를 따로 불러오는 빌드는 만든 컴퓨터에서만 돌고, --enable-nonfree 빌드는 재배포할 수 없습니다.
사용자가 고른 파일은 복사본이나 경로가 아니라 grant로 서버에 닿으므로, 큰 영상도 업로드하지 않습니다.
native.plugins에 file-picker를 적고, forServer: true로 고른 뒤 NativeFile로 grant를 풉니다:page → server


디스플레이, 창, 볼륨, 전역 단축키, 절전 막기, 로그인 시 실행은 서버가 아니라 네이티브 플러그인이 다룹니다. 각각 native.plugins에 적고 akanjs/client/native/<id>에서 가져옵니다.
지키는 사람이 없는 앱
키오스크나 전광판에는 새로고침을 누를 사람이 없습니다.
desktop.recovery: "reload"는 멈춘 페이지를 다시 불러오고 앱을 다시 띄우며, desktop.window는 창을 전체화면, 작업 표시줄 버튼 없이 엽니다. desktop.screenCapture: "auto"는 Windows에서 선택 창 없이 화면을 공유하는데, 모든 미디어 요청에 적용되므로 카메라나 마이크를 쓰는 앱에서는 켜지 않습니다. "reload"이면 페이지가 창 밖으로 아무것도 열지 못합니다. 인쇄·파일 대화상자, 공유 시트, Windows의 다운로드, OS에 넘기는 링크, macOS 우클릭 메뉴의 Search With Google 같은 텍스트 서비스가 모두 막힙니다. 앱이 직접 부르는 opener와 file-picker 플러그인은 그대로 동작하므로, 필요한 것은 그것으로 엽니다.apps/board/akan.config.ts
업데이트
설치된 앱은 직접 서명한 릴리스로 스스로 업데이트합니다.
akan update-keygen이 native.updates에 넣을 공개 키를 출력하고, akan publish-update가 updates.url에 올릴 릴리스를 dist/native/<app>/<target>/updates에 씁니다. 폰은 새 웹 번들을 스스로 받고, 데스크톱 릴리스는 앱 전체이고 재실행이 따르므로 언제 받을지는 앱이 정합니다:webkit/useAppUpdates.tsx
- 빌드와 게시에 같은
--env를 주세요. 앱은 자기 채널(updates.channel, 없으면 빌드할 때의--env)의 릴리스만 받는데,build-desktop의 기본값은debug,publish-update는main입니다. - 새 릴리스는 시험 실행부터 합니다. 첫 페이지가 마운트되고 실린 서버가 뜰 때까지이며, 실패하면 되돌리고, 그동안
check()와apply()는 거부합니다. - 매니페스트는 마지막에 올리세요.
app/과files/를 먼저 올리고<channel>.json과.sig를 함께 올리며, CDN에서는 이 둘을 캐시하지 않습니다. 다른 릴리스의 서명과 짝지어진 매니페스트는 모든 앱의 업데이트를 멈춥니다. updates.url은 공개됩니다. 업데이터는 인증 정보를 보내지 않고, 데스크톱 릴리스는 실린 서버까지 포함한 앱 전체입니다.- 폰 업데이트 키가 새면 폐기합니다. 키는
updates.publicKeys에서 자기보다 앞에 있는 키만 폐기하므로, 예비 키를 서명 키 뒤에 둡니다.AKAN_NATIVE_UPDATE_KEY로 예비 키 파일을 고르고 모든 채널에서 iOS와 Android를--revoke <keyId>로 게시합니다(keyId는akan update-keygen이 출력합니다). 그다음 그 keyId를updates.revokedKeys에 넣어, 예비 키로 서명하는 이후 릴리스가 모두 폐기를 이어 가게 하고, 새 바이너리에서 그 키를 뺀 뒤에도 남겨 둡니다. 옛 바이너리는 계속 폐기를 받아야 합니다. 폰 빌드는 이 목록의 키를 처음부터 믿지 않습니다. 데스크톱 앱은 첫 키만 믿으므로 폐기를 받지 않습니다. 폐기된 첫 키로 서명한 데스크톱 릴리스는 경고를 내며, 그 신뢰는 다른 첫 키로 만든 새 바이너리로만 끝납니다.


서명과 공증, 사람들이 내려받는 dmg·Windows 설치 프로그램·AppImage, CI 레시피는 데스크톱 배포 문서에 있습니다.
설정 확인
빌드 성공이 끝이 아닙니다. 실제 기기에서 플러그인이 불러와지는지, 네이티브 파일이 제자리에 있는지, 권한 창이 뜨는지, 푸시가 도착해 맞는 화면을 여는지 확인하세요.
| 증상 |
|---|
| ↳ 확인할 것 |
camera.takePhoto() is not supported on ios |
target에 그 플러그인이 들어 있지 않습니다. 권한을 적거나 native.plugins에 이름을 적고 다시 실행합니다. |
No dev server answers on … |
개발 빌드는 akan start myapp에서 화면을 불러옵니다. 먼저 켜거나 --release를 줍니다. |
| 저장하면 그 자리에서 바뀌지 않고 앱 전체가 다시 뜸 |
*.constant.ts 변경, 라우트 추가·삭제, 새 의존성 뒤에는 정상입니다. 나머지 수정은 그 자리에서 바뀝니다. |
| 권한 창이 뜨지 않거나, iOS에서 처음 쓸 때 앱이 꺼짐 |
permissions에 기능을 적고 다시 실행해, 사용 안내 문구와 네이티브 설정이 들어가게 합니다. |
| 네이티브 파일이 없음 |
ios.files의 키는 앱 번들 안 경로, android.files의 키는 res/…나 assets/…이고, 값은 앱 폴더 기준 경로입니다. |
| 알림을 누르면 엉뚱한 화면이 열림 |
데이터에 url: "/some/path"를 넣어 보내고, 누르면 그 CSR route가 열리는지 확인합니다. |
플랫폼별 푸시 점검
Android 푸시
- package name이 Firebase에 등록한 Android 앱과 같습니다.
native.android.googleServices가 그 앱의google-services.json을 가리킵니다.- 폰에서 알림 권한을 허용했습니다.
- 서버의 Firebase 인증 정보가 같은 프로젝트의 것입니다.
iOS 푸시
- 실기기에서 테스트합니다.
- 프로필이 푸시를 허용합니다.
aps-environment는 프로필을 따라 폰 실행에서는development, 출시에서는production입니다. - 서버에 이 bundle ID의 APNs 키(팀 ID, 키 ID, .p8 파일)가 있습니다. iOS 푸시는 Firebase를 거치지 않습니다.
다음 단계