APNS란: Apple Push Notification Service의 작동 방식과 아키텍처

저자: IT Sectr 게시일: 2026-03-20 읽는 시간: 8 분

APNS(Apple Push Notification Service)는 Apple 생태계 기기(iPhone, iPad, Mac, Apple Watch, Apple TV)에 푸시 알림을 전달하기 위한 Apple의 인프라 서비스입니다. 이 서비스는 기기와 Apple 서버 간의 영구 TLS 연결을 통해 안정적인 메시지 전달을 보장합니다. Apple Developer Documentation에 따르면, APNS는 애플리케이션 서버와의 양방향 통신에 HTTP/2 프로토콜을 사용합니다.

핵심 사항

  • APNS — 모든 Apple 기기에 푸시 알림을 전달하는 Apple의 중앙 집중식 서비스
  • 프로토콜 — TLS를 사용한 HTTP/2, 앱 서버와 Apple 서버 간 양방향 통신
  • 인증 — 두 가지 방법: 토큰 기반(p8 키) 및 인증서 기반(.p12 인증서)
  • 기기 — 각 기기는 전송 시 식별을 위한 고유한 푸시 토큰을 받음
  • 우선순위 — 메시지 유형에 따라 즉시 전송(10) 또는 에너지 효율(5)

APNS란?

Apple Push Notification Service(APNS)는 애플리케이션 서버에서 사용자 기기로 푸시 알림을 라우팅하는 Apple의 독점 서비스입니다. FCM과 달리 APNS는 Android나 다른 플랫폼을 지원하지 않으며 Apple 생태계에 완전히 종속됩니다.

이 서비스는 각 Apple 기기가 시작 시 APNS 서버와 설정하는 영구 TLS 연결을 통해 작동합니다. 이 연결은 백그라운드에서 유지되며 최소 지연 시간으로 알림을 전달하는 데 사용됩니다.

APNS는 암호화, 인증, 우선순위 지정, 기기 사용 불가 시 재전송 등 모든 전송 인프라를 처리합니다. 개발자는 올바르게 형식화된 페이로드와 유효한 푸시 토큰만 제공하면 됩니다.

APNS의 발전

원래 APNS는 포트 2195~2196에서 바이너리 프로토콜을 통해 작동했습니다. 2015년부터 Apple은 서비스를 최신 HTTP/2 프로토콜로 전환했으며, 이 프로토콜은 다중화, 헤더 압축 및 서버 푸시 알림을 지원합니다. HTTP/2는 2020년 6월부터 필수가 되었습니다.

Apple Push Notification Service의 작동 방식

APNS를 통한 푸시 알림 전달 프로세스는 기기 등록, 푸시 토큰 획득, 서버 요청 전송, APNS 라우팅, 기기 전달의 5단계로 구성됩니다.

  • 등록 — 시작 시 앱이 registerForRemoteNotifications를 호출하고 시스템이 APNS에 연결
  • 토큰 — APNS가 기기에 푸시 토큰 반환 — 기기에서 앱을 식별하는 고유 문자열
  • 전송 — 애플리케이션 서버가 토큰과 페이로드와 함께 https://api.push.apple.com에 POST 요청 전송
  • 라우팅 — APNS가 토큰으로 기기를 찾고 TLS 연결을 통해 메시지 전달
  • 처리 — iOS/macOS가 상태에 따라 알림을 표시하거나 앱에 전달

기기를 사용할 수 없는 경우(전원 꺼짐 또는 네트워크 없음), APNS는 각 앱에 대한 최신 메시지를 저장하고 연결이 복원될 때 전달합니다. 최대 저장 기간은 4주이며, 이후 메시지는 삭제됩니다.

APNS 인증: 토큰과 인증서

Apple은 푸시 알림을 보낼 때 애플리케이션 서버를 인증하는 두 가지 방법을 지원합니다. 각 방법은 유효 기간, 관리 및 사용 편의성 측면에서 고유한 특성이 있습니다.

매개변수토큰 기반(p8)인증서 기반(.p12)
유효 기간무기한(키 만료 없음)인증서 유효 기간으로 제한(보통 1년)
교체키가 손상되지 않는 한 필요 없음매년 교체 필수
멀티 앱계정의 모든 앱에 하나의 키각 앱에 대해 별도의 인증서
환경Sandbox 및 Production에 하나의 키Sandbox 및 Production에 다른 인증서

토큰 기반 인증은 2019년부터 Apple이 권장하는 방법입니다. Apple Developer Console에서 하나의 p8 키를 생성하고 서버에 업로드하여 각 APNS 요청에 서명합니다. 키는 만료되지 않으며 계정의 모든 앱에서 작동합니다.

어떤 인증 방법을 선택할까

새 프로젝트의 경우 토큰 기반 인증이 확실히 선호됩니다: 계정 전체에 하나의 p8 키, 무기한, 환경에 구애받지 않음. 인증서 기반(.p12)은 레거시 프로젝트에서 여전히 사용되지만 매년 교체와 Sandbox 및 Production용 별도 인증서가 필요합니다. CI/CD를 계획할 때 인증서 만료를 고려하세요.

APNS 푸시 알림 유형

APNS는 기기에서의 동작과 요청 속성 요구 사항이 다른 세 가지 유형의 푸시 알림을 지원합니다. 유형 선택은 UX 시나리오와 메시지의 긴급성에 따라 달라집니다.

  • Alert — 제목, 텍스트 및 선택적 작업 버튼이 있는 표준 알림
  • Background — 사용자에게 표시하지 않고 데이터를 무음 전달(사일런트 푸시), application:didReceiveRemoteNotification에서 처리
  • VOIP — VoIP 앱(PushKit)용 특수 유형, 앱이 닫혀 있어도 즉시 전달

Background 알림의 경우 content-available: 1 키를 지정하고 우선순위를 5(에너지 효율 전달)로 설정해야 합니다. 앱이 적시에 처리하지 않으면 시스템이 백그라운드 알림 수를 제한할 수 있습니다.

전달 우선순위 설정

APNS는 두 가지 우선순위 값을 지원합니다: 10(즉시 전달) 및 5(에너지 효율). Alert 알림에는 10을 사용합니다 — 사용자가 즉시 받아야 합니다. 백그라운드 알림에는 5를 사용합니다 — 시스템이 배터리 절약을 위해 전달을 지연시킬 수 있습니다. 백그라운드에 잘못된 우선순위를 설정하면 APNS가 거부할 수 있습니다.

APNS 페이로드 형식

APNS는 일반 알림의 경우 최대 4KB, VOIP의 경우 5KB 크기의 JSON 형식 페이로드를 수락합니다. 페이로드에는 표시 설정이 포함된 필수 aps 딕셔너리와 선택적 사용자 정의 필드가 포함됩니다.

json
{
    "aps": {
        "alert": {
            "title": "새 메시지",
            "body": "읽지 않은 채팅이 3개 있습니다"
        },
        "badge": 3,
        "sound": "default",
        "category": "message_category",
        "thread-id": "chat_room_42"
    },
    "customData": {
        "chatId": "42"
    }
}

thread-id 키는 iOS 알림 센터에서 알림을 그룹화합니다. category 키는 작업 버튼을 표시하기 위해 알림을 UNNotificationCategory에 연결합니다. 이러한 키가 없으면 모든 알림이 개별적으로 표시됩니다.

APNS 페이로드의 사용자 정의 필드

필수 aps 딕셔너리 외에도 APNS 페이로드는 최상위 수준에 사용자 정의 필드를 포함할 수 있습니다. 이러한 필드는 알림 처리 시 userInfo 딕셔너리를 통해 앱에서 액세스할 수 있습니다. 사용자 정의 데이터는 엔터티 식별자, 화면 또는 링크를 전달하는 데 편리합니다. 최대 페이로드 크기는 4KB이므로 푸시를 통해 많은 양의 데이터를 전송하지 마세요. 알림을 연 후 API를 통해 로드하세요.

HTTP/2 API를 통한 전송 예제

서버에서 푸시 알림을 보내려면 올바른 인증 헤더와 함께 APNS 엔드포인트에 POST 요청을 실행해야 합니다. 다음은 토큰 기반 인증을 사용하는 Node.js 예제입니다.

js
const http2 = require("http2")
const fs = require("fs")
const jwt = require("jsonwebtoken")

const token = jwt.sign(
    { iss: "TEAM_ID", iat: Math.floor(Date.now() / 1000) },
    fs.readFileSync("AuthKey.p8"),
    { algorithm: "ES256", keyid: "KEY_ID" }
)

const payload = JSON.stringify({
    aps: { alert: { title: "안녕하세요!", body: "테스트 푸시" } }
})

const client = http2.connect(
    "https://api.push.apple.com"
)

const req = client.request({
    ":method": "POST",
    ":path": "/3/device/DEVICE_PUSH_TOKEN",
    "authorization": "bearer " + token,
    "apns-push-type": "alert",
    "apns-topic": "com.example.app",
    "apns-priority": "10"
})
req.end(payload)

req.on("response", (headers) => {
    if (headers[":status"] === 200) {
        console.log("푸시가 성공적으로 전송되었습니다")
    }
})

전송 후 APNS는 성공적인 전달 시 HTTP 상태 200을 반환하거나 응답 본문에 설명과 함께 오류 코드를 반환합니다. token-unregistered(410) 오류를 처리하는 것이 중요합니다 — 앱이 기기에서 삭제되었으므로 해당 토큰은 서버에서 제거해야 합니다.

APNS 오류 및 처리

APNS는 각 전송 요청에 대해 HTTP 상태 코드를 반환합니다. 성공적인 전달은 상태 200을 반환합니다. 오류에는 다른 처리 전략이 필요합니다. BadDeviceToken(400) 또는 Unregistered(410) — 기기 토큰이 오래되어 서버에서 제거해야 합니다. PayloadTooLarge(413) — 4KB 제한을 초과했으므로 페이로드를 줄이세요.

TooManyRequests(429) — 요청 제한을 초과했습니다. APNS는 초당 전송 횟수에 할당량을 설정합니다. 429를 수신하면 지수 백오프(exponential backoff)를 구현하고 재시도하세요. HTTP/2 연결당 초당 100회 요청을 초과하지 않는 것이 좋습니다.

APNS 측 오류 — 500 및 503(내부 서버 오류 / 서비스를 사용할 수 없음). 이는 Apple 인프라의 일시적인 장애입니다. 이러한 경우 1~5초 지연으로 재시도하고 3회를 초과하지 마세요. 완전히 작동하는 서버에서 지속적인 5xx 오류는 드물며 일반적으로 TLS 연결 문제와 관련됩니다.

프로덕션 환경에서는 토큰, 오류 코드 및 시간을 포함한 모든 APNS 오류 로깅을 구현해야 합니다. 이를 통해 인증서, 할당량 또는 특정 기기 토큰 관련 문제를 신속하게 식별할 수 있습니다. 인증서 기반 인증을 사용하는 경우 정기적으로 인증서 만료 날짜를 확인하세요.

자주 묻는 질문

APNS는 어떤 포트를 사용하나요?

APNS는 HTTP/2 API를 위해 TCP 443(HTTPS)을 통해 작동합니다. 이전에는 바이너리 프로토콜에 포트 2195와 2196이 사용되었습니다. 2020년 6월부터 Apple은 포트 443에서 HTTP/2만 사용하도록 요구합니다. 서버가 api.push.apple.com에 액세스할 수 있는지 확인하세요.

APNS의 Sandbox 및 Production 환경이란?

Sandbox는 푸시 알림을 디버깅하기 위한 APNS 테스트 환경입니다. Production은 실제 사용자를 위한 라이브 환경입니다. 토큰 기반 인증에서는 하나의 키가 두 환경 모두에서 작동합니다 — 엔드포인트가 다릅니다: api.sandbox.push.apple.com 또는 api.push.apple.com.

기기 푸시 토큰은 얼마나 자주 변경되나요?

푸시 토큰은 다음 경우에 변경될 수 있습니다: 백업에서 앱 복원, 앱 재설치, OS 업데이트, 네트워크 설정 재설정. App Store를 통한 일반 앱 업데이트 중에는 토큰이 변경되지 않습니다. 서버는 BadDeviceToken(400) 오류를 토큰 제거 신호로 처리해야 합니다.

APNS의 최대 페이로드 크기는?

일반 alert/background 알림의 경우 4KB(4096바이트). PushKit을 통한 VOIP 알림의 경우 5KB(5120바이트). 크기를 초과하면 PayloadTooLarge(413) 오류가 반환됩니다. 페이로드를 최소로 유지하고 추가 데이터는 서버를 통해 로드하는 것이 좋습니다.

기기에 인터넷이 없어도 푸시를 보낼 수 있나요?

APNS는 인터넷 연결이 없는 기기에 알림을 전달할 수 없습니다. 기기가 오프라인인 경우 APNS는 28일까지 최신 메시지(앱별, 기기별)를 저장합니다. 연결이 복원되면 메시지가 즉시 전달됩니다. 이전 메시지는 보존되지 않습니다.

요약

  • APNS — iOS, macOS, watchOS 및 tvOS에 푸시를 전달하는 Apple의 인프라 서비스
  • 푸시 토큰 — registerForRemoteNotifications를 통해 얻는 고유 기기 식별자
  • HTTP/2 — 다중화를 지원하는 최신 APNS 프로토콜, 2020년부터 필수
  • 인증 — 유효 기간과 유연성 면에서 토큰 기반(p8)이 인증서 기반(.p12)보다 선호
  • Alert, Background, VOIP — 다양한 전달 규칙을 가진 세 가지 푸시 알림 유형
  • 페이로드 — 필수 aps 딕셔너리와 선택적 사용자 정의 필드가 있는 최대 4KB JSON
  • 저장 — APNS는 오프라인 기기를 위해 28일까지 최신 메시지 하나를 저장

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기