PushX 是一款專為 iOS/macOS 開發者設計的 macOS 原生應用程式,用於測試和除錯 Apple Push Notification service (APNs) 及 PushKit (VoIP) 推播通知。
- 🚀 支援 APNs & PushKit - 同時支援一般推播通知與 VoIP 推播
- 🔐 JWT 認證 - 使用 ES256 演算法自動生成 JWT Token
- 🌍 雙環境支援 - 輕鬆切換 Sandbox / Production 環境
- 📝 JSON 編輯器 - 內建 Payload 編輯器,支援即時 JSON 驗證
- 📋 範例模板 - 預設常用推播範例,快速開始測試
- 📊 完整日誌 - 詳細的推播結果記錄與錯誤訊息
- 🔧 .env 載入 - 支援從
.env檔案載入 APNs 設定 - 💾 自動記憶設定 - 自動儲存並恢復最後使用的設定、Token 與 Payload
- 🎨 現代化 UI - 採用 SwiftUI 打造,支援 macOS 14.0+
- macOS 14.0 (Sonoma) 或更新版本
- Xcode 15.0 或更新版本
- XcodeGen (用於生成 Xcode 專案)
# 1. Clone 專案
git clone https://github.com/your-username/PushX.git
cd PushX
# 2. 執行啟動腳本 (自動執行 xcodegen 並開啟專案)
chmod +x startup.sh
./startup.sh或手動執行:
# 生成 Xcode 專案
xcodegen
# 開啟專案
open PushX.xcodeproj- 前往 Apple Developer Portal
- 建立一個新的 Key,勾選 Apple Push Notifications service (APNs)
- 下載
.p8私鑰檔案並記下 Key ID - 記下你的 Team ID(可在 Membership 頁面找到)
APNS_TEAM_ID=YOUR_TEAM_ID
APNS_BUNDLE_ID=com.your.app.bundleid
APNS_KEY_ID=YOUR_KEY_ID
APNS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_CONTENT
-----END PRIVATE KEY-----"| 欄位 | 說明 |
|---|---|
APNS_TEAM_ID |
Apple Developer Team ID |
APNS_BUNDLE_ID |
目標 App 的 Bundle Identifier |
APNS_KEY_ID |
APNs Key ID(10 字元) |
APNS_PRIVATE_KEY |
.p8 私鑰內容(PEM 格式) |
⚠️ 注意: 請勿將包含私鑰的.env檔案提交到版本控制系統!
啟動應用程式後,點擊頂部工具列的「載入 .env」按鈕,選擇或貼上你的 .env 設定檔內容。
- APNs: 一般推播通知(alert/badge/sound)
- PushKit: VoIP 推播通知
- Sandbox: 開發/測試環境
- Production: 正式環境
在 Token 輸入區塊輸入目標裝置的 Device Token(64 字元十六進位字串)。支援同時輸入多個 Token。
使用內建編輯器編輯 JSON Payload,或從側邊欄選擇預設範例模板:
{
"aps": {
"alert": {
"title": "Hello from PushX",
"body": "這是一則測試推播"
},
"badge": 1,
"sound": "default"
}
}{
"aps": {
"content-available": 1
}
}{
"aps": {
"alert": "Incoming VoIP Call"
},
"call": {
"uuid": "11111111-2222-3333-4444-555555555555",
"callerName": "John Doe",
"isVideo": true
}
}點擊「發送」按鈕,推播結果會顯示在底部的日誌區塊。
PushX/
├── Sources/
│ ├── PushXApp.swift # App 進入點
│ ├── Models/
│ │ └── Models.swift # 資料模型定義
│ ├── Services/
│ │ ├── APNsClient.swift # APNs HTTP/2 Client
│ │ ├── DotEnvLoader.swift # .env 檔案載入器
│ │ ├── JWTTokenGenerator.swift # JWT Token 生成器
│ │ └── UserDefaultsManager.swift # 使用者設定持久化管理
│ ├── ViewModels/
│ │ ├── MainViewModel.swift # 主要 ViewModel
│ │ ├── PushPayloadViewModel.swift
│ │ └── TokenInputViewModel.swift
│ └── Views/
│ ├── ContentView.swift # 主視圖
│ ├── EditorsView.swift # 編輯器視圖
│ ├── EnvLoaderSheet.swift # .env 載入面板
│ ├── LogView.swift # 日誌視圖
│ ├── SidebarView.swift # 側邊欄視圖
│ └── TopBarView.swift # 頂部工具列
├── project.yml # XcodeGen 專案設定
├── startup.sh # 快速啟動腳本
└── ENV_LOADER_GUIDE.md # .env 載入功能指南
- JWT Token 使用 ES256 演算法簽署
- Token 快取時間為 55 分鐘(APNs 最大允許 60 分鐘)
- 私鑰僅在本地使用,不會上傳到任何伺服器
A: 請確認 Device Token 格式正確(64 字元十六進位),且與選擇的環境(Sandbox/Production)相符。
A: 請檢查 Team ID、Key ID 是否正確,以及私鑰是否有效。
A: 請確認:
- Topic 已加上
.voip後綴 - App 已正確註冊 PushKit
- 使用正確的 PushKit Device Token
A: 在你的 iOS App 中實作 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 方法,將 token 轉換為十六進位字串後複製使用。
本專案採用 MIT 授權條款 - 詳見 LICENSE 檔案。
歡迎提交 Issue 和 Pull Request!
PushX is a native macOS application designed for iOS/macOS developers to test and debug Apple Push Notification service (APNs) and PushKit (VoIP) push notifications.
- Features
- Screenshot
- Installation
- Configuration
- Usage
- Project Structure
- Security
- FAQ
- License
- Contributing
- 🚀 APNs & PushKit Support - Support both regular push notifications and VoIP push
- 🔐 JWT Authentication - Automatic JWT Token generation using ES256 algorithm
- 🌍 Dual Environment Support - Easy switching between Sandbox / Production environments
- 📝 JSON Editor - Built-in Payload editor with real-time JSON validation
- 📋 Sample Templates - Pre-built common push notification examples for quick testing
- 📊 Complete Logging - Detailed push result records and error messages
- 🔧 .env Loading - Support loading APNs settings from
.envfiles - 💾 Auto-Save Settings - Automatically save and restore last used settings, tokens, and payload
- 🎨 Modern UI - Built with SwiftUI, supports macOS 14.0+
- macOS 14.0 (Sonoma) or later
- Xcode 15.0 or later
- XcodeGen (for generating Xcode project)
# 1. Clone the project
git clone https://github.com/your-username/PushX.git
cd PushX
# 2. Run the startup script (automatically runs xcodegen and opens the project)
chmod +x startup.sh
./startup.shOr manually:
# Generate Xcode project
xcodegen
# Open the project
open PushX.xcodeproj- Go to Apple Developer Portal
- Create a new Key and enable Apple Push Notifications service (APNs)
- Download the
.p8private key file and note the Key ID - Note your Team ID (found on the Membership page)
APNS_TEAM_ID=YOUR_TEAM_ID
APNS_BUNDLE_ID=com.your.app.bundleid
APNS_KEY_ID=YOUR_KEY_ID
APNS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_CONTENT
-----END PRIVATE KEY-----"| Field | Description |
|---|---|
APNS_TEAM_ID |
Apple Developer Team ID |
APNS_BUNDLE_ID |
Target App's Bundle Identifier |
APNS_KEY_ID |
APNs Key ID (10 characters) |
APNS_PRIVATE_KEY |
.p8 private key content (PEM format) |
⚠️ Warning: Never commit.envfiles containing private keys to version control!
After launching the application, click the "Load .env" button in the top toolbar to select or paste your .env configuration file content.
- APNs: Regular push notifications (alert/badge/sound)
- PushKit: VoIP push notifications
- Sandbox: Development/Testing environment
- Production: Production environment
Enter the target device's Device Token (64-character hexadecimal string) in the Token input area. Multiple tokens are supported.
Use the built-in editor to edit the JSON Payload, or select preset sample templates from the sidebar:
{
"aps": {
"alert": {
"title": "Hello from PushX",
"body": "This is a test push notification"
},
"badge": 1,
"sound": "default"
}
}{
"aps": {
"content-available": 1
}
}{
"aps": {
"alert": "Incoming VoIP Call"
},
"call": {
"uuid": "11111111-2222-3333-4444-555555555555",
"callerName": "John Doe",
"isVideo": true
}
}Click the "Send" button, and the push result will be displayed in the log area at the bottom.
PushX/
├── Sources/
│ ├── PushXApp.swift # App entry point
│ ├── Models/
│ │ └── Models.swift # Data model definitions
│ ├── Services/
│ │ ├── APNsClient.swift # APNs HTTP/2 Client
│ │ ├── DotEnvLoader.swift # .env file loader
│ │ ├── JWTTokenGenerator.swift # JWT Token generator
│ │ └── UserDefaultsManager.swift # User settings persistence manager
│ ├── ViewModels/
│ │ ├── MainViewModel.swift # Main ViewModel
│ │ ├── PushPayloadViewModel.swift
│ │ └── TokenInputViewModel.swift
│ └── Views/
│ ├── ContentView.swift # Main view
│ ├── EditorsView.swift # Editor view
│ ├── EnvLoaderSheet.swift # .env loading panel
│ ├── LogView.swift # Log view
│ ├── SidebarView.swift # Sidebar view
│ └── TopBarView.swift # Top toolbar
├── project.yml # XcodeGen project configuration
├── startup.sh # Quick start script
└── ENV_LOADER_GUIDE.md # .env loading feature guide
- JWT Token is signed using ES256 algorithm
- Token cache duration is 55 minutes (APNs allows maximum 60 minutes)
- Private keys are used locally only and never uploaded to any server
A: Please verify the Device Token format is correct (64-character hexadecimal) and matches the selected environment (Sandbox/Production).
A: Please check if Team ID, Key ID are correct, and if the private key is valid.
A: Please verify:
- Topic has
.voipsuffix added - App has correctly registered for PushKit
- Using the correct PushKit Device Token
A: Implement application(_:didRegisterForRemoteNotificationsWithDeviceToken:) in your iOS App, convert the token to hexadecimal string, and copy it for use.
This project is licensed under the MIT License - see the LICENSE file for details.
Issues and Pull Requests are welcome!
Made with ❤️ for iOS Developers
