Skip to content
/ PushX Public

A native macOS app for testing Apple Push Notifications (APNs) and PushKit. Features JWT authentication, sandbox/production environment switching, JSON payload editor with validation, example templates, and comprehensive logging. Built with SwiftUI for macOS 14.0+

License

Notifications You must be signed in to change notification settings

g761007/PushX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PushX

Platform Swift License

🌐 English | 繁體中文


繁體中文

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+

📸 截圖

screenshot

📦 安裝

系統需求

  • 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

🔧 設定

準備 APNs 憑證

  1. 前往 Apple Developer Portal
  2. 建立一個新的 Key,勾選 Apple Push Notifications service (APNs)
  3. 下載 .p8 私鑰檔案並記下 Key ID
  4. 記下你的 Team ID(可在 Membership 頁面找到)

建立 .env 設定檔

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 檔案提交到版本控制系統!

📖 使用方式

1. 載入設定

啟動應用程式後,點擊頂部工具列的「載入 .env」按鈕,選擇或貼上你的 .env 設定檔內容。

2. 選擇推播類型

  • APNs: 一般推播通知(alert/badge/sound)
  • PushKit: VoIP 推播通知

3. 選擇環境

  • Sandbox: 開發/測試環境
  • Production: 正式環境

4. 輸入 Device Token

在 Token 輸入區塊輸入目標裝置的 Device Token(64 字元十六進位字串)。支援同時輸入多個 Token。

5. 編輯 Payload

使用內建編輯器編輯 JSON Payload,或從側邊欄選擇預設範例模板:

APNs 一般通知範例
{
  "aps": {
    "alert": {
      "title": "Hello from PushX",
      "body": "這是一則測試推播"
    },
    "badge": 1,
    "sound": "default"
  }
}
APNs 背景推播範例
{
  "aps": {
    "content-available": 1
  }
}
PushKit VoIP 範例
{
  "aps": {
    "alert": "Incoming VoIP Call"
  },
  "call": {
    "uuid": "11111111-2222-3333-4444-555555555555",
    "callerName": "John Doe",
    "isVideo": true
  }
}

6. 發送推播

點擊「發送」按鈕,推播結果會顯示在底部的日誌區塊。

🏗️ 專案架構

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 分鐘)
  • 私鑰僅在本地使用,不會上傳到任何伺服器

🐛 常見問題

Q: 推播發送失敗,顯示 "BadDeviceToken"

A: 請確認 Device Token 格式正確(64 字元十六進位),且與選擇的環境(Sandbox/Production)相符。

Q: 顯示 "InvalidProviderToken"

A: 請檢查 Team ID、Key ID 是否正確,以及私鑰是否有效。

Q: PushKit 推播沒有收到

A: 請確認:

  1. Topic 已加上 .voip 後綴
  2. App 已正確註冊 PushKit
  3. 使用正確的 PushKit Device Token

Q: 如何取得 Device Token?

A: 在你的 iOS App 中實作 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 方法,將 token 轉換為十六進位字串後複製使用。

📄 授權

本專案採用 MIT 授權條款 - 詳見 LICENSE 檔案。

🤝 貢獻

歡迎提交 Issue 和 Pull Request!


English

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.

📑 Table of Contents

✨ Features

  • 🚀 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 .env files
  • 💾 Auto-Save Settings - Automatically save and restore last used settings, tokens, and payload
  • 🎨 Modern UI - Built with SwiftUI, supports macOS 14.0+

📸 Screenshot

screenshot

📦 Installation

System Requirements

  • macOS 14.0 (Sonoma) or later
  • Xcode 15.0 or later
  • XcodeGen (for generating Xcode project)

Quick Start

# 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.sh

Or manually:

# Generate Xcode project
xcodegen

# Open the project
open PushX.xcodeproj

🔧 Configuration

Prepare APNs Certificate

  1. Go to Apple Developer Portal
  2. Create a new Key and enable Apple Push Notifications service (APNs)
  3. Download the .p8 private key file and note the Key ID
  4. Note your Team ID (found on the Membership page)

Create .env Configuration File

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 .env files containing private keys to version control!

📖 Usage

1. Load Configuration

After launching the application, click the "Load .env" button in the top toolbar to select or paste your .env configuration file content.

2. Select Push Type

  • APNs: Regular push notifications (alert/badge/sound)
  • PushKit: VoIP push notifications

3. Select Environment

  • Sandbox: Development/Testing environment
  • Production: Production environment

4. Enter Device Token

Enter the target device's Device Token (64-character hexadecimal string) in the Token input area. Multiple tokens are supported.

5. Edit Payload

Use the built-in editor to edit the JSON Payload, or select preset sample templates from the sidebar:

APNs Regular Notification Example
{
  "aps": {
    "alert": {
      "title": "Hello from PushX",
      "body": "This is a test push notification"
    },
    "badge": 1,
    "sound": "default"
  }
}
APNs Background Push Example
{
  "aps": {
    "content-available": 1
  }
}
PushKit VoIP Example
{
  "aps": {
    "alert": "Incoming VoIP Call"
  },
  "call": {
    "uuid": "11111111-2222-3333-4444-555555555555",
    "callerName": "John Doe",
    "isVideo": true
  }
}

6. Send Push

Click the "Send" button, and the push result will be displayed in the log area at the bottom.

🏗️ Project Structure

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

🔒 Security

  • 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

🐛 FAQ

Q: Push failed with "BadDeviceToken"

A: Please verify the Device Token format is correct (64-character hexadecimal) and matches the selected environment (Sandbox/Production).

Q: Shows "InvalidProviderToken"

A: Please check if Team ID, Key ID are correct, and if the private key is valid.

Q: PushKit push not received

A: Please verify:

  1. Topic has .voip suffix added
  2. App has correctly registered for PushKit
  3. Using the correct PushKit Device Token

Q: How to get Device Token?

A: Implement application(_:didRegisterForRemoteNotificationsWithDeviceToken:) in your iOS App, convert the token to hexadecimal string, and copy it for use.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🤝 Contributing

Issues and Pull Requests are welcome!


Made with ❤️ for iOS Developers

About

A native macOS app for testing Apple Push Notifications (APNs) and PushKit. Features JWT authentication, sandbox/production environment switching, JSON payload editor with validation, example templates, and comprehensive logging. Built with SwiftUI for macOS 14.0+

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published