모바일 개발에서의 로컬 알림: 본질, 유형 및 작동 방식

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

로컬 알림은 원격 서버의 개입 없이 앱이 사용자에게 보내는 메시지입니다. 모든 데이터는 수신자의 디바이스에서 직접 처리되고 표시됩니다. 이 메커니즘은 앱이 백그라운드에 있거나 종료된 경우 리마인더, 타이머 및 알람에 적합합니다. Apple Developer Documentation에 따르면, UNUserNotificationCenter는 iOS에서 로컬 알림의 중앙 집중식 관리를 제공합니다.

핵심 포인트

  • 로컬 알림 — 서버 개입 없이 디바이스가 예약하고 전달하는 메시지
  • 플랫폼 — Android는 NotificationManager 사용, iOS는 UNUserNotificationCenter 사용
  • 예약 — 시간, 위치 또는 캘린더에 따라 알림 트리거 가능
  • 제한 사항 — 로컬 알림은 디바이스 간에 작동하지 않으며 별도의 동기화 로직 필요
  • UX — 올바르게 구성된 알림은 참여도를 높이고 사용자를 앱으로 다시 유입시킴

로컬 알림이란?

로컬 알림은 앱이 설치된 동일한 디바이스에서 운영 체제가 생성하고 표시하는 트리거 메시지입니다. 푸시 알림과 달리 로컬 알림은 외부 서버를 거치지 않습니다 — 모든 예약 로직은 클라이언트에서 실행됩니다.

이러한 알림은 앱 상태(활성, 최소화, 완전히 종료)에 관계없이 작동합니다. 운영 체제가 예약된 시간에 전달을 처리하고, 개발자는 콘텐츠와 트리거만 지정합니다.

시스템은 네트워크가 없어도 로컬 알림 전달을 보장합니다. 이는 안정적인 인터넷 연결과 작동 중인 서버가 필요한 푸시 알림에 비해 주요 이점입니다.

요청의 주요 구성 요소

각 로컬 알림은 콘텐츠(제목, 본문, 사운드), 트리거(시간 또는 위치 조건), 요청 식별자의 세 부분으로 구성됩니다. 식별자를 사용하면 전달 전에 알림을 취소하거나 업데이트할 수 있습니다.

개발자는 iOS에서 앱당 최대 64개의 로컬 알림을 예약할 수 있고 Android에서는 무제한입니다. 이 차이는 운영 체제의 아키텍처 제약 때문입니다.

iOS 및 Android에서 로컬 알림 작동 방식

두 플랫폼 모두 로컬 알림 작업을 위한 자체 API를 제공합니다. iOS에서는 중앙 구성 요소가 UNUserNotificationCenter이고, Android에서는 NotificationManager입니다. 인터페이스는 다르지만 로직은 동일합니다: 앱이 요청을 생성하고 시스템에 등록하며 OS가 예약된 시간에 알림을 전달합니다.

iOS는 캘린더 이벤트에 UNCalendarNotificationTrigger, 간격에 UNTimeIntervalNotificationTrigger, 위치에 UNLocationNotificationTrigger를 사용합니다. Android는 AlarmManager, WorkManager 및 setExact를 통한 정확한 예약을 제공합니다.

Android 12부터 — SCHEDULE_EXACT_ALARM은 사용자의 특별 권한이 필요합니다. iOS에서는 UNUserNotificationCenter.requestAuthorization을 통해 한 번 권한이 요청되고 사용자가 액세스 수준(배너, 사운드, 배지)을 선택합니다.

로컬 알림 유형

로컬 알림은 콘텐츠가 아닌 트리거 유형에 따라 분류됩니다. 각 유형은 언제, 어떤 조건에서 알림이 사용자에게 표시될지 결정합니다.

플랫폼별 트리거 비교

iOS와 Android에서 트리거 유형은 다르게 구현되지만 논리적 분류는 동일합니다. iOS는 날짜에 UNCalendarNotificationTrigger, 간격에 UNTimeIntervalNotificationTrigger, 위치에 UNLocationNotificationTrigger를 사용합니다. Android는 setExact 및 setRepeating이 있는 AlarmManager와 지연된 작업을 위한 WorkManager를 제공합니다.

트리거 유형설명예시
시간 간격시작 후 N초 후 알림카운트다운 타이머
캘린더 날짜특정 날짜와 시간에 알림회의 리마인더
위치영역 진입/이탈 시 알림매장 리마인더
즉시API 호출 시 즉시 전달다운로드 알림

iOS는 UNNotificationAttachment도 지원합니다 — 이미지, 오디오 또는 비디오를 알림 본문에 첨부합니다. Android는 NotificationCompat.Style을 통해 버튼과 큰 이미지가 있는 사용자 정의 템플릿을 지원합니다.

트리거 선택은 시나리오에 따라 다릅니다: 캘린더 리마인더는 캘린더 트리거에 가장 적합하고, 위치 리마인더는 위치에 적합합니다. 간격 트리거는 고정된 기간의 반복 이벤트에 적합합니다.

백그라운드에서 트리거 동작

iOS에서는 앱이 종료된 경우에도 시스템이 로컬 알림을 전달합니다 — UNUserNotificationCenter가 독립적으로 대기열을 관리합니다. Android에서는 전달 방식이 선택한 메커니즘에 따라 다릅니다: AlarmManager는 화면이 꺼져 있어도 작동하고, WorkManager는 절전을 고려합니다.

모바일 앱 사용 사례

로컬 알림은 외부 인프라가 과도하거나 사용할 수 없는 작업을 해결합니다. 주요 시나리오: 리마인더, 타이머, 온보딩 팁 및 지연된 작업.

  • 리마인더 — 캘린더 앱이 지정된 이벤트 날짜에 로컬 알림 생성
  • 온보딩 팁 — 설치 후 하루 뒤, 앱이 화면 팁 표시
  • 타이머 — 주방 타이머가 설정 시간 후 앱이 종료된 상태에서도 작동
  • 작업 진행 — 다운로드 완료 또는 데이터 내보내기 알림

Localytics의 연구에 따르면 로컬 리마인더를 사용하는 앱은 설치 후 첫 주에 35% 더 많은 사용자를 유지합니다. 이는 로컬 알림을 강력한 온보딩 도구로 만듭니다.

빈도를 남용하지 않는 것이 중요합니다 — 시스템은 동일한 앱의 알림을 자동으로 그룹화하고 사용자는 알림이 성가실 경우 모든 로컬 알림을 비활성화할 수 있습니다. 중요하지 않은 이벤트의 최적 빈도는 하루 2~3개를 초과하지 않아야 합니다.

Android 예약 예제

Android에서 로컬 알림을 예약하려면 AlarmManager와 함께 NotificationManager를 사용하세요. Android 8+에서는 먼저 알림 채널을 생성해야 합니다. 그렇지 않으면 알림이 표시되지 않습니다.

kotlin
val channelId = "reminder_channel"
val notificationId = "task_reminder_42"

val channel = NotificationChannel(
    channelId,
    "리마인더",
    NotificationManager.IMPORTANCE_HIGH
).apply {
    description = "작업 리마인더 채널"
}

val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)

val intent = Intent(this, ReminderReceiver::class.java).apply {
    putExtra("notification_id", notificationId)
    putExtra("channel_id", channelId)
}

val pendingIntent = PendingIntent.getBroadcast(
    this, notificationId.hashCode(),
    intent, PendingIntent.FLAG_UPDATE_CURRENT
)

val alarmManager = getSystemService(AlarmManager::class.java)
alarmManager.setExact(
    AlarmManager.RTC_WAKEUP,
    triggerTimeMillis,
    pendingIntent
)

Android 12+에서는 setExact를 호출하기 전에 SCHEDULE_EXACT_ALARM 권한을 확인하세요. 권한이 부여되지 않은 경우 — 시간 창 내에서 전달을 보장하는 setWindow를 사용하세요.

BroadcastReceiver에서 처리

AlarmManager가 작동하면 시스템이 BroadcastReceiver가 수신하는 브로드캐스트 Intent를 보냅니다. 그 안에서 NotificationManager를 통해 알림을 생성하고 표시해야 합니다. PendingIntent가 FLAG_UPDATE_CURRENT를 사용하는지 확인하세요. 그렇지 않으면 데이터가 변경될 때 이전 알림이 계속 이전 Intent를 사용합니다.

iOS 예약 예제

iOS에서는 UNUserNotificationCenter를 통해 UNMutableNotificationContent와 트리거 중 하나를 사용하여 로컬 알림을 생성합니다. 예약 전에 사용자로부터 권한을 받아야 합니다.

swift
import UserNotifications

let center = UNUserNotificationCenter.current()

center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
    guard granted else { return }
}

let content = UNMutableNotificationContent()
content.title = "작업 리마인더"
content.body = "18:00까지 보고서를 완료하는 것을 잊지 마세요"
content.sound = .default
content.userInfo = ["task_id": "42"]

let trigger = UNTimeIntervalNotificationTrigger(
    timeInterval: 3600,
    repeats: false
)

let request = UNNotificationRequest(
    identifier: "task_reminder_42",
    content: content,
    trigger: trigger
)

center.add(request)

iOS는 최대 64개의 동시 로컬 알림 요청을 지원합니다. 제한을 초과하면 활성 요청이 전달되거나 취소될 때까지 시스템이 새 요청을 거부합니다. 현재 대기열을 확인하려면 getPendingNotificationRequests를 사용하세요.

델리게이트 응답 처리

사용자가 iOS에서 로컬 알림과 상호 작용하면 UNUserNotificationCenterDelegate의 userNotificationCenter:didReceive response 메서드가 호출됩니다. 이 메서드는 요청 식별자, actionIdentifier(누른 버튼) 및 사용자 정의 userInfo를 제공합니다. 이를 통해 단순 알림 열기와 특정 작업 버튼 누르기를 구분할 수 있습니다.

로컬 알림 모범 사례

로컬 알림이 성가시지 않고 유용하려면 몇 가지 주요 규칙을 따르세요. 첫째: 빈도 제어 — 중요하지 않은 이벤트의 경우 하루 2~3개를 초과하지 마세요. 그렇지 않으면 사용자가 모든 앱 알림을 비활성화합니다.

둘째: 사용자에게 선택권을 주세요. 인터페이스에서 특정 유형의 로컬 알림을 비활성화하는 기능을 추가하세요. Android에서는 낮은 중요도의 별도 NotificationChannel을 사용하고, iOS에서는 앱 설정에서 별도 카테고리를 사용하세요.

셋째: 상황 관련성 — 알림은 사용자가 필요로 할 때 표시되어야 합니다. 위치 트리거는 집 근처 리마인더에 이상적이고, 캘린더 트리거는 회의에, 간격 트리거는 물 마시기나 스트레칭 같은 정기 활동에 적합합니다. 불필요하게 유형을 혼합하지 마세요.

넷째: 실제 디바이스에서 테스트하세요. iOS 시뮬레이터는 특히 백그라운드에서 로컬 알림 전달의 모든 시나리오를 에뮬레이션하지 않습니다. Android에서는 adb shell dumpsys notification을 사용하여 예약된 알림의 대기열과 매개변수를 확인하세요. 다섯째: 항상 사용자에게 앱 인터페이스를 통해 알림을 비활성화하는 기능을 제공하세요 — 이는 UX 및 App Store Review Guidelines의 필수 요구 사항입니다.

자주 묻는 질문

로컬 알림과 푸시 알림의 차이점은 무엇인가요?

로컬 알림은 서버 개입 없이 디바이스가 예약하고 전달합니다. 푸시 알림은 외부 서비스(FCM, APNS)와 인터넷 연결이 필요합니다. 로컬 알림은 오프라인에서 작동하고, 푸시는 네트워크 액세스가 필요합니다.

로컬 알림은 몇 개까지 예약할 수 있나요?

iOS는 동시에 64개의 예약된 요청으로 제한합니다. Android에는 엄격한 제한이 없지만 500개 이상의 알림은 시스템 성능을 저하시키고 전달 시간에 영향을 줄 수 있습니다.

예약 후 로컬 알림을 취소할 수 있나요?

네, iOS에서는 요청 식별자와 함께 removePendingNotificationRequests를 사용하세요. Android에서는 NotificationManager.cancel을 호출하거나 AlarmManager를 통해 PendingIntent를 취소하세요. 취소에는 고유 식별자가 필수입니다.

로컬 알림에 사용자 권한이 필요한가요?

iOS에서는 requestAuthorization을 통한 권한이 필수입니다. Android 13+(Tiramisu)에서도 POST_NOTIFICATIONS 권한이 필요합니다. 이전 Android 버전에서는 로컬 알림에 명시적 권한이 필요하지 않습니다.

로컬 알림에 버튼을 추가하려면 어떻게 하나요?

iOS에서는 UNNotificationAction을 생성하여 UNNotificationCategory에 추가하세요. Android에서는 BroadcastReceiver를 대상으로 하는 PendingIntent와 함께 NotificationCompat.Builder.addAction을 사용하세요. 각 버튼은 앱에서 개별 작업을 트리거합니다.

요약

  • 로컬 알림 — 서버 인프라 없이 디바이스가 예약하고 전달하는 메시지
  • UNUserNotificationCenter — iOS에서 로컬 알림을 위한 주요 API
  • NotificationManager — Android에서 로컬 알림을 위한 주요 API
  • 트리거 유형 — 시간 간격, 캘린더 날짜, 위치, 즉시 전달
  • 제한 — iOS는 64개 예약 요청으로 제한, Android는 엄격한 제한 없음
  • 권한 — iOS 및 Android 13+는 알림에 명시적 사용자 동의 필요
  • 오프라인 — 로컬 알림은 인터넷 연결 없이 작동하여 푸시보다 안정적

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

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

프로젝트 논의

더 읽어보기