2026. 10. 27. 13:21

0. 사전 준비 (처음 한 번만)

  a. Apple Developer Program 가입

  b. Xcode -> Settings -> Accounts 에 해당 Apple ID로 로그인

  c. Apple Store Connect -> 나의 앱 -> + 에서 앱 만들고
      번들 ID 입력

 

1. 코드 의존성 정리

cd ~/front

npm i

cd ios && pod install

 

2. 빌드 번호 올리기

  TestFlight는 같은 버전 안에서 빌드 번호가 겹치면 업로드 거부

 

ios/apple.xcworkspace를 열기 

 - .xcodeproj 말고 반드시 .xcworkspace 열기

왼쪽에서 apple 프로젝트 -> TARGETS: apple -> General -> Identity

  Build : 8 -> 9 처럼 이전 업로드보다 큰 숫자로 변경

  Version: 새 버전으로 낼 때만 바꿈 (ex: 1.0 -> 1.0.1)

 

3. 서명 확인

 

Signing & Capabilities 탭에서 아래 확인

Automatically manage signing 이 체크

Team 입력 확인

에러(빨간 글씨)가 있는지 확인

Push 알림처럼 entitlements에 있는 기능도

여기에 정상적으로 표시

 

4. Archive

Xcode 상단의 실행 대상(디바이스 선택 메뉴)을
Any iOS Device (arm64)로 변경
시뮬레이터가 선택되어 있으면 Archive 메뉴가 비활성화

Product -> Scheme -> Edit Scheme -> Archive에서 
Build Configuration이 Release인지 확인

Product -> Archive를 실행
완료되면 Build Successful 이 뜨고 Archives 창이 뜸


5. 업로드

Archive가 끝나면 Organizer 창이 자동으로 뜸
안 뜨면 Window -> Organizer로 열기

방금 만든 아카이브를 선택하고 Distribute App 버튼 누름

App Store Connect 를 선택한 뒤 Distribute 누름

Uploading 창이 뜸
Upload Successful이 뜨면 업로드가 끝남

 

6. App Store Connect에서 처리

App Store Connect에서 앱 -> Test Flight 탭
빌드가 처리 중으로 보이다가 5~30분 뒤 완료

수출 규정 준수(암호화) 질문이 나오면 "표준 암호화만 사용/면제"

 

7. 테스터 추가

내부 테스트: App Store Connect 사용자로 등록된 팀원이 대상

TestFlight -> 내부 테스트 -> 그룹 생성
-> 테스터 추가 -> 빌드 선택

외부 테스트: 이메일이나 공개 링크로 최대 10,000명까지 초대

8. 테스터 설치

테스터는 아이폰에 TestFlight 앱을 설치한 뒤,

초대 메일 링크를 통해 앱을 설치

 

 

자주 막히는 지점

증상해결

Archive 메뉴가 회색 실행 대상을 Any iOS Device로 변경
"Redundant Binary Upload"/빌드 번호 중복 Build 번호 올리고 다시 Archive
Pod 관련 빌드 에러 cd ios && pod deintegrate && pod install, Xcode에서 Product → Clean Build Folder (⇧⌘K)
서명 에러 (No profiles) Xcode Accounts에 Apple ID 로그인 확인, Signing 탭에서 Team 재선택
main.jsbundle 없음 / 흰 화면 Release 구성으로 Archive했는지 확인
업로드 후 TestFlight에 빌드가 안 보임 처리 대기(최대 1시간), 이메일로 거부 사유 확인

 

2026. 10. 6. 09:03

1. Firebase 프로젝트 (https://console.firebase.google.com)
 - 새 프로젝트 만들기
 - 프로젝트 이름 입력 -> helloapple -> 약관 동의 -> 계속
 - Gemini in Firebase: 꺼도 됩니다
 - Google Analytics: 꺼도 됩니다
 - 프로젝트 만들기

2. iOS 앱 등록
 - 프로젝트 개요에서 iOS+ 아이콘 클릭
 - Apple 번들 ID: com.helloapple.helloapple
 - 앱 등록 -> GoogleService-Info.plist 다운로드
 - 이후 "SDK 추가", "초기화 코드 추가" 진행 -> 콘솔로 이동

plist를 프로젝트에 넣는 방법
 - Xcode에서 넣으려면 왼쪽 helloapple 폴더를 우클릭
 -> Add Files to "hello apple" ... -> 파일 선택
-> Targets 에서 helloapple 체크 -> Add 순서로 진행
또는 front/ios/helloapple/ 폴더에 파일 넣고 Xcode 프로젝트 등록

3.  Android 앱 등록

- 프로젝트 개요 -> 앱 추가 -> Android 아이콘
- Android 패키지 이름: com.helloapple
- 앱 닉네임과 SHA-1: 비워도 됨
- 앱 등록 -> google-services.json 다운로드
- 파일을 front/android/app/ 에 넣음
- Gradle과 SDK 반영

4. iOS 푸시 키 (APNs)

- Apple Developer (https://developers.apple.com/account)
https://developers.apple.com/account/resources/authkeys/add
-> Keys Name 입력 (ex: helloapple push)
 - Keys Name 입력하는 위치: 푸터의 계정 -> 인증서, ID 및 프로파일(영문)
 -> Keys -> Create a key
-> Apple Push Notifications service(APNs) 체크
-> Configure - Environment: Sandbox & Production
-> Key type: Team Scoped
-> Continue -> Register -> Download
키를 만들고 .p8 파일을 받음

- Firebase -> 프로젝트 설정 -> 클라우드 메시징
Apple App 구성 -> APNs 인증 키에 업로드
(Key ID, Team ID: GAB839QPF3)

5. 서버용 키
- 프로젝트 설정 -> 서비스 계정 탭 -> 새 비공개키 생성 
-> JSON 다운로드
- 서버에 올리고 .env 에 FIREBASE_CREDENTIALS=
/home/ubuntu/back/firebase-service-account.json
- pip install google-auth
python manage.py migrate
# Firebase -> 서비스 계정 -> "새 비공개 키 생성"으로
받은 JSON 을 서버에 두고 .env 에 추가
sudo systemctl restart apple

GoogleService-Info.plist, google-services.json 비밀 아님 (Firebase 공식 안내) 해도 됨
APNs .p8 키 비밀 ❌ 절대 금지
서비스 계정 JSON 비밀 (푸시 발송 권한) ❌ 절대 금지 (.gitignore에 추가해 둠)
2026. 10. 6. 08:41

@notifee/react-native

@react-native-firebase/app

@react-native-firebase/messaging

react-native-callkeep

react-native-voip-push-notification

Android 전용

@react-native-firebase/app
 - React Native에서 firebase를 쓰기 위한 기본 모듈
 - Firebase 프로젝트와 앱을 연결 

 - 아래 messaging이 동작하려면 반드시 필요


@react-native-firebase/messaging
 - FCM 푸시를 받는 모듈
(Firebase Cloud Messaging)
- getToken()/onTokenRefresh()

기기 FCM 토큰을 받아 /account/push-token에 등록
- setBackgroundMessageHandler()

앱이 꺼져 있어도 푸시가 오면 JS 코드 실행
착신 알림이 오는 시작점
- onMessage()

앱이 화면에 떠 있을 때 온 푸시를 처리

 

서버는 priority HIGH인 data 메시지로 보냄
그래야 절전 모드(doze)에서도 바로 도착

@notifee/react-native
- 로컬 알림을 세부적으로 꾸밀 수 있는 라이브러리
FCM은 메시지를 전달
화면을 보이는 건 이 쪽이 담당
CALL + fullScreenAction:
잠금 상태에서 전체화면 수신 화면으로 띄움
[거절]/[받기] 액션 버튼, 반복 벨소리(loopSound),
40초 뒤 자동 제거(timeoutAfter)
onBackgroundEvent/getInitialNotification
앱이 꺼진 상태에서 받거나 거절을 눌렀을 때 그 동작을 처리
Android 13 이상에서는 알림 권한을 요청
requestPermission

iOS 전용

react-native-voip-push-notification
- Apple CallKit(iOS 기본 전화 수신 UI)을 다루는 라이브러리


react-native-callkeep

 

 

2026. 9. 25. 23:50

@notifee/react-native

@react-native-firebase/app

@react-native-firebase/messaging

react-native-callkeep

react-native-voip-push-notification

Android 전용

@react-native-firebase/app
 - React Native에서 firebase를 쓰기 위한 기본 모듈
 - Firebase 프로젝트와 앱을 연결 

 - 아래 messaging이 동작하려면 반드시 필요


@react-native-firebase/messaging
 - FCM 푸시를 받는 모듈
(Firebase Cloud Messaging)
- getToken()/onTokenRefresh()

기기 FCM 토큰을 받아 /account/push-token에 등록
- setBackgroundMessageHandler()

앱이 꺼져 있어도 푸시가 오면 JS 코드 실행
착신 알림이 오는 시작점
- onMessage()

앱이 화면에 떠 있을 때 온 푸시를 처리

 

서버는 priority HIGH인 data 메시지로 보냄
그래야 절전 모드(doze)에서도 바로 도착

@notifee/react-native
- 로컬 알림을 세부적으로 꾸밀 수 있는 라이브러리
FCM은 메시지를 전달
화면을 보이는 건 이 쪽이 담당
CALL + fullScreenAction:
잠금 상태에서 전체화면 수신 화면으로 띄움
[거절]/[받기] 액션 버튼, 반복 벨소리(loopSound),
40초 뒤 자동 제거(timeoutAfter)
onBackgroundEvent/getInitialNotification
앱이 꺼진 상태에서 받거나 거절을 눌렀을 때 그 동작을 처리
Android 13 이상에서는 알림 권한을 요청
requestPermission

iOS 전용

react-native-voip-push-notification
- Apple CallKit(iOS 기본 전화 수신 UI)을 다루는 라이브러리


react-native-callkeep

 

 

2026. 8. 27. 15:11

OCI의 Ubuntu 이미지는 22번 포트만 열린 iptables 규칙을 탑재

 

VCN 보안 목록에서 80을 열어도 인스턴스 안쪽 방화벽에서

 

한 번 더 막히기 때문에 브라우저에서 안 보임

 

# REJECT 규칙(5번) 앞에 80/443 허용 삽입

sudo iptables -I INPUT 5 -p tcp --dport 80 -m state --state NEW -j ACCEPT