Notification Category(알림 카테고리)는 푸시 알림을 유형별로 그룹화하고 사용자 지정 작업을 첨부하기 위한 iOS 메커니즘입니다. 카테고리는 알림에 3D Touch 또는 길게 누르기를 사용할 때 표시되는 버튼과 시스템이 이 유형의 수신 알림을 처리하는 방식을 결정합니다. Apple 개발자 문서에 따르면, UNNotificationCategory는 UNUserNotificationCenter에 등록되며 APNS 페이로드의 category 필드를 통해 알림에 연결됩니다.
핵심 요점
Notification Category는 iOS 8.0부터 제공되는 기능으로, 개발자가 푸시 알림을 분류하고 대화형 작업을 추가할 수 있게 합니다. 사용자가 알림을 받고 강하게 누르거나(3D Touch) 길게 누르면 카테고리에 정의된 버튼이 나타납니다. 이렇게 하면 알림이 대화형이 되어 사용자가 앱을 열지 않고도 작업을 수행할 수 있습니다.
카테고리는 UNNotificationCategory 객체를 사용하여 등록되며, 식별자, 작업 배열 및 선택적 표시 매개변수를 포함합니다. 시스템은 APNS 페이로드의 카테고리 식별자를 사용하여 등록된 카테고리를 찾고 해당 버튼을 표시합니다.
Android Notification Channel과 달리 iOS Category는 중요도, 사운드 또는 진동을 관리하지 않습니다. 유일한 목적은 알림에 대화형 기능을 제공하는 것입니다: 응답, 확인, 취소 또는 텍스트 입력 버튼.
iOS에서 푸시 알림을 표시하는 데 카테고리는 필수가 아닙니다. 알림은 항상 표시됩니다 — 카테고리가 등록되어 있으면 버튼과 함께, 그렇지 않으면 버튼 없이 표시됩니다. 카테고리는 알림에 상호작용성을 추가하는 데만 필요합니다.
카테고리 메커니즘은 네 단계로 구성됩니다: 클라이언트에서 카테고리 등록, 카테고리가 포함된 APNS 페이로드 전송, 시스템이 카테고리를 인식, 사용자 작업 처리.
카테고리의 작업은 두 가지 유형이 있습니다: foreground(앱 열기)와 background(백그라운드에서 실행). 백그라운드 작업의 경우 앱은 UNNotificationActionHandler에서 처리하는 데 제한된 시간(약 30초)을 받습니다.
UNNotificationCategory는 options 매개변수를 통해 여러 옵션을 지원합니다: customDismissAction — 알림을 스와이프하여 닫을 때 이벤트 수신, allowInCarPlay — CarPlay에서 작업 표시, hiddenPreviewsBodyPlaceholder — 숨겨진 미리보기의 사용자 지정 플레이스홀더 텍스트.
iOS는 알림 카테고리에 두 가지 유형의 작업을 제공합니다. 각 유형은 고유한 목적과 사용자와의 상호 작용 방식을 가지고 있습니다.
| 유형 | 클래스 | 설명 | 예시 |
|---|---|---|---|
| 단순 작업 | UNNotificationAction | 제목과 옵션(destructive, foreground, authenticationRequired)이 있는 버튼 | “삭제”, “보기” |
| 텍스트 입력 | UNTextInputAction | 플레이스홀더가 있는 텍스트 입력 필드를 여는 버튼 | “답장”, “댓글” |
UNTextInputAction은 iOS의 고유한 기능입니다. 사용자가 “답장” 버튼을 탭하면 시스템이 텍스트 필드를 표시하고 사용자가 답변을 입력합니다. 입력된 텍스트는 작업 식별자와 함께 델리게이트에 전달됩니다. 이를 통해 앱을 열지 않고도 빠른 답장을 구현할 수 있습니다.
작업 옵션: options.authenticationRequired — 기기 잠금 해제 필요, options.destructive — 버튼을 빨간색으로 강조(위험한 작업용), options.foreground — 탭 후 앱 열기.
카테고리는 앱 실행 시 등록되며, 일반적으로 didFinishLaunchingWithOptions 메서드에서 수행됩니다. 등록은 UNUserNotificationCenter를 통해 알림 권한을 요청한 후 이루어집니다. 카테고리는 매 실행 시 업데이트할 수 있습니다 — 이전 버전은 새 버전으로 대체됩니다.
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate {
func registerNotificationCategories() {
let replyAction = UNTextInputNotificationAction(
identifier: "reply",
title: "답장",
options: [.foreground],
textInputButtonTitle: "보내기",
textInputPlaceholder: "메시지 입력..."
)
let deleteAction = UNNotificationAction(
identifier: "delete",
title: "삭제",
options: [.destructive]
)
let messageCategory = UNNotificationCategory(
identifier: "message",
actions: [replyAction, deleteAction],
intentIdentifiers: [],
options: [.customDismissAction]
)
UNUserNotificationCenter.current()
.setNotificationCategories([messageCategory])
}
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().delegate = self
registerNotificationCategories()
return true
}
}
카테고리를 등록한 후, APNS 페이로드에 category = “message”가 포함된 모든 알림은 “답장” 및 “삭제” 버튼을 표시합니다. 탭 처리는 userNotificationCenter:didReceive response에서 이루어지며, actionIdentifier가 눌린 버튼을 결정합니다.
사용자가 카테고리 버튼을 탭하면 iOS는 UNNotificationResponse 객체와 함께 UNUserNotificationCenterDelegate를 호출합니다. response.actionIdentifier에는 탭된 버튼의 식별자가 포함되고, response.notification.request.content.userInfo에는 페이로드의 사용자 지정 데이터가 포함됩니다.
Android Notification Channel에 익숙한 개발자들은 종종 이를 iOS Notification Category와 혼동합니다. 이름은 비슷하지만, 이러한 메커니즘은 다른 작업을 해결하고 다르게 작동합니다.
두 플랫폼 모두 두 메커니즘을 결합할 수 있습니다: Android에서는 NotificationCompat의 작업이 있는 채널에 알림이 속할 수 있고, iOS에서는 카테고리가 채널을 보완합니다. iOS에서 채널은 thread-id라고 하며 알림 센터에서 알림을 그룹화하는 데 사용됩니다.
알림에 카테고리 버튼이 표시되려면 서버가 APNS 페이로드에 category 키를 포함해야 합니다. 이 키가 없으면 시스템은 알림에 어떤 카테고리를 적용해야 할지 알 수 없습니다.
{
"aps": {
"alert": {
"title": "새 메시지",
"body": "안나: 안녕하세요! 어떻게 지내세요?"
},
"category": "message",
"thread-id": "chat_123",
"badge": 5,
"sound": "default"
}
}
category 키는 클라이언트에서 setNotificationCategories를 통해 등록된 식별자와 정확히 일치해야 합니다. 대소문자를 구분합니다 — “message”와 “Message”는 다른 카테고리로 간주됩니다. 카테고리를 찾을 수 없으면 알림이 버튼 없이 표시되며 로그에 오류가 기록되지 않습니다.
서버가 클라이언트에 등록되지 않은 카테고리로 알림을 보내면 iOS는 카테고리를 무시하고 알림을 버튼 없이 표시합니다. 오류가 기록되지 않으며 앱은 불일치를 알 수 없습니다. 서버와 클라이언트 간에 카테고리 목록을 동기화하는 것이 좋습니다.
iOS에서 알림 카테고리를 설계할 때는 하나의 카테고리 — 하나의 시나리오 원칙을 따르세요. 각 카테고리는 특정 유형의 상호 작용에 해당해야 합니다: 메시지에 답장, 작업 확인, 요청 거부. 하나의 카테고리에 다른 시나리오를 혼합하지 마세요.
앱을 열지 않고 텍스트를 입력해야 하는 시나리오(메시징 답장, 댓글, 빠른 메모)에는 UNTextInputAction을 사용하세요. 텍스트 작업은 참여도를 높입니다 — 사용자는 앱 내에서 5회 이상의 탭 대신 2회의 탭으로 의미 있는 작업을 수행합니다.
위험한 작업(삭제, 차단)에는 destructive 옵션을 사용하세요. iOS는 이러한 버튼을 빨간색으로 강조하여 작업의 되돌릴 수 없음을 사용자에게 경고합니다. 기기 잠금 해제가 필요한 작업(개인 데이터 보기)에는 authenticationRequired를 지정하세요.
다양한 기기에서 카테고리를 테스트하세요: 3D Touch 지원 iPhone, 3D Touch 미지원 iPhone(길게 누르기), iPad, Mac. Apple 플랫폼 간에 카테고리 동작이 약간 다를 수 있습니다. CarPlay에 특별히 주의하세요: 카테고리 버튼이 자동차 화면에 나타나며 운전자 안전을 위해 최소한의 텍스트로 설계해야 합니다.
자주 묻는 질문
제한이 없습니다 — iOS는 UNNotificationCategory의 수에 제한을 두지 않습니다. 그러나 실제로는 델리게이트 처리를 복잡하게 하지 않기 위해 10~15개 이하의 카테고리를 사용하는 것이 좋습니다. 각 카테고리에는 최대 4개의 작업(버튼)이 포함될 수 있습니다. 4개를 초과하는 작업은 시스템에서 무시됩니다.
UNUserNotificationCenterDelegate 프로토콜과 didReceive 메서드를 구현하세요. response.actionIdentifier를 확인하세요: UNNotificationDismissActionIdentifier — 스와이프하여 닫기, UNNotificationDefaultActionIdentifier — 본문 탭, 또는 사용자 지정 버튼 식별자. 텍스트 입력 버튼의 경우 텍스트는 response.userText를 통해 사용할 수 있습니다.
Category — 알림의 대화형 작업(버튼)을 정의합니다. Thread-id — 알림 센터에서 알림을 주제별로 그룹화합니다. 두 키 모두 APNS 페이로드에 지정됩니다. Category와 thread-id는 관련이 없습니다: 알림에 카테고리가 있어도 thread-id가 없을 수 있으며 그 반대도 가능합니다.
네, UNNotificationCategory는 macOS 10.14+(Mojave)에서 UserNotifications 프레임워크를 사용하는 앱에서 지원됩니다. macOS에서의 카테고리 동작은 iOS와 유사합니다: 알림을 클릭하면 버튼이 표시되고 처리는 UNUserNotificationCenterDelegate를 통해 이루어집니다.
setNotificationCategories를 통해 매 앱 실행 시 카테고리를 등록하는 것을 권장합니다. 시스템은 호출할 때마다 이전 카테고리 세트를 새 것으로 교체합니다. 업데이트하지 않으면 카테고리가 실행 간에 유지되지만, 코드가 변경되면 이전 카테고리가 예기치 않은 동작을 유발할 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.