Process-GPT 웹 포털을 안드로이드 · iOS 앱으로 감싸는 껍데기.
화면은 여기 없다. 앱은 웹뷰로 운영 포털을 그대로 연다.
https://process-gpt.io ← 앱이 실제로 여는 것
↑ server.url (capacitor.config.json)
process-gpt-mobile/ ← 이 저장소: 껍데기 + 네이티브
↑ 주입
process-gpt-vue3/mobile-live/shell/ ← 연결 실패 안내 화면 (index.html) · 비워 둔 appshell.js/css
전용 모바일 프론트를 따로 두면 포털을 고칠 때마다 같은 것을 두 번 만들게 된다. 그래서 화면은 포털 것을 그대로 쓰고, 앱은 앱에서만 할 수 있는 것만 맡는다.
- 푸시 알림 (앱이 꺼져 있어도 배너, 누르면 그 건으로 바로 연다)
- 켤 때 로딩 화면 (마스코트 로봇 — 시작 화면과 같은 모습으로 이어진다)
- 뒤로 가기, 마지막으로 머물던 조직 주소 기억
- 연결이 끊겼을 때의 안내 화면 (
shell/index.html) — 망이 돌아오면 보던 곳으로 되돌아간다
화면 배치와 첫 화면은 앱이 정하지 않는다. 하단 탭 · 경로 제한은 걷어 냈다 — 포털이
휴대폰 폭에서 스스로 상단 바와 사이드바를 그린다. 첫 화면(모바일은 언제나 정의 체계도)은
포털의 src/utils/homePath.ts 가 정하고, 앱은 켤 때 조직 주소의 루트만 연다. 그래서 웹에서
휴대폰으로 열었을 때와 앱이 같은 화면이 된다.
| 바꾼 곳 | 이미 깔린 앱에 반영되려면 |
|---|---|
process-gpt-vue3/src/ (포털 화면·기능) |
포털 배포만 하면 된다 |
process-gpt-vue3/mobile-live/shell/ (appshell.js/css) |
APK 를 새로 배포해야 한다 |
| 이 저장소의 네이티브 코드 | APK 를 새로 배포해야 한다 |
appshell 은 process-gpt-vue3 안에 있지만 포털 번들이 아니라 APK 에 실리는
에셋이다. 이것만 고치고 포털만 배포하면 아무 일도 일어나지 않는다.
npm install
npm run build # cap sync — shell 을 android/ios 에셋으로 복사
npm run open:android # Android Studio 에서 열기Java 는 21 이 필요하다. 시스템 Java 가 다르면 Android Studio 가 함께 설치한 것을 쓴다.
export JAVA_HOME="/c/Program Files/Android/Android Studio/jbr"cd android
./gradlew assembleDebug # app/build/outputs/apk/debug/app-debug.apk
./gradlew assembleRelease # app/build/outputs/apk/release/app-release.apk웹 빌드 단계가 없다. 포털은 런타임에 받아 오고, cap sync 는 shell 파일만 옮긴다.
android/keystore.properties 와 그것이 가리키는 .jks 가 있어야 설치 가능한
APK 가 나온다. 둘 다 저장소에 없다 — 서명 키가 새면 누구나 이 앱의 다음
판으로 인정되는 APK 를 만들 수 있기 때문이다.
# android/keystore.properties
storeFile=processgpt-release.jks
storePassword=...
keyAlias=...
keyPassword=...없으면 빌드는 성공하지만 서명되지 않은 APK 가 나오고 기기가 설치를 거부한다. 두 파일을 잃어버리면 같은 앱의 다음 판을 낼 수 없다. 이미 설치한 사람들은 업데이트를 받지 못하고 앱을 지웠다 다시 깔아야 한다. 저장소가 아닌 안전한 곳에 따로 보관할 것.
capacitor.config.local.json 이 그 용도다. 에뮬레이터 안에서 127.0.0.1 은
에뮬레이터 자신이고, 이 PC 는 10.0.2.2 로 보인다.
cp capacitor.config.local.json capacitor.config.json
npx cap sync android
cd android && ./gradlew assembleDebug포털도 에뮬레이터가 닿는 주소로 띄워야 한다.
cd ../process-gpt-vue3
VITE_SUPABASE_URL=http://10.0.2.2:54321 \
VITE_PORTAL_BASE_URL=http://localhost.10.0.2.2.nip.io:8088 \
npx vite --host 0.0.0.0 --port 8088IP 가 아니라 nip.io 이름을 쓰는 이유 — 포털은 요청 Host 의 앞부분으로 소속
조직을 가른다. 10.0.2.2 로 부르면 그것이 10 이 되어 토큰의 조직과 어긋난다.
nip.io 는 이름 안의 IP 를 그대로 해석하는 공개 DNS 라, 위 이름은 10.0.2.2 를
가리키면서 앞부분이 localhost 가 된다.
평문(http) 통신은 android/app/src/main/res/xml/network_security_config.xml 에
적힌 개발용 주소에만 열려 있다. 안드로이드 9 부터 http 가 기본으로 막히는데,
전체를 열면 운영 통신도 평문으로 나갈 수 있어 주소를 나열했다.
끝나면 capacitor.config.json 을 운영용으로 되돌리고 다시 cap sync 할 것.
서버(process-gpt-completion/fcm_service)가 user_devices 표에서 기기 토큰을
읽어 보낸다. 앱은 켤 때 PushRegistrar 가 FCM 토큰을 받아 그 표에 자기 줄을 쓴다.
- 안드로이드는
android/app/google-services.json이 있어야 한다 (들어 있다). iOS 는GoogleService-Info.plist가 필요하고 아직 없다. POST_NOTIFICATIONS는 매니페스트에 적는 것만으로는 부족하다. 안드로이드 13 부터는 사용자에게 직접 허락을 받아야 하고, 받지 않으면 기기가 메시지를 받고도 안드로이드가 조용히 버린다 — 보낸 쪽은 성공으로 보이고 받는 사람은 아무것도 못 보는, 가장 찾기 어려운 경우가 된다.MainActivity가 켤 때 물어본다.- 알림을 누르면
data.url로 간다. 그 주소가process-gpt.io안일 때만 따라간다 — 아니면 알림 하나로 앱을 아무 데나 보낼 수 있다.
src/index.js · src/native.js · src/progress-stream.js 는 지금 쓰이지 않는다.
전용 프론트를 감싸던 이전 계획에서 만든 것이다. 파일 공유 · 저장 같은 기능을
나중에 붙일 때 참고할 수 있어 지워두지 않았다.
- iOS:
GoogleService-Info.plist, 인증서 - 실제 기기 확인: 알림 왕복, 화면 회전, 저사양 기기 반응 속도