Notification Extension: 핵심 개념, 확장 유형 및 설정

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

Notification Extension은 사용자에게 알림을 표시하기 전에 푸시 알림의 콘텐츠와 모양을 수정할 수 있는 iOS 메커니즘입니다. 확장 기능은 운영 체제 쪽에서 별도 프로세스로 작동합니다. UNNotificationServiceExtension은 수신 콘텐츠를 처리하고 UNNotificationContentExtension은 인터페이스를 관리합니다. Apple Developer Documentation, 2026에 따르면 Service Extension은 알림이 표시되기 전에 작업을 수행하는 데 최대 30초까지 사용할 수 있습니다. 이 제한은 첨부 파일을 다운로드하거나 데이터를 해독할 때 중요합니다.

핵심 요점

  • Service Extension — 표시 전에 알림을 가로채고 텍스트 수정, 미디어 추가, 30초 제한 내 데이터 해독이 가능합니다.
  • Content Extension — 스토리보드 또는 SwiftUI를 통해 사용자 정의 UI, 버튼 및 탭 처리가 있는 사용자 정의 알림 인터페이스를 생성합니다.
  • 미디어 첨부 파일 — 이미지, 비디오 및 오디오는 Content Extension으로 전달되기 전에 Service Extension에서 UNNotificationAttachment를 통해 추가됩니다.
  • 등록 — 두 확장 모두 Info.plist에서 알림 카테고리 및 NSExtensionPointIdentifier와 함께 별도 대상으로 등록됩니다.
  • 제한 사항 — 확장은 기본 애플리케이션에 액세스할 수 없으며 50MB 메모리 제한이 있는 격리된 샌드박스에서 실행됩니다.

Notification Extension이란

Notification Extension은 푸시 알림의 표준 동작을 확장하여 콘텐츠 수정 및 인터페이스 사용자 정의 기능을 추가하는 iOS 소프트웨어 구성 요소입니다. 시스템이 표준 형식으로 표시하는 일반 알림과 달리 확장 기능을 사용하면 개발자가 표시 전에 콘텐츠에 영향을 주고 고유한 사용자 인터페이스를 만들 수 있습니다.

두 가지 유형의 알림 확장

Apple은 다양한 목적을 위해 두 가지 유형의 Notification Extension을 제공합니다. UNNotificationServiceExtension은 수신 페이로드 처리를 담당하고 UNNotificationContentExtension은 표시를 관리합니다. Service Extension은 알림이 표시되기 전에 실행되며 Apple Developer Documentation에 따라 최대 30초의 제한된 실행 시간을 갖습니다. Content Extension은 사용자가 알림과 상호 작용한 후 활성화되어 사용자 정의 보기를 표시합니다.

표준 알림과의 차이점

표준 iOS 푸시 알림은 JSON 페이로드의 alert, title 및 subtitle 필드를 기반으로 시스템에 의해 자동으로 표시됩니다. Notification Extension은 제어를 가로챕니다. Service Extension은 원시 페이로드를 수신하여 수정한 후 표시를 위해 시스템에 전달합니다. Content Extension은 표준 배너를 임의의 제어 요소가 있는 사용자 정의 인터페이스로 대체합니다.

확장 수명 주기

장치가 mutable-content: 1 키가 있는 푸시 알림을 수신하면 시스템이 별도 프로세스에서 Service Extension을 시작합니다. 확장 프로세스는 기본 애플리케이션과 격리되어 있으며 50MB 메모리 제한이 있는 자체 샌드박스를 갖습니다. 처리가 완료되면 확장이 completion handler를 호출하여 수정된 UNNotificationContent를 표시를 위해 시스템에 전달합니다.

UNNotificationServiceExtension: 콘텐츠 수정

UNNotificationServiceExtension은 사용자에게 표시하기 전에 프로그래밍 방식으로 푸시 알림을 수정하는 기본 도구입니다. 확장은 페이로드에 mutable-content: 1 플래그가 설정된 알림을 수신하면 자동으로 활성화됩니다. 30초 이내에 확장은 미디어 첨부 파일 다운로드, 텍스트 변경, 암호화된 데이터 해독 또는 콘텐츠 보강을 수행할 수 있습니다.

UNNotificationServiceExtension 프로토콜 메서드

확장은 UNNotificationServiceExtension 프로토콜의 두 가지 주요 메서드를 구현합니다. didReceive 메서드는 원시 UNNotificationRequest와 함께 수신 요청을 받고 새 UNNotificationContent로 completion handler를 통해 수정을 허용합니다. serviceExtensionTimeWillExpire 메서드는 시간 초과 1초 전에 시스템에 의해 호출되며, 이 메서드에서 처리를 완료하고 현재 (부분적일 수 있는) 결과를 전달해야 합니다.

예제: 알림에 이미지 추가

서버가 사용자 정의 필드에 이미지 URL과 함께 푸시를 보내는 시나리오를 고려해 보세요. Service Extension이 네트워크를 통해 이 이미지를 다운로드하고 UNNotificationAttachment를 생성하여 콘텐츠에 추가합니다. UNNotificationAttachment는 로컬 이미지, 비디오 또는 오디오 파일을 수락하고 자동으로 확장의 샌드박스에 복사합니다. 첨부 파일을 생성한 후 확장은 업데이트된 콘텐츠를 시스템에 전달합니다.

swift
class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
        withContentHandler contentHandler:
        @escaping (UNNotificationContent) -> Void) {

        let userInfo = request.content.userInfo
        guard let imageURL = URL(string: userInfo["image-url"] as! String)
        else { contentHandler(request.content); return }

        let attachment = try! UNNotificationAttachment(
            identifier: "image", url: imageURL,
            options: [UNNotificationAttachmentOptionsTypeHintKey: "jpg"])

        let modifiedContent = request.content.mutableCopy()
            as! UNMutableNotificationContent
        modifiedContent.attachments = [attachment]
        contentHandler(modifiedContent)
    }

    override func serviceExtensionTimeWillExpire() {
        contentHandler?(bestAttemptContent ?? request.content)
    }
}

캐싱 및 재사용

동일한 첨부 파일이 포함된 알림이 자주 전송되는 경우 다운로드한 파일을 장치에 캐싱하는 것이 좋습니다. FileManager는 실행 간에 유지되는 확장의 캐시 디렉토리에 대한 액세스를 제공합니다. 이렇게 하면 후속 알림의 처리 시간이 줄어들고 네트워크 부하가 감소합니다. Apple에 따르면 캐싱을 통해 처리 시간을 전체 다운로드 대신 2~5초로 줄일 수 있습니다.

UNNotificationContentExtension: 사용자 정의 인터페이스

UNNotificationContentExtension을 사용하면 표준 알림 배너를 Interface Builder 또는 SwiftUI에서 만든 사용자 정의 인터페이스로 대체할 수 있습니다. 확장은 사용자가 알림에 대해 작업(탭, 아래로 스와이프 또는 3D Touch)을 수행할 때 활성화됩니다. Content Extension은 Service Extension에서 이미 처리된 콘텐츠를 받아 사용자 정의 보기에 표시합니다.

스토리보드 및 알림 카테고리

각 Content Extension은 Info.plist를 통해 하나 이상의 알림 카테고리에 연결됩니다. 카테고리는 서버에서 APNS 페이로드의 category 필드에 의해 정의됩니다. 시스템은 수신된 알림의 카테고리에 따라 적절한 확장을 자동으로 선택합니다. 인터페이스는 표준 UIKit 구성 요소 또는 SwiftUI View를 사용하여 스토리보드를 통해 구축됩니다.

사용자 작업 처리

Content Extension은 UNNotificationAction에 정의된 사용자 정의 버튼 및 탭 핸들러를 지원합니다. UNNotificationAction은 카테고리 등록 단계에서 생성되며 UNTextInputNotificationAction을 통해 텍스트 입력을 지원할 수 있습니다. 사용자가 버튼을 누르면 확장이 작업 식별자와 함께 didReceive 콜백을 수신하고 해당 로직(URL 열기, 서버에 요청 보내기 또는 인터페이스 업데이트)을 실행할 수 있습니다.

성능 제한 사항

Content Extension은 자체 실행 루프와 약 50MB의 메모리 제한이 있는 격리된 프로세스에서 실행됩니다. 확장 성능은 시스템 워치독이 제한을 초과하면 프로세스를 종료하기 때문에 중요합니다. Content Extension 내에서 무거운 계산, 큰 이미지 로딩 및 긴 네트워크 요청을 피하는 것이 좋습니다.

미디어 첨부 파일 및 UNNotificationAttachment

UNNotificationAttachment는 푸시 알림에 미디어 파일(이미지, 비디오, 오디오 또는 GIF)을 추가하는 객체입니다. 첨부 파일은 확장의 샌드박스에 있어야 하는 로컬 파일 URL에서 생성됩니다. 최대 첨부 파일 크기는 10MB를 초과하지 않아야 하며, 그렇지 않으면 시스템이 생성 시 첨부 파일을 거부합니다.

지원되는 형식

Apple은 미디어 첨부 파일에 대해 제한된 형식 집합을 지원합니다. 이미지 — JPEG, PNG, GIF(애니메이션 포함), TIFF. 비디오 — MPEG, MP4, MOV(최대 30초). 오디오 — MP3, AAC, WAV, CAF. 각 형식에 대해 UNNotificationAttachmentOptionsTypeHintKey를 통해 유형을 지정할 수 있으며, 이는 시스템이 파일을 올바르게 처리하는 데 도움이 됩니다.

네트워크에서 첨부 파일 다운로드

푸시 페이로드에는 파일 자체가 아닌 URL만 포함되어 있으므로 첨부 파일 다운로드는 Service Extension 내에서 수행해야 합니다. 최대 다운로드 시간은 30초로 제한되므로 최소 설정으로 URLSession을 사용하고 신호가 약할 때 다운로드를 비활성화하는 것이 좋습니다. 첨부 파일이 제 시간에 로드되지 않으면 미디어 없이 알림이 표시됩니다. 이것이 기본 시스템 동작입니다.

Swift 구현 예제

이미지를 다운로드하고 저장하여 알림에 추가하는 완전한 Notification Extension 예제를 살펴보겠습니다. NotificationService는 UNNotificationServiceExtension을 상속하고 didReceive 메서드를 재정의합니다. 예제는 선택적 필드 처리, 첨부 파일 생성 및 수정된 콘텐츠로 completion handler 호출을 보여줍니다.

swift
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler:
        @escaping (UNNotificationContent) -> Void
    ) {
        self.contentHandler = contentHandler
        self.bestAttemptContent =
            (request.content.mutableCopy()
                as! UNMutableNotificationContent)

        guard let attachmentURLString =
            bestAttemptContent?.userInfo["attachment-url"] as? String,
            let url = URL(string: attachmentURLString)
        else {
            contentHandler(request.content)
            return
        }

        URLSession.shared.downloadTask(with: url) {
            [weak self] localURL, _, error in
            guard let localURL = localURL, error == nil
            else {
                contentHandler(request.content)
                return
            }
            let attachment = try! UNNotificationAttachment(
                identifier: "media", url: localURL)
            self?.bestAttemptContent?.attachments = [attachment]
            contentHandler(self?.bestAttemptContent
                ?? request.content)
        }.resume()
    }

    override func serviceExtensionTimeWillExpire() {
        if let content = bestAttemptContent {
            contentHandler?(content)
        }
    }
}

확장을 위한 Info.plist 구성

확장이 올바르게 작동하려면 Info.plist에 알림 카테고리를 등록해야 합니다. NSExtensionPointIdentifier 키는 Service Extension의 경우 com.apple.usernotifications.service로, Content Extension의 경우 com.apple.usernotifications.content로 설정됩니다. 카테고리는 AppDelegate에서 UNUserNotificationCenter를 통해 앱 시작 시 정의되며, 확장은 페이로드에 일치하는 카테고리가 있는 알림에 대해서만 활성화됩니다.

자주 묻는 질문

Service Extension과 Content Extension의 차이점은 무엇인가요?

Service Extension은 알림이 표시되기 전에 콘텐츠를 수정합니다 — 미디어 추가, 텍스트 변경, 데이터 해독. Content Extension은 사용자 상호 작용 후 알림 인터페이스를 사용자 정의 인터페이스로 대체합니다. Service Extension은 표시 전에 작동하고 Content Extension은 표시 후에 작동합니다.

Service Extension에서 처리 시간은 얼마나 주어지나요?

시스템은 didReceive에서 코드 실행을 위해 30초를 할당합니다. 이 시간 내에 처리가 완료되지 않으면 serviceExtensionTimeWillExpire가 호출되어 현재 결과를 전달해야 합니다. 첨부 파일 다운로드를 고려하여 10~15초 이내에 완료하는 것이 좋습니다.

Content Extension에서 SwiftUI를 사용할 수 있나요?

네, iOS 16부터 Content Extension에서 SwiftUI가 지원됩니다. View는 UIHostingController에 래핑되어 스토리보드에 추가됩니다. 그러나 메모리 제한으로 인해 SwiftUI는 최소한의 요소로 간단한 인터페이스에만 사용하는 것이 좋습니다.

첨부 파일 다운로드 오류를 어떻게 처리하나요?

다운로드 오류 또는 시간 초과 시 첨부 파일 없이 원래 콘텐츠로 completion handler를 호출하면 됩니다. 시스템이 알림을 미디어 없이 표준 형식으로 표시합니다. 진단을 위해 OSLog를 통해 오류를 기록하되 알림 표시를 차단하지 마세요.

Notification Extension의 메모리 제한은 어떻게 되나요?

확장은 약 50MB 제한이 있는 격리된 프로세스에서 실행됩니다. 초과 시 시스템 워치독이 프로세스를 종료합니다. 큰 파일 로딩, 메모리에 이미지 저장, URLSession 작업 시 누수를 피하세요.

요약

  • Notification Extension — 푸시 알림 수정을 위한 iOS 메커니즘으로 Service Extension(콘텐츠)과 Content Extension(인터페이스)을 포함합니다.
  • Service Extension은 30초 제한으로 알림 표시 전에 페이로드를 처리하고 미디어 첨부 파일을 추가하고 데이터를 해독할 수 있습니다.
  • Content Extension은 UIKit 또는 SwiftUI를 통해 표준 배너를 사용자 정의 인터페이스로 대체하고 대화형 버튼을 지원합니다.
  • UNNotificationAttachment는 알림에 이미지, 비디오 및 오디오를 추가하고 JPEG, PNG, MP4, MP3 등의 형식을 지원합니다.
  • 확장 등록은 활성화를 위해 NSExtensionPointIdentifier 및 알림 카테고리를 지정하여 Info.plist를 통해 수행됩니다.
  • 제한 사항 — 50MB 메모리 제한, 기본 애플리케이션에 액세스할 수 없는 격리된 샌드박스, 제한된 실행 시간.
  • Notification Extension은 풍부한 사용자 알림을 생성하는 핵심 도구로, iOS에서 푸시 커뮤니케이션의 참여도와 기능을 향상시킵니다.

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

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

프로젝트 논의

더 읽어보기