Unity

Unity 푸시 알람 기능 구현

sungmin08 2025. 3. 31. 16:48

모바일 앱에는 보통 푸시알람 기능이 있다. 사용자의 재접속 유도, 업데이트 알림 등 다양한 푸시알람을 제공하게 되는데 나도 이번에 프로젝트를 진행하면서 푸시알람 기능을 구현해보려고 한다.

 

먼저 다행히도 Unity에서 푸시알람 기능 관련 패키지를 지원해준다.

 

1. 먼저 아래 패키지를 Import 하자

Window -> Package Manager -> Mobile Notifications 검색

 

2. 위 패키지를 되면 Samples라는 Text가 생길텐데 저곳에 들어가서 Notification Samples 또한 Inport 해줘야 한다.

Import 하게 되면 프로젝트 창에 Sample 폴더에 위 패키지폴더가 생성된다.

 

3. Import를 모두 마쳤다면 Project Settings에 들어가서 Mobile Notifications로 들어가서 어떤 이미지를 띄울건지 이미지를 넣으면 된다.

Android

*그냥 이미지를 넣을 시 에러가 뜰 수 있는데 이럴 때는 이미지 세팅에서 read/write를 체크해주면 된다.

IOS ->Reqiest Authorization on App Launch는 체크해주자. 체크 시 앱을 실행하면 자동으로 푸시 알람 권한을 물어본다.

 

자 이제 모든 세팅은 끝났고 Script를 작성해보자. 나는 특정 날짜에 지속적으로 푸시 알람을 보내야 하기 때문에 이거에 맞춰 코드를 구현해보았다.

 

using UnityEngine;
using System;
using Unity.VisualScripting;
#if UNITY_ANDROID
using Unity.Notifications.Android;
using UnityEngine.Android;
#elif UNITY_IOS
using Unity.Notifications.iOS;
#endif

public class LocalPushManager : MonoBehaviour
{
    // 앱 시작 시 권한 요청 및 채널 등록, 그리고 예약 알림 호출
    void Start()
    {
#if UNITY_ANDROID
        // Android: 알림 채널 등록
        RegisterAndroidChannel();

        // Android 13(API 33) 이상에서는 POST_NOTIFICATIONS 권한 요청
        if (!Permission.HasUserAuthorizedPermission("android.permission.POST_NOTIFICATIONS"))
        {
            Permission.RequestUserPermission("android.permission.POST_NOTIFICATIONS");
        }
#elif UNITY_IOS
        // iOS: 알림 권한 요청 (Alert, Badge, Sound 모두 요청)
        iOSNotificationCenter.RequestAuthorization(
            iOSAuthorizationOption.Alert | iOSAuthorizationOption.Badge | iOSAuthorizationOption.Sound,
            (granted, error) =>
            {
                Debug.Log("Notification Permission (iOS): " + granted);
            });
#endif
    }

#if UNITY_ANDROID
    /// <summary>
    /// Android 알림 채널 등록 (앱 실행 시 한 번만 호출)
    /// </summary>
    void RegisterAndroidChannel()
    {
        var channel = new AndroidNotificationChannel()
        {
            Id = "my_channel_id",
            Name = "Default Channel",
            Importance = Importance.Default,
            Description = "Generic notifications"
        };
        AndroidNotificationCenter.RegisterNotificationChannel(channel);
    }
#endif

    /// <summary>
    /// 지정한 시간에 푸시 알람을 예약합니다.
    /// 예약 시간은 현재 시간보다 미래여야 하며, 앱이 백그라운드 또는 종료 상태여도 운영체제에서 알림을 전송합니다.
    /// </summary>
    /// <param name="title">알림 제목</param>
    /// <param name="message">알림 내용</param>
    /// <param name="scheduleTime">알림 전송 시간 (미래의 DateTime)</param>
    public static void SchedulePushNotification(string title, string message, DateTime scheduleTime)
    {
        // 예약 시간이 현재보다 미래인지 확인
        if (scheduleTime <= DateTime.Now)
        {
            Debug.Log("예약 시간이 현재 시간보다 이르거나 같습니다. 올바른 미래 시간을 입력하세요.");
            return;
        }

        try
        {
#if UNITY_ANDROID
            // Android: 알림 객체 생성 및 설정
            var notification = new AndroidNotification();
            notification.Title = title;
            notification.Text = message;
            notification.FireTime = scheduleTime;
            notification.LargeIcon = "icon_0";
            notification.ShowInForeground = false;
            string channelId = "my_channel_id"; // 미리 등록된 채널 ID 사용

            AndroidNotificationCenter.SendNotification(notification, channelId);
#elif UNITY_IOS
            // iOS: 예약 시간과 현재 시간 간의 간격(TimeInterval) 계산
            TimeSpan interval = scheduleTime - DateTime.Now;
            if (interval.TotalSeconds <= 0)
            {
                Debug.LogWarning("예약 간격이 0 이하입니다. 올바른 미래 시간을 입력하세요.");
                return;
            }

            var timeTrigger = new iOSNotificationTimeIntervalTrigger()
            {
                TimeInterval = interval,
                Repeats = false
            };

            var notification = new iOSNotification()
            {
                Identifier = Guid.NewGuid().ToString(), // 중복되지 않는 고유 ID 생성
                Title = title,
                Body = message,
                ShowInForeground = false,
                ForegroundPresentationOption = (PresentationOption.Alert | PresentationOption.Sound),
                CategoryIdentifier = "custom_category",
                ThreadIdentifier = "custom_thread",
                Trigger = timeTrigger,
            };

            iOSNotificationCenter.ScheduleNotification(notification);
#endif
        }
        catch (Exception e)
        {
            Debug.Log("푸시알람 예약 중 오류 발생: " + e.ToString());
        }
    }

    /// <summary>
    /// 모든 예약된 알림을 취소합니다.
    /// </summary>
    public static void CancelAllPushNotifications()
    {
#if UNITY_ANDROID
        AndroidNotificationCenter.CancelAllNotifications();
#elif UNITY_IOS
        iOSNotificationCenter.RemoveAllScheduledNotifications();
#endif
    }
}

다음 코드는 Android와 IOS 각각의 권한 요청과 푸쉬알람으로 보내주는 코드이다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class PushAlerm : MonoBehaviour
{
    private int month, day;
    void Start()
    {
        //외부에서 month와 day를 넣어줄 수 있다.
        DateTime today = DateTime.Now;
        DateTime PushAlermTime = new DateTime(today.Year, month, day, 9, 0, 0);

        LocalPushManager.SchedulePushNotification("제목", "내용", PushAlermTime);

나는 특정 날짜에 푸쉬알람을 제공할 것이므로 특정 날짜에 특정 내용의 푸쉬알람을 보내기 위해서 추가적으로 코드를 작성해주었다.

* 위 코드는 예시로 원하는 month와 day 변수에 원하는 날짜를 넣어주면 해당 날짜에 푸쉬알람이 울리게된다.