PushLab é um aplicativo nativo macOS desenvolvido em SwiftUI para testar e enviar push notifications durante o desenvolvimento. Clone do QuickPush Tool.
PushLab permite que desenvolvedores mobile testem push notifications via:
- Expo - Notificações para apps React Native/Expo
- Live Activity - Atualizações de Live Activities (iOS)
- APNs - Apple Push Notification service
- FCM - Firebase Cloud Messaging
- ✅ Expo Notification - Envio via API do Expo (exp.host)
- ✅ Live Activity - Start, Update e End de Live Activities
- ✅ APNs Nativo - Envio direto via Apple Push Notification service
- ✅ FCM Nativo - Firebase Cloud Messaging
- ✅ Saved Tokens - Salvar e reutilizar tokens com labels customizadas
- ✅ Response Viewer - Painel de resposta mostrando status HTTP e JSON
- ✅ cURL Export - Gerar comando cURL completo do payload
- ✅ Keyboard Shortcuts - ⌘+Enter para enviar, ⌘1-4 para navegar entre abas
- ✅ Custom Data - Adicionar key-value pairs arbitrários ao payload
PushLab/
├── Models/
│ ├── SavedToken.swift # Modelo de tokens salvos
│ └── PushPayload.swift # Modelos de payload (Expo, APNs, FCM, LiveActivity)
├── Services/
│ ├── KeychainService.swift # Gerenciamento de credenciais sensíveis
│ └── PushService.swift # HTTP client para APIs de push
├── ViewModels/
│ ├── ExpoViewModel.swift
│ ├── APNsViewModel.swift
│ ├── LiveActivityViewModel.swift
│ └── FCMViewModel.swift
├── Modules/
│ ├── ExpoView.swift
│ ├── APNsView.swift
│ ├── LiveActivityView.swift
│ └── FCMView.swift
├── Components/
│ ├── TokenRow.swift # Componente de token salvo
│ ├── ResponsePanel.swift # Painel de resposta
│ └── CURLModal.swift # Modal de cURL
├── ContentView.swift # View principal com tabs
└── PushLabApp.swift # Entry point
- Framework: SwiftUI
- Persistência: SwiftData (tokens) + Keychain (credenciais sensíveis)
- Network: URLSession com async/await
- Pattern: MVVM com @Observable
- Target: macOS 13+ (Ventura)
⌘1- Aba Expo Notification⌘2- Aba Live Activity⌘3- Aba APNs⌘4- Aba FCM⌘↵- Enviar push notification
- Cole o(s) ExponentPushToken(s) no campo de tokens
- Preencha título, corpo e prioridade
- (Opcional) Adicione custom data com key-value pairs
- Clique em "Send Push" ou pressione ⌘↵
- Cole o device token
- Configure Bundle ID, Team ID, Key ID
- Carregue o arquivo .p8 key
- Selecione ambiente (Sandbox/Production)
- Preencha o conteúdo da notificação
- Envie com ⌘↵
- Cole o activity token
- Configure APNs (Bundle ID, Team ID, Key ID, .p8)
- Escolha o evento (Update/End)
- Adicione content state key-value pairs
- Envie com ⌘↵
- Cole o FCM registration token
- Adicione o server key/OAuth token
- Configure título, corpo e settings Android
- Adicione custom data se necessário
- Envie com ⌘↵
Em qualquer aba:
- Preencha o campo de token
- Clique em "Save Token"
- Digite um label (ex: "iPhone 17 Pro")
- Use o ícone de seta para aplicar o token salvo
- Tokens salvos são armazenados via SwiftData
- Credenciais sensíveis (.p8 keys, access tokens) podem ser armazenadas no Keychain
- Arquivos .p8 são carregados via NSOpenPanel (sandbox-safe)
- Floating pinned window (NSPanel)
- Launch at Login (SMAppService)
- Advanced settings por plataforma
- Histórico de envios
- Temas
- Export/import de tokens
- Templates de payload
- Múltiplos workspaces
A implementação atual do JWT para APNs é um placeholder. Para produção, é necessário implementar ES256 signing usando CryptoKit:
import CryptoKit
// Carregar a chave .p8
let p8Key = try P256.Signing.PrivateKey(pemRepresentation: p8KeyString)
// Gerar JWT com ES256
let header = ["alg": "ES256", "kid": keyId]
let claims = ["iss": teamId, "iat": timestamp]
// ... signing logicO app usa a nova FCM HTTP v1 API. A URL precisa incluir o project ID correto:
https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send
Projeto desenvolvido como clone do QuickPush Tool para fins de aprendizado.
Desenvolvido com ❤️ usando SwiftUI