PushKit เป็นเฟรมเวิร์กของ Apple สำหรับการส่งการแจ้ง push แบบรับประกันทันที ซึ่งออกแบบมาสำหรับแอปพลิเคชัน VoIP เป็นหลัก แตกต่างจาก APNs มาตรฐาน (Apple Push Notification service) ที่อาจล่าช้าหรือถูกจัดกลุ่ม PushKit ใช้การเชื่อมต่อ TCP แบบถาวรระหว่างอุปกรณ์และเซิร์ฟเวอร์ของ Apple ตาม Apple Developer Documentation, 2026 PushKit ให้ความหน่วงในการส่งแบบครบวงจรน้อยกว่า 500 มิลลิวินาที ซึ่งสำคัญอย่างยิ่งสำหรับแอปพลิเคชันแบบเวลาจริง — การโทรด้วยเสียงและวิดีโอ
หัวข้อสำคัญ
PushKit เป็นเฟรมเวิร์กของ Apple ที่เปิดตัวใน iOS 8 ซึ่งมีกลไกการส่งการแจ้ง push แบบมีลำดับความสำคัญที่รับประกันผ่านการเชื่อมต่อถาวรกับเซิร์ฟเวอร์ APNs แตกต่างจากการแจ้งทั่วไปที่ผ่านช่องทาง APNs ช่องทางเดียวและอาจล่าช้า การแจ้ง PushKit ใช้สตรีมเฉพาะที่มีลำดับความสำคัญสูงกว่า ทำให้มั่นใจได้ว่าส่งได้ใกล้เคียงเวลาจริง
ในทางเทคนิค PushKit ทำงานผ่านการเชื่อมต่อ TCP แบบถาวรระหว่างอุปกรณ์และเซิร์ฟเวอร์ push ของ Apple เมื่อเซิร์ฟเวอร์ส่งการแจ้ง VoIP การเชื่อมต่อจะส่งไปยังอุปกรณ์ทันที ซึ่งจะปลุกแอปพลิเคชันและเรียกตัวแทน PKPushRegistry แอปพลิเคชันไม่จำเป็นต้องอยู่ในสถานะทำงาน — PushKit สามารถปลุกมันจากพื้นหลัง สถานะสิ้นสุด หรือแม้หลังจากรีสตาร์ทอุปกรณ์
ตามการวิจัยของ Microsoft Research (2024) เกี่ยวกับความหน่วงของการแจ้ง push บนแพลตฟอร์มมือถือ ค่ามัธยฐานความหน่วงของ PushKit คือ 120–350 ms ในขณะที่การแจ้ง APNs มาตรฐานมีค่ามัธยฐาน 1–5 วินาที ความแตกต่างถึงระดับหลายเท่านี้อธิบายได้ด้วยช่องทาง TCP เฉพาะและการประมวลผลแบบลำดับความสำคัญที่ฝั่ง Apple
PushKit รองรับสี่ ประเภท: VoIP (สำหรับโทรศัพท์), Complication (สำหรับข้อมูลหน้าปัดนาฬิกา), FileProvider (สำหรับซิงค์ไฟล์) และ PushToTalk (สำหรับฟังก์ชันวิทยุสื่อสาร) ตั้งแต่ iOS 13 มีเพียงประเภท VoIP เท่านั้นที่ยังคงใช้ได้อย่างกว้างขวางสำหรับนักพัฒนาบุคคลที่สาม Complication และ FileProvider มีการใช้งานเฉพาะทางและจำกัดอยู่ในระบบนิเวศของ Apple เอง
| ประเภท PushKit | วัตถุประสงค์ | ความพร้อมใช้งาน |
|---|---|---|
| VoIP | การบ่งบอกสายเข้าเสียงและวิดีโอ | iOS 8+, App Store |
| Complication | อัปเดตข้อมูลบนหน้าปัด Apple Watch | watchOS 6+ |
| FileProvider | สัญญาณเกี่ยวกับไฟล์ใหม่ใน File Provider Extension | iOS 11+, จำกัด |
| PushToTalk | ฟังก์ชันวิทยุสื่อสารในแอปพลิเคชันองค์กร | iOS 16+, การเข้าถึงจำกัด |
APNs (Apple Push Notification service) เป็นบริการส่งการแจ้ง push แบบสากลที่ทำงานผ่านช่องทางเดียวสำหรับแอปพลิเคชันทั้งหมด Apple อาจบัฟเฟอร์ จัดกลุ่ม หรือแม้แต่ทิ้งการแจ้ง APNs เมื่อช่องทางแออัด ในทางกลับกัน PushKit ใช้การเชื่อมต่อเฉพาะสำหรับแต่ละประเภทการแจ้ง และ Apple รับประกันการส่ง VoIP push ทุกครั้งโดยไม่มีการบัฟเฟอร์
ความแตกต่างจะเห็นได้ชัดเจนในสถานการณ์ที่สำคัญต่อเวลา: สายเข้าที่ส่งผ่าน APNs อาจมาพร้อมความล่าช้า 10–30 วินาที หรือไม่มาเลยหากอุปกรณ์อยู่ในโหมดประหยัดพลังงาน PushKit ส่งการแจ้งเดียวกันใน 100–500 ms โดยไม่คำนึงถึงสภาพอุปกรณ์ เพราะช่องทาง TCP ของมันถูกรักษาให้ทำงานโดยระบบด้วยลำดับความสำคัญ
| พารามิเตอร์ | PushKit | APNs |
|---|---|---|
| ประเภทการเชื่อมต่อ | TCP ถาวร (ช่องทางเฉพาะ) | ช่องทางที่ใช้ร่วมกันที่มีบัฟเฟอร์ |
| ค่ามัธยฐานความหน่วง | 120–350 ms | 1–5 วินาที |
| การปลุกแอป | เสมอ, จากทุกสถานะ | เฉพาะเมื่อแอปไม่ได้ถูกปิด |
| ขนาด Payload | สูงสุด 5 KB | สูงสุด 4 KB |
| การจัดกลุ่มของ iOS | ไม่ | ใช่ |
สถาปัตยกรรม PushKit สร้างขึ้นรอบ PKPushRegistry — วัตถุที่ลงทะเบียนแอปพลิเคชันเพื่อรับการแจ้งของประเภทเฉพาะ แอปพลิเคชันสร้างอินสแตนซ์ PKPushRegistry ระบุประเภทที่ต้องการ (เช่น PKPushTypeVoIP) และกำหนดตัวแทน หลังจากการลงทะเบียน ระบบจะรักษาการเชื่อมต่อกับ APNs โดยอัตโนมัติและส่งการแจ้ง push ผ่านตัวแทน
การแจ้งแต่ละครั้งจะแสดงโดยวัตถุ PKPushPayload ซึ่งมี dictionaryPayload พร้อมข้อมูลจากเซิร์ฟเวอร์ ขนาด payload จำกัดที่ 5 KB ซึ่งเพียงพอสำหรับการส่งข้อมูลเมตาของสาย: ตัวระบุผู้โทร, ประเภทสาย (เสียง/วิดีโอ), ชื่อผู้ติดต่อ และโทเคนเซสชัน สตรีมสื่อถูกส่งแยกต่างหากผ่าน WebRTC หรือโปรโตคอลเวลาจริงอื่น
import PushKit
class PushKitManager: NSObject {
private let pushRegistry = PKPushRegistry(queue: .main)
func configure() {
pushRegistry.delegate = self
pushRegistry.desiredPushTypes = [.voIP]
}
}
PushKit เรียกเมธอดตัวแทนเมื่อได้รับการแจ้ง ณ จุดนี้ แอปพลิเคชันต้องดึงข้อมูลจาก dictionaryPayload และแสดงสายทันทีผ่าน CallKit มิฉะนั้นระบบอาจยุติงานพื้นหลัง Apple แนะนำให้ประมวลผลให้เสร็จภายใน 30 วินาที แต่สำหรับสาย VoIP การแสดงหน้าจอสายภายในวินาทีแรกเป็นสิ่งสำคัญ
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType
) {
guard let caller =
payload.dictionaryPayload["caller"] as? String
else { return }
CallKitManager.shared.reportIncomingCall(
uuid: UUID(),
handle: caller
)
}
}
เมื่อเปิดตัว iOS 13 Apple ได้แนะนำ ข้อจำกัดที่เข้มงวด ในการใช้ PushKit นักพัฒนาได้ใช้ VoIP push อย่างแพร่หลายเป็นกลไกซ่อนเร้นสำหรับการอัปเดตแอปพื้นหลัง — การปลุกผ่าน PushKit อนุญาตให้โหลดเนื้อหา ซิงค์ข้อมูล และอัปเดตอินเตอร์เฟซโดยไม่ต้องขออนุญาตจากผู้ใช้อย่างชัดเจน Apple ถือว่านี่เป็นการละเมิดแนวคิดการประหยัดพลังงานและจำกัด PushKit เฉพาะการบ่งบอกสายเข้าเท่านั้น
ตอนนี้การแจ้ง PushKit ทุกครั้งต้องส่งผลให้แสดงสายเข้าผ่าน CallKit ทันที หากระบบตรวจพบว่า PushKit ถูกใช้เพื่อวัตถุประสงค์อื่น — เช่น การซิงค์พื้นหลังหรืออัปเดตเนื้อหาโดยไม่แสดงสาย — แอปพลิเคชันอาจถูกปฏิเสธระหว่างการตรวจสอบหรือถูกปิดใช้งานจากบริการ PushKit Apple ยังได้ลบความสามารถในการใช้ PushKit สำหรับการอัปเดตข้อมูลพื้นหลังตั้งแต่ iOS 13
การผสาน PushKit แบบเต็มรูปแบบรวมถึงการลงทะเบียน การรับโทเคน push และการจัดการการแจ้งขาเข้า PushKit ขออนุญาตส่งการแจ้งโดยอัตโนมัติ — ไม่จำเป็นต้องเรียก UNUserNotificationCenter เพิ่มเติมสำหรับ PushKit เอง แต่อาจจำเป็นสำหรับการแจ้งภายในของแอปพลิเคชัน หลังจากการลงทะเบียน ระบบจะเรียก pushRegistry:didUpdatePushCredentials เพื่อส่งโทเคน push ซึ่งต้องส่งไปยังเซิร์ฟเวอร์
extension PushKitManager: PKPushRegistryDelegate {
func pushRegistry(
_ registry: PKPushRegistry,
didUpdate pushCredentials: PKPushCredentials,
for type: PKPushType
) {
let token = pushCredentials.token
.map { String(format: "%02x", $0) }
.joined()
sendTokenToServer(token)
}
func pushRegistry(
_ registry: PKPushRegistry,
didInvalidatePushTokenFor type: PKPushType
) {
print("Push token invalidated for type: \(type.rawValue)")
}
}
ฝั่งเซิร์ฟเวอร์ส่งการแจ้ง PushKit ผ่าน APNs ด้วย push-type = voip และส่วนหัว apns-push-type: voip แตกต่างจาก APNs ทั่วไป VoIP push ใช้ใบรับรองของตัวเองและไม่ต้องกำหนดค่า topic Payload ควรมีข้อมูลขั้นต่ำสำหรับการระบุสาย
// ตัวอย่าง payload push VoIP
{
"aps": {
"alert": {}
},
"caller": "+15551234567",
"callerName": "Alice Johnson",
"sessionId": "abc-123-def",
"hasVideo": false
}
การดีบัก PushKit ซับซ้อนกว่า APNs มาตรฐานเพราะ PushKit ไม่ทำงานบนซิมูเลเตอร์ iOS จำเป็นต้องใช้ iPhone หรือ iPad จริงสำหรับการวินิจฉัย สัญญาณแรกของการทำงานที่ถูกต้องคือการเรียก pushRegistry:didUpdatePushCredentials เมื่อเริ่มต้นและการปรากฏของโทเคน push ในรูปแบบเฉพาะ (64 อักขระฐานสิบหกสำหรับ VoIP) หากไม่มีการเรียกตัวแทน ให้ตรวจสอบ entitlement ของแอปพลิเคชันของคุณ
อีกปัญหาที่พบบ่อยคือ PushKit ไม่ส่งการแจ้ง หลังจากอัปเดตแอปพลิเคชัน สิ่งนี้เกิดขึ้นเมื่อโทเคน push เปลี่ยนไป แต่เซิร์ฟเวอร์ยังคงใช้อันเก่าอยู่ วิธีแก้คือส่งโทเคนใหม่ไปยังเซิร์ฟเวอร์เมื่อเริ่มแอปพลิเคชันและลบโทเคนที่ไม่ถูกต้องเมื่อมีการเรียก pushRegistry:didInvalidatePushTokenForType Apple แนะนำให้ใช้กลไกสำรองผ่าน APNs ทั่วไปด้วย
| ปัญหา | สาเหตุ | วิธีแก้ไข |
|---|---|---|
| ไม่มีการเรียก didUpdatePushCredentials | ขาด entitlement หรือประเภทไม่ถูกต้อง | ตรวจสอบ Capabilities → Push Notifications + VoIP ใน Xcode |
| push มาช้า | อุปกรณ์อยู่ในโหมดประหยัดพลังงานหรือสัญญาณอ่อน | PushKit ไม่สามารถเลี่ยงข้อจำกัดด้านฮาร์ดแวร์ |
| ไม่ได้รับการแจ้งหลังจากเริ่มใช้ใหม่ | โทเคน push เปลี่ยนหลังจากติดตั้งแอปพลิเคชันใหม่ | ขอโทเคนใหม่และอัปเดตบนเซิร์ฟเวอร์ |
| App Store ปฏิเสธเนื่องจาก PushKit | ใช้ PushKit เพื่อวัตถุประสงค์ที่ไม่ใช่การโทร | ตรวจสอบว่าทุก push นำไปสู่ reportNewIncomingCall |
คำถามที่พบบ่อย
ในทางเทคนิคทำได้ แต่จะ ไม่มีประโยชน์ ตั้งแต่ iOS 13 การใช้งาน PushKit ที่ได้รับอนุญาตเท่านั้นคือการบ่งบอกสายเข้า ซึ่งต้องใช้ CallKit สำหรับการแสดงผล การใช้ PushKit โดยไม่มี CallKit จะส่งผลให้แอปพลิเคชันถูกปฏิเสธบน App Store
ขนาด payload สูงสุดสำหรับ PushKit คือ 5 KB (5120 ไบต์) ซึ่งมากกว่าการแจ้ง APNs ทั่วไป 1 KB ทำให้สามารถส่งข้อมูลเมตาของสายได้มากขึ้น
Apple จะ ทำให้โทเคน push ไม่ถูกต้อง โดยอัตโนมัติเมื่อลบแอปพลิเคชัน เซิร์ฟเวอร์จะได้รับการแจ้งการไม่ถูกต้องและต้องหยุดส่ง push ไปยังโทเคนนั้น การพยายามส่ง push ไปยังโทเคนที่ไม่ถูกต้องจะทำให้เกิดข้อผิดพลาด APNs 410
PushKit ใช้งานได้บน macOS 10.14+ สำหรับแอปพลิเคชัน Mac ที่สร้างด้วย Mac Catalyst หรือ AppKit ฟังก์ชันการทำงานเหมือนกับเวอร์ชัน iOS ทุกประการ รวมถึงการรองรับการแจ้ง VoIP
ใช้ การวิเคราะห์ของคุณเอง: ติดตามเวลาระหว่างการส่ง push จากเซิร์ฟเวอร์และการเรียก didReceiveIncomingPushWithPayload บนไคลเอนต์ เวลาเฉลี่ยน้อยกว่า 500 ms บ่งชี้ว่า PushKit ทำงานได้อย่างถูกต้อง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ