Notification Service Extension — วิธีการประมวลผลการแจ้งเตือนแบบพุช

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-06-16 เวลาอ่าน: 9 นาที

Notification Service Extension เป็นส่วนขยายของ iOS ที่สกัดกั้นการแจ้งเตือนแบบพุชทันทีหลังจากได้รับ แต่ก่อนที่จะแสดงให้ผู้ใช้เห็น ส่วนขยายสามารถถอดรหัสเพย์โหลดที่เข้ารหัส ดาวน์โหลดและแนบไฟล์สื่อ และเปลี่ยนแปลงข้อความหรือหัวเรื่องการแจ้งเตือนแบบเรียลไทม์ ตามเอกสารสำหรับนักพัฒนาของ Apple (2025) ในการเปิดใช้งานส่วนขยาย เซิร์ฟเวอร์ต้องส่งคีย์ mutable-content:1 ในคุณสมบัติการแจ้งเตือน — นี่เป็นเงื่อนไขเดียวในการเริ่มต้น UNNotificationServiceExtension

ประเด็นสำคัญ

  • Notification Service Extension ปรับเปลี่ยนการแจ้งเตือนแบบพุชก่อนที่จะแสดงให้ผู้ใช้เห็นบนอุปกรณ์ iOS
  • การเปิดใช้งานส่วนขยายต้องใช้พารามิเตอร์ mutable-content:1 ในเพย์โหลดการแจ้งเตือนจากเซิร์ฟเวอร์
  • โปรโตคอลหลักคือ UNNotificationServiceExtension พร้อมเมธอด didReceive(_:withContentHandler:) และ serviceExtensionTimeWillExpire()
  • ส่วนขยายสามารถดาวน์โหลด ไฟล์แนบสื่อ จากเครือข่ายและแนบไปกับการแจ้งเตือนผ่าน UNNotificationAttachment
  • เวลาดำเนินการมีจำกัด — ระบบจัดสรรประมาณ 30 วินาที สำหรับการประมวลผลการแจ้งเตือนหนึ่งรายการอย่างสมบูรณ์

Notification Service Extension คืออะไร

Notification Service Extension เป็นส่วนขยายของแอปใน iOS ที่สกัดกั้นการแจ้งเตือนแบบพุชที่ขาเข้าฝั่งอุปกรณ์และอนุญาตให้ปรับเปลี่ยนเนื้อหาก่อนที่ผู้ใช้จะเห็น นี่เป็นส่วนขยายการแจ้งเตือนประเภทเดียวที่ทำงานกับเนื้อหาแทนที่จะเป็นการแสดงผล

ความแตกต่างหลักจาก Notification Content Extension: Service Extension ทำงาน ก่อน การแสดงการแจ้งเตือนและสามารถเปลี่ยนหัวเรื่อง เนื้อหา ไฟล์เสียง และไฟล์แนบได้ Content Extension ทำงาน หลังจาก การแสดงและจัดการเฉพาะการนำเสนอด้วยภาพของการแจ้งเตือนที่เสร็จสมบูรณ์เท่านั้น ส่วนขยายทั้งสองนี้สามารถทำงานร่วมกันได้: Service Extension ดาวน์โหลดรูปภาพ และ Content Extension แสดงในอินเทอร์เฟซที่กำหนดเอง

ส่วนขยายจะเปิดใช้งานโดยอัตโนมัติเมื่อได้รับการแจ้งเตือนแบบพุชที่มีคุณสมบัติ mutable-content:1 ในพจนานุกรม aps iOS เริ่มต้นส่วนขยายในพื้นหลัง ส่ง UNNotificationRequest ดั้งเดิมให้ และรอเวอร์ชันที่ปรับเปลี่ยนแล้วเพื่อแสดง

การประมวลผลการแจ้งเตือนแบบพุชทันที

UNNotificationServiceExtension ได้รับ UNNotificationRequest เต็มรูปแบบพร้อมเนื้อหาดั้งเดิม ส่วนขยายสามารถปรับเปลี่ยนฟิลด์ใด ๆ ของ UNNotificationContent: title, subtitle, body, userInfo, attachments และ sound การเปลี่ยนแปลงจะถูกนำไปใช้ก่อนที่จะแสดงการแจ้งเตือน

สถานการณ์การใช้งานทั่วไป

การถอดรหัสเนื้อหา — หากการแจ้งเตือนแบบพุชมีเพย์โหลดที่เข้ารหัส ส่วนขยายจะถอดรหัสก่อนแสดง การดาวน์โหลดสื่อ — การแนบรูปภาพหรือวิดีโอไปกับการแจ้งเตือน การแปลภาษา — การปรับข้อความการแจ้งเตือนให้เข้ากับการตั้งค่าภูมิภาคของอุปกรณ์ การเสริมข้อมูล — การเพิ่มข้อมูลเพิ่มเติมจากพื้นที่จัดเก็บในเครื่องหรือแคช

ตามข้อมูลของ Apple สถานการณ์ที่พบบ่อยที่สุดในแอปคือ การดาวน์โหลดรูปภาพ สำหรับการแจ้งเตือนสื่อสมบูรณ์ เซิร์ฟเวอร์ส่ง URL รูปภาพในเพย์โหลด ส่วนขยายดาวน์โหลดไปยังไดเรกทอรีชั่วคราวและสร้าง UNNotificationAttachment ซึ่งระบบจะแสดงในอินเทอร์เฟซมาตรฐานหรือกำหนดเอง

การปรับเปลี่ยนข้อความและหัวเรื่อง

ส่วนขยายสามารถเขียนข้อความการแจ้งเตือนใหม่ทั้งหมด เปลี่ยนหัวเรื่อง หรือเพิ่มหัวเรื่องย่อย ตัวอย่างเช่น แอปส่งข้อความสามารถรับการแจ้งเตือนที่เข้ารหัส ถอดรหัสในส่วนขยาย และแสดงข้อความที่อ่านได้ หรือแอปข่าวสามารถเพิ่มหมวดหมู่ข่าวลงในหัวเรื่องย่อยก่อนแสดง

swift
override func didReceive(
    _ request: UNNotificationRequest,
    withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
    let content = request.content.mutableCopy()
        as! UNMutableNotificationContent
    if let imageURL = content.userInfo["media-url"]
        as? String {
        downloadAndAttach(imageURL: imageURL,
            content: content,
            handler: contentHandler)
    }
}

โปรโตคอล UNNotificationServiceExtension

UNNotificationServiceExtension เป็นคลาสพื้นฐานที่ Service Extension สืบทอด คลาสกำหนดเมธอดวงจรชีวิตสองแบบ: didReceive(_:withContentHandler:) — เมธอดการประมวลผลหลัก และ serviceExtensionTimeWillExpire() — ตัวจัดการการหมดเวลา

เมธอด didReceive:withContentHandler:

didReceive(_:withContentHandler:) ถูกเรียกเมื่อได้รับการแจ้งเตือน ส่วนขยายได้รับ UNNotificationRequest และคลอเชอร์ contentHandler ซึ่งต้องเรียกด้วย UNMutableNotificationContent ที่ปรับเปลี่ยนแล้ว ส่วนขยายมีหน้าที่เรียก contentHandler — หากไม่เรียก iOS จะแสดงการแจ้งเตือนดั้งเดิมหลังจากหมดเวลา

สำคัญ: ส่วนขยายสามารถประมวลผลได้เพียงหนึ่งการแจ้งเตือนในแต่ละครั้ง หากมีการแจ้งเตือนหลายรายการมาพร้อมกัน iOS จะสร้างอินสแตนซ์ส่วนขยายแยกต่างหากสำหรับแต่ละรายการ ไม่สามารถใช้สถานะส่วนกลางสำหรับการประมวลผลตามลำดับได้

เมธอด serviceExtensionTimeWillExpire:

serviceExtensionTimeWillExpire() ถูกเรียกโดยระบบเมื่อเวลาดำเนินการที่เหลืออยู่ใกล้จะหมด ในเมธอดนี้ คุณต้องเรียก contentHandler ทันทีด้วยเนื้อหาใด ๆ ที่พร้อมในขณะนั้น — แม้ว่าไฟล์สื่อจะยังดาวน์โหลดไม่เสร็จก็ตาม หากคุณไม่เรียก contentHandler ในเมธอดนี้ iOS จะแสดงการแจ้งเตือนดั้งเดิม

แนะนำให้บันทึกเนื้อหาที่ยอมรับได้น้อยที่สุดในเมธอดนี้ — ตัวอย่างเช่น การแจ้งเตือนที่มีข้อความและหัวเรื่อง แต่ไม่มีรูปภาพที่การดาวน์โหลดไม่เสร็จทันเวลา

การเข้ารหัสและไฟล์แนบสื่อ

UNNotificationAttachment เป็นออบเจ็กต์ที่สร้างโดยส่วนขยายเพื่อแนบไฟล์สื่อไปกับการแจ้งเตือน ส่วนขยายดาวน์โหลดไฟล์จากเครือข่าย บันทึกลงในไดเรกทอรีชั่วคราว และสร้าง UNNotificationAttachment พร้อมระบุประเภทเนื้อหา

การสร้างไฟล์แนบจากไฟล์ที่ดาวน์โหลด

UNNotificationAttachment ถูกสร้างโดยใช้ตัวเริ่มต้น init(identifier:url:options:) URL ต้องชี้ไปยังไฟล์ภายในเครื่องในไดเรกทอรีชั่วคราวที่ส่วนขยายสามารถเข้าถึงได้ หลังจากสร้าง ไฟล์แนบจะถูกเพิ่มไปยังอาร์เรย์ attachments ของ UNMutableNotificationContent

Apple แนะนำให้ใช้ URLSession พร้อมการกำหนดค่าพื้นหลังสำหรับการดาวน์โหลด — เมื่อใช้ URLSession มาตรฐาน การดาวน์โหลดจะบล็อกเธรดและใช้เวลาจากขีดจำกัด 30 วินาที URLSession พื้นหลังจะดาวน์โหลดต่อแม้เมื่อส่วนขยายสิ้นสุดลง และผลลัพธ์สามารถใช้ได้ในการเริ่มต้นครั้งต่อไป

การถอดรหัสเพย์โหลดที่เข้ารหัส

หากเซิร์ฟเวอร์ส่งการแจ้งเตือนที่เข้ารหัส ส่วนขยายต้องถอดรหัสเพย์โหลดก่อนเรียก contentHandler การถอดรหัสมักเกี่ยวข้องกับการขอคีย์จาก Keychain หรือ App Group การถอดรหัสผ่าน CommonCrypto และการแทนที่ body หรือ userInfo ของการแจ้งเตือน ในกรณีที่เกิดข้อผิดพลาดในการถอดรหัส คุณควรเรียก contentHandler ด้วยเนื้อหาดั้งเดิม — เพื่อให้ผู้ใช้อย่างน้อยเห็นว่ามีการแจ้งเตือนมา แม้จะอ่านไม่ได้

swift
func downloadAndAttach(
    imageURL: String,
    content: UNMutableNotificationContent,
    handler: @escaping (UNNotificationContent) -> Void
) {
    let task = URLSession.shared.dataTask(with:
        URL(string: imageURL)!) { data, _, _ in
        let url = FileManager.default
            .temporaryDirectory
            .appendingPathComponent("image.jpg")
        try? data?.write(to: url)
        let attachment = try? UNNotificationAttachment(
            identifier: "image", url: url)
        content.attachments = [attachment].compactMap { $0 }
        handler(content)
    }
    task.resume()
}

การหมดเวลาและกลไกสำรอง

Notification Service Extension ทำงานภายใต้กรอบเวลาที่เข้มงวด iOS จัดสรรเวลาดำเนินการคงที่ — ประมาณ 30 วินาที นับจากการเปิดใช้งาน หากส่วนขยายไม่ได้เรียก contentHandler ภายในเวลานี้ ระบบจะบังคับสิ้นสุดกระบวนการและแสดงการแจ้งเตือนดั้งเดิมโดยไม่เปลี่ยนแปลง

กลยุทธ์การลดประสิทธิภาพอย่างค่อยเป็นค่อยไป

แนะนำให้ใช้กลไกสำรองหลายระดับ: ก่อนอื่นลองดาวน์โหลดสื่อ หากสำเร็จให้เรียก contentHandler ด้วยเนื้อหาเต็ม หากล้มเหลวให้เรียก contentHandler ด้วยข้อความแต่ไม่มีสื่อ หากเกิดข้อผิดพลาดร้ายแรงให้ส่งเนื้อหาดั้งเดิม วิธีการนี้รับประกันว่าผู้ใช้จะเห็นการแจ้งเตือนเสมอ ไม่ใช่หน้าจอว่างเปล่า

ตามข้อมูลของ Apple สาเหตุที่พบบ่อยที่สุดของการหมดเวลาคือ การดาวน์โหลดไฟล์สื่อขนาดใหญ่ ผ่านการเชื่อมต่อที่ช้า เพื่อลดความเสี่ยง แนะนำให้ปรับขนาดรูปภาพบนเซิร์ฟเวอร์ให้เหมาะสม — ส่งตัวอย่างสูงสุด 300 KB แทนความละเอียดเต็ม รูปภาพขนาดเต็มควรดาวน์โหลดเมื่อเปิดแอป

การตรวจสอบประสิทธิภาพ

เพื่อติดตามการหมดเวลาและข้อผิดพลาดของส่วนขยาย คุณสามารถใช้ os_log เพื่อบันทึกข้อความวินิจฉัยในระบบบันทึกแบบรวม แม้ว่าการบันทึกไฟล์โดยตรงในส่วนขยายจะทำได้ยาก แต่ os_log ช่วยให้วิเคราะห์ประสิทธิภาพผ่าน Console.app บนอุปกรณ์ของนักพัฒนา Apple แนะนำให้เพิ่มเมตริกในทุกการเรียก didReceive — เวลาดาวน์โหลด ขนาดไฟล์ ผลลัพธ์การดำเนินการ

swift
override func serviceExtensionTimeWillExpire() {
    let fallback = bestEffortContent as?
        UNMutableNotificationContent
        ?? request.content.mutableCopy()
        as! UNMutableNotificationContent
    contentHandler(fallback)
}

คำถามที่พบบ่อย

เซิร์ฟเวอร์เปิดใช้งาน Notification Service Extension อย่างไร?

เซิร์ฟเวอร์เพิ่มคีย์ mutable-content:1 ลงในพจนานุกรม aps ของการแจ้งเตือนแบบพุช หากไม่มีพารามิเตอร์นี้ ระบบจะละเว้นส่วนขยายและแสดงการแจ้งเตือนมาตรฐาน

สามารถใช้ส่วนขยายโดยไม่มี mutable-content ได้หรือไม่?

ไม่ได้ mutable-content:1 เป็นเงื่อนไขบังคับสำหรับการเปิดใช้งาน Service Extension หากคีย์หายไปหรือตั้งค่าเป็น 0 การแจ้งเตือนจะแสดงโดยไม่เรียกส่วนขยาย

เกิดอะไรขึ้นเมื่อเกินขีดจำกัด 30 วินาที?

iOS บังคับสิ้นสุดส่วนขยายและแสดง การแจ้งเตือนดั้งเดิม โดยไม่เปลี่ยนแปลง เพื่อหลีกเลี่ยงนี้ ให้ใช้ serviceExtensionTimeWillExpire() ด้วยเนื้อหาที่ยอมรับได้น้อยที่สุด

จะส่งคีย์การเข้ารหัสไปยังส่วนขยายได้อย่างไร?

ผ่าน App Group (UserDefaults หรือไฟล์ที่ใช้ร่วมกัน) หรือ Keychain ที่มีการเข้าถึงร่วมกันระหว่างแอปและส่วนขยาย การส่งคีย์โดยตรงในเพย์โหลดการแจ้งเตือนไม่ปลอดภัย

สามารถแนบไฟล์สื่อได้กี่ไฟล์ใน Service Extension?

สูงสุด 4 ไฟล์แนบ ต่อการแจ้งเตือน แต่ละไฟล์สูงสุด 50 MB ขนาดรวมของไฟล์แนบส่งผลต่อเวลาดาวน์โหลด — ยิ่งมีไฟล์มาก ความเสี่ยงในการหมดเวลาก็ยิ่งสูงขึ้น

สรุป

  • Notification Service Extension ปรับเปลี่ยนการแจ้งเตือนแบบพุชบนอุปกรณ์ก่อนแสดง โดยเปลี่ยนข้อความ หัวเรื่อง และไฟล์แนบสื่อ
  • การเปิดใช้งานต้องใช้คีย์ mutable-content:1 ในพจนานุกรม aps — หากไม่มี ส่วนขยายจะไม่เริ่มทำงาน
  • โปรโตคอลหลัก UNNotificationServiceExtension กำหนดเมธอด didReceive และ serviceExtensionTimeWillExpire สำหรับการประมวลผล
  • ส่วนขยายสามารถดาวน์โหลดสื่อจากเครือข่าย ถอดรหัสเพย์โหลด และเพิ่ม 4 ไฟล์แนบ สูงสุดในการแจ้งเตือน
  • เวลาดำเนินการจำกัดอยู่ที่ประมาณ 30 วินาที — หากเกิน iOS จะแสดงการแจ้งเตือนดั้งเดิม
  • แนะนำกลยุทธ์การลดประสิทธิภาพอย่างค่อยเป็นค่อยไปพร้อมกลไกสำรองหลายระดับเพื่อป้องกันการแจ้งเตือนที่ว่างเปล่า

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม