A complete demonstration of iOS push notifications with a SwiftUI frontend and Vapor backend server. This project showcases how to implement push notifications with image attachments, device token management, and a notification service extension for rich content delivery.
ios-push-notification-full-stack-demo/ ├── App/ # iOS Application │ ├── PushNotifications/ # Main iOS app │ └── AttachmentNotification/ # Notification Service Extension └── Backend/ # Vapor Web Server ├── Sources/WebService/ # Server source code ├── AuthKey_XXXX.p8 # Your APNs Authentication Key └── docker-compose.yml # Docker configuration - iOS Push Notifications: Complete implementation with device token registration
- Rich Media Notifications: Support for image attachments in notifications
- Notification Service Extension: Processes and enhances notifications with media
- Token Management: RESTful API for device token storage and management
- APNs Integration: Server-side push notification delivery using APNs
- SwiftUI Frontend: Modern iOS app interface
- Vapor Backend: Swift server with PostgreSQL database
- Xcode 15.0 or later
- iOS 17.0 or later
- Apple Developer Account (for push notifications)
- Physical iOS device (push notifications don't work in simulator)
- Swift 6.0 or later
- Docker and Docker Compose
- PostgreSQL (via Docker)
- Go to Apple Developer Console
- Create or select your App ID
- Enable "Push Notifications" capability
- Create an APNs Authentication Key:
- Go to "Keys" section
- Create a new key with "Apple Push Notifications service (APNs)" enabled
- Download the
.p8file and note the Key ID and Team ID
- Add your APNs authentication key file
AuthKey_XXXX.p8toBackendfolder - Update the backend configuration with your credentials (see Backend Setup section)
- Open
App/PushNotifications/AppDelegate.swift - Update the server URL on line 47: Replace
PushNotifications.send(token: deviceToken, to: "http://YOUR_SERVER_IP:8080/token")
YOUR_SERVER_IPwith your actual server IP address. You can find your localhost IP attach from macOS network settings
-
Navigate to Backend directory:
cd Backend -
Update APNs Configuration:
- Add your APNs authentication key file
AuthKey_XXXX.p8toBackendfolder - Update the configuration in
Sources/WebService/configure.swiftwith your:- Key ID
- Team ID
- Bundle ID
- Update the name of your authentication key file
AuthKey_XXXX.p8in Dockerfile
- Add your APNs authentication key file
-
Build and start the services: Login and run docker in your Mac. Then run
docker compose up db docker compose up app
-
Verify the server is running:
- Visit
http://localhost:8080in your browser - You should see "It works!"
- Visit
-
Open the project:
open App/PushNotifications.xcodeproj
-
Configure your development team:
- Select the project in Xcode
- Go to "Signing & Capabilities"
- Select your development team
- Ensure "Push Notifications" capability is enabled
-
Build and run on a physical device:
- Connect your iOS device
- Select your device as the target
- Build and run the app (⌘+R)
- Launch the iOS app on your physical device
- Grant notification permissions when prompted
- The app will automatically register for push notifications and send the device token to your server
- Check the server logs to confirm token registration
curl -X POST http://localhost:8080/token/notify- Put the iOS app in the background or lock the device
- Send the notification using the API call above
- You should receive a push notification with:
- Title: "Hello!"
- Body: "How are you today?"
- Image attachment (downloaded and displayed by the notification service extension)
The backend provides the following RESTful endpoints:
| Method | Endpoint | Description |
|---|---|---|
GET | / | Health check - returns "It works!" |
GET | /hello | Test endpoint - returns "Hello, world!" |
POST | /token | Register a new device token |
DELETE | /token/:token | Remove a device token |
POST | /token/notify | Send push notification to all registered devices |
Register a device token:
curl -X POST http://localhost:8080/token \ -H "Content-Type: application/json" \ -d '{"token": "your_device_token_here", "debug": true}'Send notification to all devices:
curl -X POST http://localhost:8080/token/notify- MVVM Pattern: Uses SwiftUI with Observable view models
- Combine Framework: Handles reactive programming and data flow
- Notification Center: Manages push notification registration and handling
- Service Extension: Processes rich media notifications
- Vapor Framework: Swift web framework for the server
- Fluent ORM: Database abstraction layer
- PostgreSQL: Persistent storage for device tokens
- APNs Library: Apple Push Notification service integration
-
No notifications received:
- Ensure you're testing on a physical device (not simulator)
- Ensure your device is not in
Do Not Disturbmode - Check that push notifications are enabled in device settings
- Verify your APNs authentication key is correctly configured
- Check server logs for any errors
-
Token registration fails:
- Verify the server URL in
AppDelegate.swiftis correct - Ensure the backend server is running and accessible
- Check network connectivity between device and server
- Verify the server URL in
-
Docker issues:
- Ensure Docker is running
- Try
docker compose down -vto reset volumes - Check
docker compose logsfor error messages
-
Build errors:
- Clean build folder (⌘+Shift+K)
- Update dependencies:
swift package resolve - Ensure you're using the correct Swift version
- The project uses Swift 6.0 with modern concurrency features
- Push notifications require a valid Apple Developer account
- The notification service extension handles image downloads and attachment creation
- Device tokens are automatically cleaned up when they become invalid
- The backend supports both development and production APNs environments
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly on a physical device
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- The book, Push Notifications by Tutorials, by kodeco
- Built with Vapor web framework
- Uses APNs Swift library
- Inspired by iOS push notification best practices
