콘텐츠로 이동

5단계. 리모트 푸시 수신

iOS 환경에서 도착한 리모트 푸시 메시지를 앱 클라이언트에서 처리합니다.

본 문서에서는 Hive Axyl APNs 플러그인으로 실행 중 알림 이벤트를 수신하고, 사용자가 알림을 탭해 앱이 실행된 경우의 페이로드를 확인하는 과정을 안내합니다.


APNs 푸시 수신 처리 구현 방법은 아래와 같습니다.

APNs 플러그인은 수신 이벤트와 콜드 스타트 알림 조회 기능만 제공합니다. 알림 표시 방식, 데이터 해석, 화면 이동 처리는 앱 클라이언트에서 직접 수행합니다.

Note
  • iOS의 수신 이벤트는 OS가 플러그인에 직접 전달하지 않습니다. 앱의 델리게이트가 OS 콜백을 Notify* 메서드로 전달할 때 플러그인이 NotificationPresented 또는 NotificationOpened 이벤트를 발생시킵니다.
  • 콜드 스타트 페이로드의 캡처도 앱의 application(_:didFinishLaunchingWithOptions:) 델리게이트 코드가 수행하며, 캡처한 페이로드를 NotifyColdStartNotificationAsync()로 전달해야 합니다.


방법 1. 실행 중 알림 수신

앱의 델리게이트가 다음 두 콜백을 전달하면 알림 상태에 따라 NotificationPresented 또는 NotificationOpened 이벤트가 발생합니다. 이벤트는 엔진 메인 스레드로 전달됩니다.

  • NotifyWillPresentNotificationAsync(notification): 포그라운드에서 알림이 표시되기 직전(willPresent) 호출합니다. 호출 후 NotificationPresented 이벤트가 발생합니다. 포그라운드 표시 방식(배지, 사운드, 배너 등)은 앱이 자신의 델리게이트 안에서 OS completionHandler로 직접 반환합니다.
  • NotifyDidReceiveResponseAsync(notification, actionIdentifier): 사용자가 알림을 탭하거나 커스텀 액션을 선택했을 때(didReceive) 호출합니다. 호출 후 NotificationOpened 이벤트가 발생합니다. actionIdentifier는 OS의 UNNotificationResponse.actionIdentifier 값을 그대로 전달합니다.

두 메서드 모두 성공 응답에 앱이 사용할 데이터가 없으며, 반환 객체는 Success/Failure로 분기됩니다. NotifyWillPresentNotificationAsync() 응답의 PresentationOptions는 항상 빈 배열입니다. 표시 옵션은 앱이 OS completionHandler로 직접 반환합니다.


호출 예시

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

IAPNSPlugin apns = HiveCore.Resolve<IAPNSPlugin>();

apns.NotificationPresented += notification =>
{
    // 포그라운드 수신 - 인앱 배너 표시 등 앱이 결정합니다.
    string title = notification.Title;
    string body  = notification.Body;

    // 커스텀 데이터는 APNs 페이로드 원본 JSON으로 전달됩니다.
    string userInfoJson = notification.UserInfoJson;
};

apns.NotificationOpened += opened =>
{
    // 알림 탭 또는 액션 선택 - 화면 이동 등 앱이 결정합니다.
    string actionIdentifier = opened.ActionIdentifier;
    string userInfoJson = opened.Notification.UserInfoJson;
};


호출 시 고려 사항

  • NotificationPresented와 NotificationOpened 이벤트를 받으려면 APNs 플러그인 인스턴스가 유지되어야 합니다.
  • 앱 델리게이트에서 OS 알림 콜백을 플러그인의 Notify* 메서드로 전달해야 합니다.
  • 포그라운드에서 알림을 어떻게 표시할지는 앱 클라이언트가 OS completionHandler로 직접 결정합니다.


방법 2. 알림 탭 진입 처리

사용자가 알림을 탭해 앱이 실행된 경우, GetColdStartNotificationAsync()로 해당 알림의 페이로드를 조회합니다.

Method

public Task GetColdStartNotificationAsync();


콜드 스타트 알림 버퍼는 1회용입니다. 일반 실행이거나 이미 한 번 꺼낸 뒤에는 모든 필드가 기본값인 빈 알림이 반환되며, 이는 실패가 아닙니다. 앱 시작 시점에 한 번 호출해 알림 탭 진입 여부를 확인하세요.

앱이 종료된 상태에서 알림 탭으로 실행된 경우, 앱 델리게이트에서 캡처한 원본 페이로드 JSON을 NotifyColdStartNotificationAsync(userInfoJson)로 먼저 전달해야 GetColdStartNotificationAsync()에서 조회할 수 있습니다.


호출 파라미터

필드명 타입 필수 여부 설명
ct CancellationToken Optional 호출을 취소할 때 사용하는 취소 토큰입니다. 생략하면 기본값이 사용됩니다.


호출 예시

GetColdStartNotificationAsync()의 반환 객체 ApnsServiceGetColdStartNotificationResult는 성공, 실패 상태로 나뉩니다. 메서드 호출 시 예외(Exception)를 발생시키지 않으며, 모든 처리 결과가 반환 객체로 전달됩니다. 따라서 별도의 try/catch 구문을 사용하지 않고 switch 구문으로 응답 상태를 분기해 처리합니다.

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

ApnsServiceGetColdStartNotificationResult result = await apns.GetColdStartNotificationAsync();

switch (result)
{
    case ApnsServiceGetColdStartNotificationResult.Success success:
        ApnsNotification notification = success.Data.Notification;
        // 알림 탭 진입이면 페이로드가 채워져 있고, 일반 실행이면 모든 필드가 기본값입니다.
        if (!string.IsNullOrEmpty(notification.UserInfoJson))
        {
            // 페이로드를 해석해 특정 화면으로 이동하는 등 처리합니다.
        }
        break;

    // 공통 실패 처리 - 자세한 에러 모델은 [에러 처리](PLACEHOLDER_에러처리_링크) 참고
    case ApnsServiceGetColdStartNotificationResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // 안전망: 알 수 없는 신규 결과
    default:
        Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
        break;
}


호출 시 고려 사항

  • 앱 시작 시점에 한 번 호출해 알림 탭 진입 여부를 확인하세요.
  • Success가 반환되어도 알림 필드가 기본값이면 일반 실행이거나 이미 꺼낸 버퍼입니다.
  • 콜드 스타트 페이로드 캡처를 위해 앱 델리게이트에서 실행 옵션을 처리하고 NotifyColdStartNotificationAsync()를 호출해야 합니다. 자세한 내용은 델리게이트 코드 준비를 참고하세요.
  • macOS에서는 일반 .app 실행처럼 캡처 소스가 없는 빌드이거나 릴레이가 완료되기 전에 조회하면 빈 알림이 반환될 수 있습니다.


응답 데이터

성공 시 ApnsServiceGetColdStartNotificationResult.Success의 Data에 알림이 담깁니다.

필드명 타입 필수 여부 설명
Data.Notification ApnsNotification Required 사용자가 탭한 알림의 페이로드입니다. 일반 실행이거나 이미 꺼낸 버퍼면 모든 필드가 기본값인 빈 알림입니다.


응답 상태

반환 객체 ApnsServiceGetColdStartNotificationResult는 아래 케이스로 분기됩니다. switch 구문으로 처리하세요.

응답 케이스 설명 앱 클라이언트 대응
Success 조회에 성공했습니다. 알림 탭 진입이면 페이로드가 채워져 있고, 일반 실행이면 빈 알림입니다. 페이로드 유무로 분기 처리
Failure 네이티브 연동 오류. Problem(HiveError)에 상세가 담깁니다. 일반 실행으로 간주 또는 오류 기록


참고. 수신 알림 데이터 확인

알림에 함께 실어 보낸 커스텀 데이터(예: 딥링크, 이벤트 식별자)는 APNs 페이로드 원본 JSON인 ApnsNotification.UserInfoJson으로 전달됩니다. 중첩 구조가 손실 없이 전달되므로, 앱이 JSON을 파싱해 화면 이동, 상태 갱신 같은 동작을 구현합니다.

데이터는 표시되는 알림(notification)에 동봉해 전달하며, 데이터만 단독으로 담은 메시지(무음 푸시)의 발송 가능 여부는 푸시 발송(서버) 명세를 따릅니다. 관련 빌드 구성은 APNs 연동 환경 구성을 참고하세요.


참고: ApnsNotification 구조

수신 알림은 iOS 알림(UNNotification) 내용을 그대로 옮긴 구조입니다. 값이 없는 필드는 기본값(빈 문자열/0)입니다.

필드명 타입 필수 여부 설명
Title string Required 알림 제목입니다.
Subtitle string Required 알림 부제목입니다.
Body string Required 알림 본문입니다.
Badge int Required 앱 아이콘 배지 수입니다. 값이 없거나 배지를 지우는 페이로드면 0입니다.
Sound string Required 알림 사운드입니다.
CategoryIdentifier string Required 알림 카테고리 식별자입니다.
ThreadIdentifier string Required 알림 그룹(스레드) 식별자입니다.
LaunchImageName string Required 실행 이미지 이름입니다.
TargetContentIdentifier string Required 대상 콘텐츠 식별자입니다.
InterruptionLevel UNNotificationInterruptionLevel Required 알림 중요도입니다(Passive/Active/TimeSensitive/Critical). 값이 없으면 Unspecified입니다.
RelevanceScore double Required 알림 요약 정렬에 쓰이는 관련도 점수입니다(0.0~1.0).
UserInfoJson string Required APNs 페이로드 전체(aps 딕셔너리 + 커스텀 키)의 원본 JSON 문자열입니다. 중첩 구조가 손실 없이 전달됩니다.
Note

알림 이미지 표시에는 UNNotificationServiceExtension 타깃이 별도로 필요합니다. SDK는 extension 런타임을 제공하지 않으며, 앱이 추가하지 않으면 알림은 텍스트만 표시됩니다.


연관 문서

본 문서의 내용과 관련하여 참조하는 문서는 아래와 같습니다.