Notification Extension: Khái niệm chính, loại mở rộng và thiết lập

Tác giả: IT Sectr Đã đăng: 2026-03-20 Thời gian đọc: 8 phút

Notification Extension là cơ chế iOS cho phép sửa đổi nội dung và giao diện của thông báo push trước khi hiển thị cho người dùng. Các tiện ích mở rộng hoạt động phía hệ điều hành trong một tiến trình riêng: UNNotificationServiceExtension xử lý nội dung đến, trong khi UNNotificationContentExtension quản lý giao diện. Theo Apple Developer Documentation, 2026, Service Extension có tối đa 30 giây để thực hiện tác vụ trước khi thông báo được hiển thị. Giới hạn này rất quan trọng khi tải tệp đính kèm hoặc giải mã dữ liệu.

Điểm chính

  • Service Extension — chặn thông báo trước khi hiển thị, cho phép thay đổi văn bản, thêm phương tiện và giải mã dữ liệu với giới hạn 30 giây.
  • Content Extension — tạo giao diện thông báo tùy chỉnh với UI tùy ý, nút và xử lý chạm qua storyboard hoặc SwiftUI.
  • Tệp đính kèm đa phương tiện — hình ảnh, video và âm thanh được thêm qua UNNotificationAttachment trong Service Extension trước khi chuyển đến Content Extension.
  • Đăng ký — cả hai tiện ích mở rộng được đăng ký trong Info.plist dưới dạng target riêng biệt với chỉ định danh mục thông báo và NSExtensionPointIdentifier.
  • Giới hạn — tiện ích mở rộng không có quyền truy cập vào ứng dụng chính, hoạt động trong hộp cát cách ly với giới hạn bộ nhớ 50 MB.

Notification Extension là gì

Notification Extension là một thành phần phần mềm iOS mở rộng hành vi tiêu chuẩn của thông báo push bằng cách thêm khả năng sửa đổi nội dung và tùy chỉnh giao diện. Không giống như thông báo thông thường được hệ thống hiển thị ở định dạng tiêu chuẩn, tiện ích mở rộng cho phép nhà phát triển tác động đến nội dung trước khi hiển thị và tạo giao diện người dùng độc đáo.

Hai loại tiện ích mở rộng thông báo

Apple cung cấp hai loại Notification Extension cho các mục đích khác nhau: UNNotificationServiceExtension xử lý tải trọng đến, trong khi UNNotificationContentExtension quản lý hiển thị. Service Extension chạy trước khi thông báo được hiển thị và có thời gian thực thi giới hạn — lên đến 30 giây theo Apple Developer Documentation. Content Extension được kích hoạt sau khi người dùng tương tác với thông báo và hiển thị chế độ xem tùy chỉnh.

Khác biệt so với thông báo tiêu chuẩn

Thông báo push iOS tiêu chuẩn được hệ thống tự động hiển thị dựa trên các trường alert, title và subtitle từ tải trọng JSON. Notification Extension chặn quyền điều khiển: Service Extension nhận tải trọng thô, sửa đổi nó và chuyển cho hệ thống để hiển thị. Content Extension thay thế biểu ngữ tiêu chuẩn bằng giao diện tùy chỉnh với bất kỳ thành phần điều khiển nào.

Vòng đời của tiện ích mở rộng

Khi thiết bị nhận được thông báo push với khóa mutable-content: 1, hệ thống khởi chạy Service Extension trong một tiến trình riêng. Tiến trình tiện ích mở rộng được cách ly khỏi ứng dụng chính và có hộp cát riêng với giới hạn bộ nhớ 50 MB. Sau khi hoàn tất xử lý, tiện ích mở rộng gọi completion handler, chuyển UNNotificationContent đã sửa đổi cho hệ thống để hiển thị.

UNNotificationServiceExtension: Sửa đổi nội dung

UNNotificationServiceExtension là công cụ chính để sửa đổi thông báo push theo chương trình trước khi hiển thị cho người dùng. Tiện ích mở rộng tự động kích hoạt khi nhận được thông báo có tải trọng được đặt cờ mutable-content: 1. Trong vòng 30 giây, tiện ích mở rộng có thể tải tệp đính kèm đa phương tiện, thay đổi văn bản, giải mã dữ liệu đã mã hóa hoặc làm phong phú nội dung.

Các phương thức của giao thức UNNotificationServiceExtension

Tiện ích mở rộng triển khai hai phương thức chính từ giao thức UNNotificationServiceExtension. Phương thức didReceive nhận yêu cầu đến với UNNotificationRequest thô và cho phép sửa đổi thông qua completion handler với UNNotificationContent mới. Phương thức serviceExtensionTimeWillExpire được hệ thống gọi một giây trước khi hết thời gian chờ — trong đó bạn phải hoàn tất xử lý và chuyển kết quả hiện tại (có thể một phần).

Ví dụ: thêm hình ảnh vào thông báo

Hãy xem xét tình huống máy chủ gửi push với URL hình ảnh trong trường tùy chỉnh. Service Extension tải hình ảnh này qua mạng, tạo UNNotificationAttachment và thêm vào nội dung. UNNotificationAttachment chấp nhận tệp hình ảnh, video hoặc âm thanh cục bộ và tự động sao chép vào hộp cát của tiện ích mở rộng. Sau khi tạo tệp đính kèm, tiện ích mở rộng chuyển nội dung đã cập nhật cho hệ thống.

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)
    }
}

Lưu vào bộ nhớ đệm và tái sử dụng

Khi thông báo có cùng tệp đính kèm được gửi thường xuyên, bạn nên lưu vào bộ nhớ đệm các tệp đã tải trên thiết bị. FileManager cung cấp quyền truy cập vào thư mục bộ nhớ đệm của tiện ích mở rộng, tồn tại giữa các lần khởi chạy. Điều này giảm thời gian xử lý cho các thông báo tiếp theo và giảm tải mạng. Theo Apple, lưu vào bộ nhớ đệm có thể giảm thời gian xử lý xuống còn 2–5 giây thay vì tải hoàn toàn.

UNNotificationContentExtension: Giao diện tùy chỉnh

UNNotificationContentExtension cho phép thay thế biểu ngữ thông báo tiêu chuẩn bằng giao diện tùy chỉnh được tạo trong Interface Builder hoặc SwiftUI. Tiện ích mở rộng được kích hoạt khi người dùng thực hiện hành động trên thông báo: chạm, vuốt xuống hoặc 3D Touch. Content Extension nhận nội dung đã được Service Extension xử lý và hiển thị trong chế độ xem tùy chỉnh.

Storyboard và danh mục thông báo

Mỗi Content Extension được liên kết với một hoặc nhiều danh mục thông báo thông qua Info.plist. Danh mục được xác định trên máy chủ bằng trường category trong tải trọng APNS. Hệ thống tự động chọn tiện ích mở rộng phù hợp dựa trên danh mục của thông báo nhận được. Giao diện được xây dựng qua storyboard sử dụng các thành phần UIKit tiêu chuẩn hoặc SwiftUI View.

Xử lý hành động của người dùng

Content Extension hỗ trợ các nút tùy chỉnh và trình xử lý chạm được định nghĩa trong UNNotificationAction. UNNotificationAction được tạo ở giai đoạn đăng ký danh mục và có thể hỗ trợ nhập văn bản qua UNTextInputNotificationAction. Khi người dùng nhấn nút, tiện ích mở rộng nhận được callback didReceive với mã định danh hành động và có thể thực thi logic tương ứng — mở URL, gửi yêu cầu đến máy chủ hoặc cập nhật giao diện.

Giới hạn hiệu suất

Content Extension chạy trong một tiến trình cách ly với vòng lặp thực thi riêng và giới hạn bộ nhớ khoảng 50 MB. Hiệu suất của tiện ích mở rộng rất quan trọng vì watchdog của hệ thống sẽ kết thúc tiến trình khi vượt quá giới hạn. Bạn nên tránh các tính toán nặng, tải hình ảnh lớn và yêu cầu mạng kéo dài bên trong Content Extension.

Tệp đính kèm đa phương tiện và UNNotificationAttachment

UNNotificationAttachment là một đối tượng thêm tệp đa phương tiện vào thông báo push: hình ảnh, video, âm thanh hoặc GIF. Tệp đính kèm được tạo từ URL tệp cục bộ phải nằm trong hộp cát của tiện ích mở rộng. Kích thước tối đa của tệp đính kèm không được vượt quá 10 MB, nếu không hệ thống sẽ từ chối tệp đính kèm khi tạo.

Các định dạng được hỗ trợ

Apple hỗ trợ một tập hợp định dạng giới hạn cho tệp đính kèm đa phương tiện. Hình ảnh — JPEG, PNG, GIF (bao gồm hoạt hình), TIFF. Video — MPEG, MP4, MOV với thời lượng tối đa 30 giây. Âm thanh — MP3, AAC, WAV, CAF. Đối với mỗi định dạng, bạn có thể chỉ định loại qua UNNotificationAttachmentOptionsTypeHintKey, giúp hệ thống xử lý tệp chính xác.

Tải tệp đính kèm từ mạng

Vì tải trọng push chỉ chứa URL, không phải tệp, việc tải tệp đính kèm phải được thực hiện bên trong Service Extension. Thời gian tải tối đa bị giới hạn ở 30 giây, do đó bạn nên sử dụng URLSession với cài đặt tối thiểu và vô hiệu hóa tải khi tín hiệu yếu. Nếu tệp đính kèm không được tải kịp, thông báo sẽ hiển thị mà không có phương tiện — đây là hành vi mặc định của hệ thống.

Ví dụ triển khai trong Swift

Hãy xem qua ví dụ Notification Extension hoàn chỉnh tải hình ảnh, lưu và thêm vào thông báo. NotificationService kế thừa từ UNNotificationServiceExtension và ghi đè phương thức didReceive. Ví dụ minh họa cách xử lý các trường tùy chọn, tạo tệp đính kèm và gọi completion handler với nội dung đã sửa đổi.

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)
        }
    }
}

Cấu hình Info.plist cho tiện ích mở rộng

Để tiện ích mở rộng hoạt động chính xác, cần đăng ký các danh mục thông báo trong Info.plist. Khóa NSExtensionPointIdentifier được đặt thành com.apple.usernotifications.service cho Service Extension hoặc com.apple.usernotifications.content cho Content Extension. Các danh mục được xác định trong AppDelegate khi khởi chạy ứng dụng qua UNUserNotificationCenter, và tiện ích mở rộng chỉ kích hoạt cho thông báo có danh mục phù hợp trong tải trọng.

Câu hỏi thường gặp

Service Extension khác Content Extension như thế nào?

Service Extension sửa đổi nội dung trước khi thông báo được hiển thị — thêm phương tiện, thay đổi văn bản, giải mã dữ liệu. Content Extension thay thế giao diện thông báo bằng giao diện tùy chỉnh sau khi người dùng tương tác. Service Extension hoạt động trước khi hiển thị, Content Extension hoạt động sau đó.

Bao nhiêu thời gian được cấp cho xử lý trong Service Extension?

Hệ thống phân bổ 30 giây để thực thi mã trong didReceive. Nếu xử lý không hoàn tất trong thời gian này, serviceExtensionTimeWillExpire được gọi, nơi bạn phải chuyển kết quả hiện tại. Bạn nên giới hạn trong 10–15 giây có tính đến việc tải tệp đính kèm.

Có thể sử dụng SwiftUI trong Content Extension không?

Có, SwiftUI được hỗ trợ trong Content Extension từ iOS 16 trở lên. View được bọc trong UIHostingController và thêm vào storyboard. Tuy nhiên, do giới hạn bộ nhớ, bạn chỉ nên sử dụng SwiftUI cho các giao diện đơn giản với số lượng phần tử tối thiểu.

Làm thế nào để xử lý lỗi tải tệp đính kèm?

Trong trường hợp lỗi tải hoặc hết thời gian, chỉ cần gọi completion handler với nội dung gốc không có tệp đính kèm. Hệ thống sẽ hiển thị thông báo ở dạng tiêu chuẩn không có phương tiện. Ghi lại lỗi qua OSLog để chẩn đoán, nhưng không chặn hiển thị thông báo.

Giới hạn bộ nhớ của Notification Extension là gì?

Tiện ích mở rộng chạy trong một tiến trình cách ly với giới hạn khoảng 50 MB. Khi vượt quá, hệ thống sẽ kết thúc tiến trình qua watchdog. Tránh tải tệp lớn, lưu trữ hình ảnh trong bộ nhớ và rò rỉ khi làm việc với URLSession.

Tổng kết

  • Notification Extension — cơ chế iOS để sửa đổi thông báo push, bao gồm Service Extension (nội dung) và Content Extension (giao diện).
  • Service Extension xử lý tải trọng trước khi hiển thị thông báo với giới hạn 30 giây, có thể thêm tệp đính kèm đa phương tiện và giải mã dữ liệu.
  • Content Extension thay thế biểu ngữ tiêu chuẩn bằng giao diện tùy chỉnh qua UIKit hoặc SwiftUI với hỗ trợ nút tương tác.
  • UNNotificationAttachment thêm hình ảnh, video và âm thanh vào thông báo, hỗ trợ các định dạng như JPEG, PNG, MP4, MP3 và các định dạng khác.
  • Đăng ký tiện ích mở rộng được thực hiện qua Info.plist với NSExtensionPointIdentifier và danh mục thông báo được chỉ định để kích hoạt.
  • Giới hạn — giới hạn bộ nhớ 50 MB, hộp cát cách ly không có quyền truy cập vào ứng dụng chính, thời gian thực thi giới hạn.
  • Notification Extension là công cụ chính để tạo thông báo người dùng phong phú, tăng cường mức độ tương tác và chức năng của truyền thông push trong iOS.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm