콘텐츠로 이동

Apple Push Notification Service 구현하기

iOS에서 리모트 푸시 알림을 수신하려면 아래 절차를 순서대로 완료하세요.

시작하기 전에 공통 사전 준비를 마치세요.

전체 흐름

각 단계에서 무엇을 조작하고 무엇을 호출하는지는 아래와 같습니다.


순서 구분 하는 일
1 외부 콘솔 Apple Developer에서 Push Notifications capability와 APNs 키 준비
2 Hive 콘솔 APNs 발송 정보 등록
3 Hive Axyl SDK, OS 플러그인 푸시 모듈과 APNs 플러그인 설치 및 등록
4 앱 코드 APNs 델리게이트 콜백 연결
5 레시피 코드 레시피 폴더 복사
6 앱 코드 PushPreparation 생성
7 레시피 코드 알림 권한 요청, APNs 환경 확인, APNs 토큰 발급, Hive Axyl 서버 등록
8 앱 코드, 레시피 코드 토큰 갱신 이벤트 대응
9 OS 플러그인, 앱 코드 수신 알림과 콜드 스타트 처리
10 Hive 콘솔, Hive Axyl 서버 API 리모트 푸시 발송


APNs 환경을 임의로 정하지 마세요

개발 서명 빌드는 APNs sandbox 토큰을, 배포 빌드는 APNs production 토큰을 사용합니다. 레시피는 빌드의 aps-environment 값을 읽어 등록 값을 정합니다. 앱 코드에서 임의로 Apns 또는 ApnsSandbox를 고정하지 마세요.

1. Apple Developer 설정

Apple Developer에서 Push Notifications capability를 활성화하고 APNs 발송에 사용할 키 정보를 준비하세요.

Capability를 변경한 뒤에는 Provisioning Profile을 갱신해야 합니다. Xcode 자동 서명을 사용하지 않는다면 갱신한 프로파일을 직접 내려받아 빌드에 적용하세요.

2. Hive 콘솔 설정

  • Hive 콘솔  Hive 콘솔에서 설정합니다.

1단계에서 준비한 APNs 발송 정보를 Hive 콘솔에 등록하세요.


설정 항목 필수 여부 확인할 곳
APNs 인증서 파일 필수 App Store 푸시 알림 연동
Key ID 필수 App Store 푸시 알림 연동
Team ID 필수 App Store 푸시 알림 연동


앱에서 토큰 등록에 성공해도 Hive 콘솔의 APNs 발송 정보가 잘못되면 실제 푸시 발송이 실패할 수 있습니다.

3. SDK 모듈과 플러그인 준비

푸시 모듈과 APNs 플러그인을 설치한 뒤 SDK를 초기화할 때 등록하세요.


패키지 역할
com.hive.axyl.core SDK 초기화와 공통 기능
com.hive.axyl.auth 토큰 등록에 필요한 로그인 세션
com.hive.axyl.push Hive Axyl 서버의 디바이스 토큰 등록
com.com2usplatform.hiveaxyl.push.addon.apns APNs 토큰 발급, APNs 환경 확인, 토큰 갱신 이벤트, 수신 알림 이벤트
com.unity.mobile.notifications iOS 알림 권한 요청


아래는 SDK를 초기화할 때 푸시 모듈과 APNs 플러그인을 등록하는 예제 코드입니다.

using Hive.Axyl.Core;
using Hive.Axyl.Core.Unity;
using Hive.Axyl.Auth;
using Hive.Axyl.Push;
using Hive.Axyl.Push.Addon.APNS;

var config = CoreConfig.CreateBuilder("{appId}")
    .SetZone(Zone.Sandbox)
    .Build();

HiveBootstrap.Initialize(config, builder =>
{
    builder.AddAuth();
    builder.AddPush();
    builder.AddAPNS();
});

AddPush()를 등록하지 않으면 레시피가 FailedPrecondition 오류로 실패합니다. AddAPNS()를 등록하지 않으면 APNs 토큰 소스가 토큰을 발급받을 수 없습니다.

4. APNs 델리게이트 코드 준비

APNs 플러그인은 앱의 UIApplicationDelegate 또는 UNUserNotificationCenterDelegate를 대신 설치하지 않습니다. 앱 델리게이트가 OS 콜백을 플러그인의 Notify* 메서드로 전달해야 합니다.


OS 델리게이트 콜백 호출할 플러그인 메서드
application(_:didRegisterForRemoteNotificationsWithDeviceToken:) NotifyDidRegisterForRemoteNotificationsAsync(deviceToken)
application(_:didFailToRegisterForRemoteNotificationsWithError:) NotifyDidFailToRegisterAsync(errorDescription)
userNotificationCenter(_:willPresent:withCompletionHandler:) NotifyWillPresentNotificationAsync(notification)
userNotificationCenter(_:didReceive:withCompletionHandler:) NotifyDidReceiveResponseAsync(notification, actionIdentifier)
콜드 스타트 실행 옵션 또는 초기 알림 응답 NotifyColdStartNotificationAsync(userInfoJson)


델리게이트 콜백을 연결하지 않으면 APNs 토큰 발급 호출이 완료되지 않고, 수신 이벤트도 앱에 전달되지 않습니다.

5. 레시피 코드 설치

  • 레시피 코드  레시피 코드를 프로젝트에 복사합니다.

레시피는 패키지가 아니라 프로젝트에 복사해서 사용하는 소스 코드입니다. 아래 항목을 Unity 프로젝트의 Assets/Recipes/ 아래로 복사하세요.


복사 대상 역할
Recipes.asmdef 공통 어셈블리 정의
Helper/ 여러 레시피가 함께 사용하는 공통 코드
Push/ PushRecipe, PushPreparation, 결과 타입
Push.Apns/ Apple APNs 권한 요청, APNs 환경 확인, 토큰 발급 코드


앱 코드에서 레시피를 호출하려면 앱 쪽 어셈블리 정의의 references에 Hive.Axyl.Samples.Recipes, Hive.Axyl.Samples.Recipes.Push, Hive.Axyl.Samples.Recipes.Push.Apns를 추가하세요.

APNs 플러그인이 없으면 빌드에서 제외됩니다

Push.Apns/의 어셈블리 정의는 APNs 플러그인 패키지가 설치되어 있을 때만 컴파일됩니다. 플러그인을 설치하지 않아도 공통 푸시 레시피는 남고, APNs 토큰 소스 어셈블리만 빌드에서 제외됩니다.

6. PushPreparation 생성

  • 앱 코드  앱에서 직접 구현합니다.

PushPreparation은 이 디바이스를 어떤 조건과 수신 동의 값으로 등록할지를 담는 레시피 타입입니다.

using Hive.Axyl.Samples.Recipes;

var preparation = new PushPreparation(
    language: "ko",
    country: "KR",
    timezoneId: "Asia/Seoul",
    agreedToInfo: true,
    agreedToAdvertising: false,
    agreedToNightAdvertising: false,
    serverId: "KR-01",
    appVersion: Application.version);

language는 Hive Axyl 서버가 지원하는 언어 코드로 전달하세요. country는 ISO 3166-1 alpha-2 형식으로 전달하고, timezoneId는 IANA 타임존 이름으로 전달하세요.

agreedToNightAdvertising은 agreedToAdvertising이 true일 때만 true로 설정할 수 있습니다. 잘못된 조합이면 레시피는 서버 호출 전에 실패로 반환합니다.

7. APNs 토큰 등록

  • 레시피 코드  레시피 코드를 앱에서 호출합니다.

로그인을 완료한 뒤 PrepareAsync()를 호출하세요. 이 메서드 하나가 iOS 알림 권한을 확인 또는 요청하고, 빌드의 APNs 환경을 확인하고, APNs 토큰을 발급받고, Hive Axyl 서버에 토큰과 수신 동의 값을 등록합니다.

using System;
using System.Threading;
using Hive.Axyl.Samples.Recipes;

CancellationToken cancellationToken = default;
Action restoreNotificationDelegate = () =>
{
    // 앱이 사용하는 APNs 델리게이트 포워더를 다시 설치합니다.
};
using IPushTokenSource source = new ApnsPushTokenSource();
var recipe = new PushRecipe(source);

PreparePushOutcome prepared;
try
{
    prepared = await recipe.PrepareAsync(preparation, cancellationToken);
}
finally
{
    restoreNotificationDelegate();
}

switch (prepared.Status)
{
    case PreparePushStatus.Success:
        // prepared.Provider가 Apns 또는 ApnsSandbox인지 확인할 수 있습니다.
        break;

    case PreparePushStatus.PermissionDenied:
        // 알림 권한이 허용되지 않아 토큰을 등록하지 않았습니다.
        break;

    case PreparePushStatus.BusinessOutcome:
        Debug.LogWarning($"{prepared.FailedStep}: {prepared.BusinessOutcome}");
        break;

    case PreparePushStatus.Failure:
        Debug.LogError($"{prepared.FailedStep}: {prepared.Error?.Message}");
        break;
}

레시피가 내부에서 수행하는 작업은 아래와 같습니다.


구분 호출 확인할 곳
OS 플러그인 iOS 알림 권한 확인 또는 요청 APNs 연동 환경 구성
OS 플러그인 GetProviderEnvironmentAsync()로 APNs 환경 확인 APNs 토큰 발급 및 등록
OS 플러그인 GetTokenAsync()로 APNs 토큰 발급 APNs 토큰 발급 및 등록
Hive Axyl SDK UpsertTokenAsync()로 토큰과 수신 동의 등록 디바이스 토큰 등록


Unity Mobile Notifications가 iOS 알림 권한을 요청하면 notification center delegate가 Unity 쪽으로 바뀔 수 있습니다. 앱이 APNs 델리게이트 포워더를 사용한다면 레시피 호출이 성공, 실패, 취소 중 무엇으로 끝나더라도 finally 블록에서 포워더를 다시 설치하세요. recipes/Notifications/PushPreparationExample.cs는 이 복구 콜백을 받는 예시를 제공합니다.

8. 토큰 갱신 대응

  • 앱 코드  앱에서 직접 구현합니다.

    레시피 코드  레시피 코드를 앱에서 호출합니다.

APNs가 새 토큰을 발급하면 앱은 새 토큰을 다시 Hive Axyl 서버에 등록해야 합니다. 레시피는 TokenRefreshed 이벤트를 직접 소유하지 않으므로, 앱의 생명주기 소유자가 이벤트를 구독하고 등록 호출을 직렬화하세요.

string latestRefreshToken = null;

source.TokenRefreshed += refreshed =>
{
    latestRefreshToken = refreshed;
};

PreparePushOutcome prepared = await recipe.PrepareAsync(preparation, cancellationToken);

if (prepared.Status == PreparePushStatus.Success
    && !string.IsNullOrEmpty(latestRefreshToken)
    && latestRefreshToken != prepared.DeviceToken)
{
    prepared = await recipe.PrepareAsync(preparation, cancellationToken);
}

한 번에 여러 등록을 동시에 실행하지 마세요. 성공한 뒤 최신 이벤트 토큰이 방금 등록한 토큰과 다를 때만 한 번 더 등록하세요.

9. 푸시 수신 처리

  • OS 플러그인  OS 플러그인을 앱에서 호출합니다.

    앱 코드  앱에서 직접 구현합니다.


    상세 절차: 푸시 수신 처리(iOS)

레시피는 토큰을 등록할 뿐, 도착한 푸시 알림을 화면에 표시하거나 알림 탭으로 앱이 열린 상황을 처리하지 않습니다. 토큰 등록 후에는 APNs 수신 처리를 구현하세요.

수신 알림의 UserInfoJson은 앱이 해석해 화면 이동, 상태 갱신, 이벤트 처리 같은 동작을 구현합니다.

10. 리모트 푸시 발송

  • Hive 콘솔  Hive 콘솔에서 리모트 푸시를 발송합니다.

    Hive Axyl 서버 API  앱 서버에서 Hive Axyl 서버 API를 호출합니다.


    상세 절차: 리모트 푸시 전송

리모트 푸시 메시지는 Hive 콘솔 또는 Hive Axyl 서버 API로 발송합니다. 앱 클라이언트는 발송 주체가 아닙니다.

캠페인 발송 대상 필터에는 토큰 등록 시 전달한 언어, 국가, 타임존, 수신 동의 값이 사용됩니다.

다음 단계

Android에서도 리모트 푸시 알림을 구현하려면 Google Firebase Cloud Messaging 구현을 참조하세요. Unity Mobile Notifications 기반 로컬 알림 예시는 Notifications 예시 활용을 참조하세요.