|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Bark is an iOS push notification tool app that allows users to send custom push notifications to their devices via HTTP requests. It leverages Apple Push Notification service (APNs) and supports advanced iOS notification features like grouping, custom icons/sounds, time-sensitive notifications, critical alerts, and end-to-end encryption. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Dependencies |
| 12 | +```bash |
| 13 | +# Install CocoaPods dependencies |
| 14 | +pod install |
| 15 | + |
| 16 | +# Always work with the workspace, not the project |
| 17 | +# Open: Bark.xcworkspace |
| 18 | +``` |
| 19 | + |
| 20 | +### Testing |
| 21 | +```bash |
| 22 | +# Run tests via fastlane |
| 23 | +bundle exec fastlane tests |
| 24 | + |
| 25 | +# Run tests via xcodebuild |
| 26 | +xcodebuild test -workspace Bark.xcworkspace -scheme Bark |
| 27 | +``` |
| 28 | + |
| 29 | +### Building |
| 30 | +```bash |
| 31 | +# Build the app |
| 32 | +xcodebuild -workspace Bark.xcworkspace -scheme Bark build |
| 33 | + |
| 34 | +# Build for TestFlight (requires proper certificates and environment variables) |
| 35 | +bundle exec fastlane beta |
| 36 | +``` |
| 37 | + |
| 38 | +## Architecture |
| 39 | + |
| 40 | +### Core Components |
| 41 | + |
| 42 | +**Main App Target (Bark/)** |
| 43 | +- Entry point: `AppDelegate.swift` - handles app lifecycle, APNs registration, Realm setup |
| 44 | +- `AppDelegate+Realm.swift` - Realm database initialization and migration logic |
| 45 | +- Realm schema version: 17 (see `RealmConfiguration.swift`) |
| 46 | + |
| 47 | +**Notification Extensions** |
| 48 | +1. `NotificationServiceExtension/` - UNNotificationServiceExtension that processes incoming notifications |
| 49 | + - `NotificationService.swift` - orchestrates notification processing through a pipeline of processors |
| 50 | + - `Processor/` directory contains specialized processors that run sequentially: |
| 51 | + - `CiphertextProcessor` - decrypts encrypted push content (must run first) |
| 52 | + - `MarkdownProcessor` - renders markdown in notification body |
| 53 | + - `LevelProcessor` - handles notification levels (active/timeSensitive/passive/critical) |
| 54 | + - `BadgeProcessor` - manages app badge count |
| 55 | + - `AutoCopyProcessor` - auto-copies content to clipboard |
| 56 | + - `ArchiveProcessor` - saves message to Realm database |
| 57 | + - `MuteProcessor` - handles group muting |
| 58 | + - `CallProcessor` - plays repeating sound for 30 seconds |
| 59 | + - `ImageProcessor` - downloads and attaches images |
| 60 | + - `IconProcessor` - sets custom notification icon (iOS 15+, runs last as it may timeout) |
| 61 | + |
| 62 | +2. `notificationContentExtension/` - custom notification UI |
| 63 | + - `NotificationViewController.swift` - displays custom content in notification |
| 64 | + |
| 65 | +### Project Structure |
| 66 | + |
| 67 | +**Model/** - Data models |
| 68 | +- `Message.swift` - Realm object for stored notifications (properties: title, subtitle, body, bodyType, url, image, group, createDate) |
| 69 | +- `MessageItemModel.swift` - view model for message display |
| 70 | +- `Algorithm.swift` - encryption/decryption algorithms for end-to-end encryption |
| 71 | + |
| 72 | +**Controller/** - View controllers using MVVM pattern |
| 73 | +- Suffix `ViewController` for views, `ViewModel` for view models |
| 74 | +- Key screens: |
| 75 | + - `HomeViewController` + `HomeViewModel` - main screen showing tutorial and test URL |
| 76 | + - `MessageListViewController` + `MessageListViewModel` - notification history grouped by date/group |
| 77 | + - `ServerListViewController` + `ServerListViewModel` - manage multiple push servers |
| 78 | + - `CryptoSettingController` + `CryptoSettingViewModel` - configure encryption keys |
| 79 | + - `SoundsViewController` + `SoundsViewModel` - manage custom notification sounds |
| 80 | + |
| 81 | +**View/** - Reusable UI components |
| 82 | +- Custom cells, buttons, text views |
| 83 | +- `View/MessageList/` - specialized views for message display with markdown support |
| 84 | + |
| 85 | +**Common/** - Shared utilities and managers |
| 86 | +- `Client.swift` - singleton managing app state, device token, current tab navigation |
| 87 | +- `ServerManager.swift` - manages multiple push servers (default: https://api.day.app) |
| 88 | +- `BarkSettings.swift` - UserDefaults wrapper for persistent settings using DefaultsKit |
| 89 | +- `RealmConfiguration.swift` - shared Realm configuration between app and extensions |
| 90 | +- `Moya/` - Network layer using Moya + RxSwift |
| 91 | + - `BarkApi.swift` - API endpoints (ping, register) |
| 92 | + - `BarkTargetType.swift` - base target type |
| 93 | + - `Observable+Extension.swift` - Rx helpers |
| 94 | + |
| 95 | +### Key Technologies |
| 96 | + |
| 97 | +- **RxSwift/RxCocoa** - Reactive programming for data binding and async operations |
| 98 | +- **Realm** - Local database for message persistence (shared between app and extensions via App Groups) |
| 99 | +- **Moya** - Network abstraction layer over Alamofire |
| 100 | +- **Material/SnapKit** - UI framework and Auto Layout DSL |
| 101 | +- **CryptoSwift** - Encryption for secure push notifications |
| 102 | +- **Kingfisher** - Image downloading and caching |
| 103 | + |
| 104 | +### Data Flow |
| 105 | + |
| 106 | +1. **Device Registration**: App requests APNs token → sends to server via `/register` endpoint → server stores device token with user's key |
| 107 | +2. **Receiving Push**: Server sends push → APNs delivers to device → `NotificationServiceExtension` processes through processor pipeline → notification displayed |
| 108 | +3. **Message Storage**: `ArchiveProcessor` saves to Realm → Darwin notification sent to main app → main app refreshes message list |
| 109 | +4. **Encryption Flow**: If ciphertext parameter present → `CiphertextProcessor` decrypts using locally stored key → continues normal processing |
| 110 | + |
| 111 | +### App Groups & Data Sharing |
| 112 | + |
| 113 | +The app uses App Groups to share data between the main app and notification extensions: |
| 114 | +- Realm database at shared Documents directory |
| 115 | +- Settings via `BarkSettings` (DefaultsKit) |
| 116 | +- Darwin notifications for cross-process communication (e.g., "com.bark.newmessage") |
| 117 | + |
| 118 | +### Server Architecture |
| 119 | + |
| 120 | +Users can configure multiple push servers (`ServerManager`): |
| 121 | +- Default server: `https://api.day.app` |
| 122 | +- Each server has: id, address, key, state, optional name |
| 123 | +- Old single-server data (pre-v1.2.6) is automatically migrated to new multi-server format |
| 124 | + |
| 125 | +### Notification Processing Pipeline |
| 126 | + |
| 127 | +Order matters - processors run sequentially in `NotificationService.swift`: |
| 128 | +1. Ciphertext decryption (must be first - may contain all push data) |
| 129 | +2. Content processing (markdown, level, badge, autoCopy) |
| 130 | +3. Database archiving |
| 131 | +4. Mute checking |
| 132 | +5. Sound effects (call mode) |
| 133 | +6. Media attachments (image, icon - icon last as it may timeout) |
| 134 | + |
| 135 | +## Important Notes |
| 136 | + |
| 137 | +- Always open `Bark.xcworkspace`, never `Bark.xcproject` |
| 138 | +- Minimum iOS deployment target: 13.0 |
| 139 | +- Realm schema migrations are handled in `RealmConfiguration.swift` - increment `schemaVersion` when changing Message model |
| 140 | +- The app supports both iPhone and iPad (with split view controller on iPad) |
| 141 | +- Localization is managed via `Localizable.xcstrings` |
| 142 | +- Custom notification sounds are in `Sounds/` directory |
| 143 | +- The app uses Material Design components for UI |
| 144 | +- Code signing is disabled for Pods (see Podfile post_install) |
| 145 | + |
| 146 | +## Testing |
| 147 | + |
| 148 | +Tests are located in `BarkTests/` directory. The CI runs tests on every push to master via GitHub Actions (`.github/workflows/tests.yaml`). |
0 commit comments