APNS (Apple Push Notification Service) คือบริการโครงสร้างพื้นฐานของ Apple สำหรับส่งการแจ้งเตือนแบบ push ไปยังอุปกรณ์ในระบบนิเวศ: iPhone, iPad, Mac, Apple Watch และ Apple TV บริการนี้รับประกันการส่งข้อความที่เชื่อถือได้ผ่านการเชื่อมต่อ TLS ถาวรระหว่างอุปกรณ์และเซิร์ฟเวอร์ของ Apple ตาม เอกสารสำหรับนักพัฒนา Apple APNS ใช้โปรโตคอล HTTP/2 สำหรับการสื่อสารสองทางกับเซิร์ฟเวอร์แอปพลิเคชัน
ประเด็นสำคัญ
Apple Push Notification Service (APNS) คือบริการเฉพาะของ Apple สำหรับกำหนดเส้นทางการแจ้งเตือนแบบ push จากเซิร์ฟเวอร์แอปพลิเคชันไปยังอุปกรณ์ของผู้ใช้ แตกต่างจาก FCM ตรงที่ APNS ไม่รองรับ Android หรือแพลตฟอร์มอื่น ๆ — มันผูกติดกับระบบนิเวศของ Apple อย่างสมบูรณ์
บริการทำงานผ่าน การเชื่อมต่อ TLS ถาวร ที่อุปกรณ์ Apple แต่ละเครื่องสร้างขึ้นกับเซิร์ฟเวอร์ APNS เมื่อเริ่มต้นระบบ การเชื่อมต่อนี้จะถูกเก็บไว้ในพื้นหลังและใช้เพื่อส่งการแจ้งเตือนด้วยความหน่วงต่ำที่สุด
APNS จัดการโครงสร้างพื้นฐานการส่งทั้งหมด: การเข้ารหัส, การตรวจสอบสิทธิ์, การจัดลำดับความสำคัญ และการส่งซ้ำเมื่ออุปกรณ์ไม่พร้อมใช้งาน นักพัฒนาเพียงแค่ต้องให้เพย์โหลดที่มีรูปแบบถูกต้องและโทเค็น push ที่ถูกต้อง
เดิมที APNS ทำงานผ่าน โปรโตคอลไบนารี บนพอร์ต 2195–2196 ตั้งแต่ปี 2015 Apple ได้ย้ายบริการไปยังโปรโตคอล HTTP/2 ที่ทันสมัย ซึ่งรองรับการมัลติเพล็กซ์ การบีบอัดส่วนหัว และการแจ้งเตือนแบบ push จากเซิร์ฟเวอร์ HTTP/2 กลายเป็นข้อบังคับตั้งแต่เดือนมิถุนายน 2020
กระบวนการส่งการแจ้งเตือนแบบ push ผ่าน APNS ประกอบด้วยห้าขั้นตอน: การลงทะเบียนอุปกรณ์, การรับโทเค็น push, การส่งคำขอจากเซิร์ฟเวอร์, การกำหนดเส้นทาง APNS และการส่งไปยังอุปกรณ์
หากอุปกรณ์ ไม่พร้อมใช้งาน (ปิดเครื่องหรือไม่มีเครือข่าย) APNS จะเก็บข้อความล่าสุดสำหรับแต่ละแอปและส่งเมื่อการเชื่อมต่อได้รับการกู้คืน ระยะเวลาการเก็บสูงสุดคือ 4 สัปดาห์ หลังจากนั้นข้อความจะถูกลบ
Apple รองรับสองวิธีในการตรวจสอบสิทธิ์เซิร์ฟเวอร์แอปพลิเคชันเมื่อส่งการแจ้งเตือนแบบ push แต่ละวิธีมีลักษณะเฉพาะของตัวเองในด้านระยะเวลาที่มีผล การจัดการ และความสะดวกในการใช้งาน
| พารามิเตอร์ | ใช้ Token (p8) | ใช้ใบรับรอง (.p12) |
|---|---|---|
| อายุ | ไม่มีกำหนด (คีย์ไม่หมดอายุ) | จำกัดตามอายุใบรับรอง (โดยปกติ 1 ปี) |
| การหมุนเวียน | ไม่จำเป็นเว้นแต่คีย์จะถูกบุกรุก | ต้องเปลี่ยนทุกปี |
| หลายแอป | คีย์เดียวสำหรับทุกแอปในบัญชี | ใบรับรองแยกต่างหากสำหรับแต่ละแอป |
| สภาพแวดล้อม | คีย์เดียวสำหรับ Sandbox และ Production | ใบรับรองต่างกันสำหรับ Sandbox และ Production |
การตรวจสอบสิทธิ์ แบบใช้ Token เป็นวิธีที่ Apple แนะนำตั้งแต่ปี 2019 คุณสร้างคีย์ p8 หนึ่งอันใน Apple Developer Console อัปโหลดไปยังเซิร์ฟเวอร์ของคุณ และเซ็นคำขอ APNS แต่ละรายการด้วยคีย์นั้น คีย์ไม่หมดอายุและทำงานกับแอปทั้งหมดในบัญชีของคุณ
สำหรับโปรเจกต์ใหม่ การตรวจสอบสิทธิ์ แบบใช้ Token เหมาะกว่าอย่างชัดเจน: คีย์ p8 เดียวสำหรับทั้งบัญชี ไม่มีกำหนด ไม่ผูกกับสภาพแวดล้อม วิธีใช้ใบรับรอง (.p12) ยังคงใช้ในโปรเจกต์เก่า แต่ต้องเปลี่ยนทุกปีและต้องใช้ใบรับรองแยกต่างหากสำหรับ Sandbox และ Production พิจารณาวันหมดอายุของใบรับรองเมื่อวางแผน CI/CD
APNS รองรับการแจ้งเตือนแบบ push สามประเภท ซึ่งแตกต่างกันในพฤติกรรมบนอุปกรณ์และข้อกำหนดคุณสมบัติของคำขอ การเลือกประเภทขึ้นอยู่กับสถานการณ์ UX และความเร่งด่วนของข้อความ
สำหรับการแจ้งเตือน Background คุณต้องระบุคีย์ content-available: 1 และตั้งค่าลำดับความสำคัญเป็น 5 (ส่งแบบประหยัดพลังงาน) ระบบอาจจำกัดจำนวนการแจ้งเตือนพื้นหลังหากแอปไม่ประมวลผลทันเวลา
APNS รองรับค่าลำดับความสำคัญสองค่า: 10 (ส่งทันที) และ 5 (ประหยัดพลังงาน) สำหรับการแจ้งเตือนแบบ alert ใช้ 10 — ผู้ใช้ควรได้รับทันที สำหรับการแจ้งเตือนพื้นหลัง ใช้ 5 — ระบบอาจชะลอการส่งเพื่อประหยัดแบตเตอรี่ ลำดับความสำคัญที่ไม่ถูกต้องสำหรับพื้นหลังอาจทำให้ APNS ปฏิเสธ
APNS รับเพย์โหลดในรูปแบบ JSON ด้วยขนาดสูงสุด 4 KB สำหรับการแจ้งเตือนปกติและ 5 KB สำหรับ VOIP เพย์โหลดประกอบด้วยพจนานุกรม aps ที่จำเป็นพร้อมการตั้งค่าการแสดงผลและฟิลด์ที่กำหนดเองเสริม
{
"aps": {
"alert": {
"title": "ข้อความใหม่",
"body": "คุณมี 3 แชทที่ยังไม่ได้อ่าน"
},
"badge": 3,
"sound": "default",
"category": "message_category",
"thread-id": "chat_room_42"
},
"customData": {
"chatId": "42"
}
}
คีย์ thread-id จัดกลุ่มการแจ้งเตือนในศูนย์การแจ้งเตือนของ iOS คีย์ category เชื่อมโยงการแจ้งเตือนกับ UNNotificationCategory เพื่อแสดงปุ่มดำเนินการ หากไม่มีคีย์เหล่านี้ การแจ้งเตือนทั้งหมดจะแสดงทีละรายการ
นอกเหนือจากพจนานุกรม aps ที่จำเป็น เพย์โหลด APNS สามารถมีฟิลด์ที่กำหนดเองที่ระดับบนสุดได้ ฟิลด์เหล่านี้เข้าถึงได้โดยแอปผ่านพจนานุกรม userInfo เมื่อประมวลผลการแจ้งเตือน ข้อมูลที่กำหนดเองสะดวกสำหรับการส่งตัวระบุเอนทิตี หน้าจอ หรือลิงก์ ขนาดเพย์โหลดสูงสุดคือ 4 KB ดังนั้นหลีกเลี่ยงการถ่ายโอนข้อมูลปริมาณมากผ่าน push; โหลดผ่าน API หลังจากเปิดการแจ้งเตือน
ในการส่งการแจ้งเตือนแบบ push จากเซิร์ฟเวอร์ คุณต้องดำเนินการคำขอ POST ไปยังปลายทาง APNS ด้วยส่วนหัวการตรวจสอบสิทธิ์ที่ถูกต้อง ด้านล่างเป็นตัวอย่างใน Node.js ที่ใช้การตรวจสอบสิทธิ์แบบใช้ Token
const http2 = require("http2")
const fs = require("fs")
const jwt = require("jsonwebtoken")
const token = jwt.sign(
{ iss: "TEAM_ID", iat: Math.floor(Date.now() / 1000) },
fs.readFileSync("AuthKey.p8"),
{ algorithm: "ES256", keyid: "KEY_ID" }
)
const payload = JSON.stringify({
aps: { alert: { title: "สวัสดี!", body: "Push ทดสอบ" } }
})
const client = http2.connect(
"https://api.push.apple.com"
)
const req = client.request({
":method": "POST",
":path": "/3/device/DEVICE_PUSH_TOKEN",
"authorization": "bearer " + token,
"apns-push-type": "alert",
"apns-topic": "com.example.app",
"apns-priority": "10"
})
req.end(payload)
req.on("response", (headers) => {
if (headers[":status"] === 200) {
console.log("Push ถูกส่งสำเร็จ")
}
})
หลังจากส่ง APNS จะส่งคืนสถานะ HTTP 200 เมื่อส่งสำเร็จ หรือรหัสข้อผิดพลาดพร้อมคำอธิบายในเนื้อความตอบกลับ สิ่งสำคัญคือต้องจัดการข้อผิดพลาด token-unregistered (410) — โทเค็นดังกล่าวควรถูกลบออกจากเซิร์ฟเวอร์ เนื่องจากแอปถูกลบออกจากอุปกรณ์แล้ว
APNS ส่งคืนรหัสสถานะ HTTP สำหรับแต่ละคำขอส่ง การส่งสำเร็จส่งคืนสถานะ 200 ข้อผิดพลาดต้องใช้กลยุทธ์การจัดการที่แตกต่างกัน BadDeviceToken (400) หรือ Unregistered (410) — โทเค็นอุปกรณ์ล้าสมัยและควรถูกลบออกจากเซิร์ฟเวอร์ PayloadTooLarge (413) — เกินขีดจำกัด 4 KB ให้ลดเพย์โหลด
TooManyRequests (429) — เกินขีดจำกัดคำขอ APNS กำหนดโควตาสำหรับจำนวนการส่งต่อวินาที เมื่อได้รับ 429 ให้ใช้การหน่วงเวลาแบบเอกซ์โพเนนเชียล (exponential backoff) และลองใหม่ ขอแนะนำไม่เกิน 100 คำขอต่อวินาทีต่อการเชื่อมต่อ HTTP/2
ข้อผิดพลาดฝั่ง APNS — 500 และ 503 (ข้อผิดพลาดภายในเซิร์ฟเวอร์ / บริการไม่พร้อมใช้งาน) สิ่งเหล่านี้คือความล้มเหลวชั่วคราวของโครงสร้างพื้นฐานของ Apple ในกรณีดังกล่าว ให้ลองใหม่ด้วยความหน่วง 1–5 วินาที ไม่เกิน 3 ครั้ง ข้อผิดพลาด 5xx ถาวรกับเซิร์ฟเวอร์ที่ทำงานได้อย่างสมบูรณ์นั้นหายาก และมักเกี่ยวข้องกับปัญหาการเชื่อมต่อ TLS
สำหรับสภาพแวดล้อม Production ต้องแน่ใจว่าได้ implement การบันทึกข้อผิดพลาด APNS ทั้งหมด พร้อมโทเค็น รหัสข้อผิดพลาด และเวลา ซึ่งจะช่วยระบุปัญหากับใบรับรอง โควตา หรือโทเค็นอุปกรณ์เฉพาะได้อย่างรวดเร็ว ตรวจสอบวันหมดอายุของใบรับรองเป็นประจำหากคุณใช้การตรวจสอบสิทธิ์แบบใช้ใบรับรอง
คำถามที่พบบ่อย
APNS ทำงานผ่าน TCP 443 (HTTPS) สำหรับ API HTTP/2 ก่อนหน้านี้ พอร์ต 2195 และ 2196 ถูกใช้สำหรับโปรโตคอลไบนารี ตั้งแต่เดือนมิถุนายน 2020 Apple กำหนดให้ใช้ HTTP/2 บนพอร์ต 443 เท่านั้น ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ของคุณสามารถเข้าถึง api.push.apple.com ได้
Sandbox คือสภาพแวดล้อมทดสอบ APNS สำหรับดีบักการแจ้งเตือนแบบ push Production คือสภาพแวดล้อมจริงสำหรับผู้ใช้จริง ด้วยการตรวจสอบสิทธิ์แบบใช้ Token คีย์เดียวใช้ได้กับทั้งสองสภาพแวดล้อม — ปลายทางแตกต่างกัน: api.sandbox.push.apple.com หรือ api.push.apple.com
โทเค็น push สามารถเปลี่ยนได้เมื่อ: กู้คืนแอปจากสำรองข้อมูล, ติดตั้งแอปใหม่, อัปเดตระบบปฏิบัติการ, รีเซ็ตการตั้งค่าเครือข่าย โทเค็นไม่เปลี่ยนแปลง ระหว่างการอัปเดตแอปปกติผ่าน App Store เซิร์ฟเวอร์ควรจัดการข้อผิดพลาด BadDeviceToken (400) เป็นสัญญาณให้ลบโทเค็น
4 KB (4096 ไบต์) สำหรับการแจ้งเตือน alert/background ปกติ สำหรับการแจ้งเตือน VOIP ผ่าน PushKit — 5 KB (5120 ไบต์) การเกินขนาดจะส่งคืนข้อผิดพลาด PayloadTooLarge (413) ขอแนะนำให้เก็บเพย์โหลดให้น้อยที่สุดและโหลดข้อมูลเพิ่มเติมผ่านเซิร์ฟเวอร์
APNS ไม่สามารถ ส่งการแจ้งเตือนไปยังอุปกรณ์ที่ไม่มีการเชื่อมต่ออินเทอร์เน็ต หากอุปกรณ์ออฟไลน์ APNS จะเก็บข้อความล่าสุด (ต่อแอปต่ออุปกรณ์) นานถึง 28 วัน เมื่อการเชื่อมต่อถูกกู้คืน ข้อความจะถูกส่งทันที ข้อความที่เก่ากว่าจะไม่ถูกเก็บไว้
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม