การแจ้งเตือนภายในคือข้อความที่แอปส่งถึงผู้ใช้โดยไม่ต้องมีเซิร์ฟเวอร์ระยะไกลเข้ามาเกี่ยวข้อง ข้อมูลทั้งหมดจะถูกประมวลผลและแสดงบนอุปกรณ์ของผู้รับโดยตรง กลไกนี้เหมาะสำหรับการเตือนความจำ ตัวจับเวลา และนาฬิกาปลุกเมื่อแอปอยู่ในพื้นหลังหรือปิดอยู่ ตาม Apple Developer Documentation UNUserNotificationCenter จัดการการแจ้งเตือนภายในบน iOS แบบรวมศูนย์
ประเด็นสำคัญ
การแจ้งเตือนภายในคือข้อความทริกเกอร์ที่สร้างและแสดงโดยระบบปฏิบัติการบนอุปกรณ์เดียวกับที่ติดตั้งแอปไว้ ต่างจากการแจ้งเตือนแบบพุช การแจ้งเตือนภายในไม่ผ่านเซิร์ฟเวอร์ภายนอก — ตรรกะการกำหนดเวลาทั้งหมดทำงานบนไคลเอ็นต์
การแจ้งเตือนเหล่านี้ทำงานโดยไม่ขึ้นกับสถานะของแอป: เปิดอยู่ ย่อเล็กสุด หรือปิดสนิท ระบบปฏิบัติการจัดการการส่งในเวลาที่กำหนด ในขณะที่นักพัฒนากำหนดเฉพาะเนื้อหาและทริกเกอร์เท่านั้น
ระบบรับประกันการส่งการแจ้งเตือนภายในแม้ไม่มีการเชื่อมต่อเครือข่าย นี่คือข้อได้เปรียบสำคัญเหนือการแจ้งเตือนแบบพุช ซึ่งต้องการการเชื่อมต่ออินเทอร์เน็ตที่เสถียรและเซิร์ฟเวอร์ที่ทำงานอยู่
การแจ้งเตือนภายในแต่ละครั้งประกอบด้วยสามส่วน: เนื้อหา (หัวเรื่อง เนื้อหา เสียง) ทริกเกอร์ (เงื่อนไขเวลาหรือตำแหน่ง) และตัวระบุคำขอ ตัวระบุช่วยให้สามารถยกเลิกหรืออัปเดตการแจ้งเตือนก่อนส่ง
นักพัฒนาสามารถกำหนดเวลาการแจ้งเตือนภายในได้สูงสุด 64 รายการต่อแอปบน iOS และไม่จำกัดจำนวนบน Android ความแตกต่างนี้เกิดจากข้อจำกัดทางสถาปัตยกรรมของระบบปฏิบัติการ
ทั้งสองแพลตฟอร์มมี API ของตนเองสำหรับทำงานกับการแจ้งเตือนภายใน บน iOS องค์ประกอบหลักคือ UNUserNotificationCenter บน Android คือ NotificationManager แม้จะมีอินเทอร์เฟซต่างกัน แต่ตรรกะเหมือนกัน: แอปสร้างคำขอ ลงทะเบียนในระบบ และระบบปฏิบัติการส่งการแจ้งเตือนในเวลาที่กำหนด
iOS ใช้ UNCalendarNotificationTrigger สำหรับเหตุการณ์ในปฏิทิน UNTimeIntervalNotificationTrigger สำหรับช่วงเวลา และ UNLocationNotificationTrigger สำหรับตำแหน่งทางภูมิศาสตร์ Android มี AlarmManager, WorkManager และการกำหนดเวลาแบบแม่นยำผ่าน setExact
ตั้งแต่ Android 12 — SCHEDULE_EXACT_ALARM ต้องการสิทธิ์พิเศษจากผู้ใช้ บน iOS จะขอสิทธิ์ครั้งเดียวผ่าน UNUserNotificationCenter.requestAuthorization และผู้ใช้เลือกระดับการเข้าถึง: แบนเนอร์ เสียง ป้าย
การแจ้งเตือนภายในถูกจำแนกตามประเภททริกเกอร์ ไม่ใช่ตามเนื้อหา แต่ละประเภทกำหนดว่าเมื่อใดและภายใต้เงื่อนไขใดที่การแจ้งเตือนจะแสดงแก่ผู้ใช้
บน iOS และ Android ประเภททริกเกอร์ถูกนำไปใช้แตกต่างกัน แม้ว่าการจำแนกเชิงตรรกะจะเหมือนกัน iOS ใช้ UNCalendarNotificationTrigger สำหรับวันที่ UNTimeIntervalNotificationTrigger สำหรับช่วงเวลา และ UNLocationNotificationTrigger สำหรับตำแหน่งทางภูมิศาสตร์ Android มี AlarmManager พร้อม setExact และ setRepeating รวมถึง WorkManager สำหรับงานที่เลื่อนออกไป
| ประเภททริกเกอร์ | คำอธิบาย | ตัวอย่าง |
|---|---|---|
| ช่วงเวลา | การแจ้งเตือนหลังจากเริ่มต้น N วินาที | ตัวจับเวลานับถอยหลัง |
| วันที่ในปฏิทิน | การแจ้งเตือนในเวลาและวันที่ระบุ | การเตือนการประชุม |
| ตำแหน่งทางภูมิศาสตร์ | การแจ้งเตือนเมื่อเข้าหรือออกจากพื้นที่ | การเตือนที่ร้านค้า |
| ทันที | ส่งทันทีเมื่อเรียก API | การแจ้งเตือนการดาวน์โหลด |
iOS ยังรองรับ UNNotificationAttachment — การแนบรูปภาพ เสียง หรือวิดีโอไปกับเนื้อหาการแจ้งเตือน Android รองรับเทมเพลตที่กำหนดเองพร้อมปุ่มและรูปภาพขนาดใหญ่ผ่าน NotificationCompat.Style
การเลือกทริกเกอร์ขึ้นอยู่กับสถานการณ์: การเตือนในปฏิทินทำงานได้ดีที่สุดกับทริกเกอร์ปฏิทิน การเตือนตามตำแหน่งกับตำแหน่งทางภูมิศาสตร์ ทริกเกอร์ช่วงเวลาเหมาะสำหรับเหตุการณ์ที่เกิดขึ้นซ้ำๆ กับช่วงเวลาที่แน่นอน
บน iOS การแจ้งเตือนภายในจะถูกส่งโดยระบบแม้เมื่อแอปปิดอยู่ — UNUserNotificationCenter จัดการคิวอย่างอิสระ บน Android การส่งขึ้นอยู่กับกลไกที่เลือก: AlarmManager ทำงานแม้ปิดหน้าจอ ในขณะที่ WorkManager คำนึงถึงการประหยัดพลังงาน
การแจ้งเตือนภายในแก้ปัญหางานที่โครงสร้างพื้นฐานภายนอกมากเกินไปหรือไม่พร้อมใช้งาน สถานการณ์หลัก: การเตือนความจำ ตัวจับเวลา คำแนะนำการเริ่มต้นใช้งาน และการดำเนินการที่เลื่อนออกไป
การวิจัยของ Localytics แสดงให้เห็นว่าแอปที่ใช้การเตือนภายในสามารถรักษาผู้ใช้ไว้ได้มากกว่า 35% ในสัปดาห์แรกหลังการติดตั้ง สิ่งนี้ทำให้การแจ้งเตือนภายในเป็นเครื่องมือเริ่มต้นใช้งานที่ทรงพลัง
สิ่งสำคัญคือไม่ใช้ความถี่มากเกินไป — ระบบจะจัดกลุ่มการแจ้งเตือนจากแอปเดียวกัน และผู้ใช้สามารถปิดการแจ้งเตือนภายในทั้งหมดหากมันน่ารำคาญ ความถี่ที่เหมาะสมคือไม่เกิน 2–3 การแจ้งเตือนต่อวันสำหรับเหตุการณ์ที่ไม่สำคัญ
ในการกำหนดเวลาการแจ้งเตือนภายในบน Android ให้ใช้ NotificationManager ร่วมกับ AlarmManager บน Android 8+ คุณต้องสร้างช่องทางการแจ้งเตือนก่อน มิฉะนั้นการแจ้งเตือนจะไม่แสดง
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+ ให้ตรวจสอบสิทธิ์ SCHEDULE_EXACT_ALARM ก่อนเรียก setExact หากไม่ได้รับสิทธิ์ — ให้ใช้ setWindow ซึ่งรับประกันการส่งภายในกรอบเวลา
เมื่อ AlarmManager ทำงาน ระบบจะส่ง Intent แบบกระจายเสียงที่ BroadcastReceiver รับ ภายในนั้น คุณต้องสร้างและแสดงการแจ้งเตือนผ่าน NotificationManager ตรวจสอบให้แน่ใจว่า PendingIntent ใช้ FLAG_UPDATE_CURRENT มิฉะนั้นการแจ้งเตือนเก่าจะยังคงใช้ Intent ที่ล้าสมัยเมื่อข้อมูลเปลี่ยนแปลง
บน iOS การแจ้งเตือนภายในถูกสร้างขึ้นผ่าน UNUserNotificationCenter โดยใช้ UNMutableNotificationContent และหนึ่งในทริกเกอร์ ก่อนกำหนดเวลา คุณต้องขอสิทธิ์จากผู้ใช้
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 เมธอด userNotificationCenter:didReceive response ของตัวแทน UNUserNotificationCenterDelegate จะถูกเรียก เมธอดนี้ให้ตัวระบุคำขอ actionIdentifier (ปุ่มใดถูกกด) และ userInfo ที่กำหนดเอง สิ่งนี้ช่วยให้แยกความแตกต่างระหว่างการเปิดการแจ้งเตือนแบบธรรมดาและการกดปุ่มดำเนินการเฉพาะ
เพื่อให้การแจ้งเตือนภายในมีประโยชน์แทนที่จะน่ารำคาญ ให้ปฏิบัติตามกฎสำคัญหลายข้อ ข้อแรก: ควบคุมความถี่ — ไม่เกิน 2–3 การแจ้งเตือนต่อวันสำหรับเหตุการณ์ที่ไม่สำคัญ มิฉะนั้นผู้ใช้จะปิดการแจ้งเตือนทั้งหมดของแอป
ข้อสอง: ให้ทางเลือกแก่ผู้ใช้ เพิ่มความสามารถในอินเทอร์เฟซในการปิดการแจ้งเตือนภายในบางประเภท บน Android ให้ใช้ NotificationChannel แยกต่างหากที่มีความสำคัญต่ำ บน iOS ให้ใช้หมวดหมู่แยกต่างหากในการตั้งค่าแอป
ข้อสาม: ความเกี่ยวข้องตามบริบท — การแจ้งเตือนควรปรากฏเมื่อผู้ใช้ต้องการ ทริกเกอร์ตำแหน่งเหมาะสำหรับการเตือนใกล้บ้าน ทริกเกอร์ปฏิทินสำหรับการประชุม ทริกเกอร์ช่วงเวลาสำหรับกิจกรรมประจำเช่นการดื่มน้ำหรือการยืดเส้น อย่าผสมประเภทโดยไม่จำเป็น
ข้อสี่: ทดสอบบนอุปกรณ์จริง โปรแกรมจำลอง iOS ไม่จำลองสถานการณ์การส่งการแจ้งเตือนภายในทั้งหมด โดยเฉพาะในพื้นหลัง บน Android ให้ใช้ adb shell dumpsys notification เพื่อตรวจสอบคิวการแจ้งเตือนที่กำหนดเวลาและพารามิเตอร์ของมัน ข้อห้า: ให้ความสามารถแก่ผู้ใช้ในการปิดการแจ้งเตือนผ่านอินเทอร์เฟซของแอปเสมอ — นี่คือข้อกำหนดบังคับของ UX และแนวทางการตรวจสอบ App Store
คำถามที่พบบ่อย
การแจ้งเตือนภายในถูกกำหนดเวลาและส่งโดยอุปกรณ์โดยไม่ต้องมีเซิร์ฟเวอร์ การแจ้งเตือนแบบพุช ต้องการบริการภายนอก (FCM, APNS) และการเชื่อมต่ออินเทอร์เน็ต การแจ้งเตือนภายในทำงานแบบออฟไลน์ การแจ้งเตือนแบบพุชทำงานเมื่อมีการเชื่อมต่อเครือข่ายเท่านั้น
iOS จำกัดที่ 64 คำขอที่กำหนดเวลาพร้อมกัน Android ไม่มีขีดจำกัดที่เข้มงวด แต่การแจ้งเตือนมากกว่า 500 รายการอาจลดประสิทธิภาพของระบบและส่งผลต่อเวลาในการส่ง
ได้ บน iOS ใช้ removePendingNotificationRequests พร้อมตัวระบุคำขอ บน Android เรียก NotificationManager.cancel หรือยกเลิก PendingIntent ผ่าน AlarmManager จำเป็นต้องมีตัวระบุที่ไม่ซ้ำกันสำหรับการยกเลิก
บน iOS ต้องขอสิทธิ์ผ่าน requestAuthorization บน Android 13+ (Tiramisu) ก็ต้องใช้สิทธิ์ POST_NOTIFICATIONS เช่นกัน Android เวอร์ชันเก่ากว่าไม่ต้องการสิทธิ์ชัดเจนสำหรับการแจ้งเตือนภายใน
บน iOS สร้าง UNNotificationAction และเพิ่มใน UNNotificationCategory บน Android ใช้ NotificationCompat.Builder.addAction พร้อม PendingIntent ที่กำหนดเป้าหมาย BroadcastReceiver แต่ละปุ่มจะเรียกการดำเนินการแยกต่างหากในแอป
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม