130 lines
4.3 KiB
Markdown
130 lines
4.3 KiB
Markdown
# Mobile App — Social Proximity
|
|
|
|
## Technology Choice: Flutter
|
|
|
|
We chose **Flutter** over React Native for this project because BLE scanning requires close hardware access. Flutter compiles to native ARM code and communicates with the platform via direct platform channels — no JavaScript bridge between the app logic and the BLE hardware.
|
|
|
|
| | Flutter (chosen) | React Native |
|
|
|---|---|---|
|
|
| Language | Dart | TypeScript |
|
|
| BLE access | Platform channels — native | Via JS bridge |
|
|
| Performance | Compiles to native | JS runtime overhead |
|
|
| BLE library | `flutter_blue_plus` | `react-native-ble-plx` |
|
|
| Platforms | Android + iOS from one codebase | Same |
|
|
|
|
**Dart** is straightforward to learn if you know TypeScript: strongly typed, OOP, async/await, null safety built in.
|
|
|
|
## BLE Library: `flutter_blue_plus`
|
|
|
|
`flutter_blue_plus` is the most actively maintained Flutter BLE library. It supports:
|
|
- Scanning for nearby BLE peripherals
|
|
- Advertising as a BLE peripheral (Android 5+, iOS limited)
|
|
- Reading/writing GATT characteristics
|
|
- Connection state management
|
|
|
|
**Required permissions:**
|
|
|
|
_Android (`AndroidManifest.xml`):_
|
|
```xml
|
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
|
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
|
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
```
|
|
|
|
_iOS (`Info.plist`):_
|
|
```xml
|
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
|
<string>Used to detect nearby people with shared interests.</string>
|
|
```
|
|
|
|
## BLE Flow
|
|
|
|
```
|
|
App starts
|
|
└─► Check BLE permissions (request if missing)
|
|
└─► Generate ephemeral BLE token (UUID v4, per-session)
|
|
└─► Register token + interests with backend (POST /session)
|
|
|
|
User enables "Open to talk"
|
|
└─► Start BLE advertising (token in manufacturer data)
|
|
└─► Start BLE scanning for other tokens
|
|
└─► Open WebSocket to backend (/ws/{token})
|
|
|
|
Nearby token detected
|
|
└─► Send detected token to backend (POST /match)
|
|
└─► If match: WebSocket nudge received
|
|
└─► Display nudge card to user
|
|
|
|
User disables "Open to talk" or closes app
|
|
└─► Stop advertising + scanning
|
|
└─► Close WebSocket
|
|
└─► Session expires on backend (Redis TTL)
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
app/
|
|
├── lib/
|
|
│ ├── main.dart
|
|
│ ├── screens/
|
|
│ │ ├── onboarding_screen.dart ← Interest selection on first launch
|
|
│ │ ├── home_screen.dart ← "Open to talk" toggle + nudge display
|
|
│ │ └── settings_screen.dart ← Manage interests, reset session
|
|
│ ├── widgets/
|
|
│ │ ├── nudge_card.dart ← The nudge notification UI
|
|
│ │ ├── interest_chip.dart ← Selectable interest tag
|
|
│ │ └── open_toggle.dart ← Big friendly on/off toggle
|
|
│ ├── services/
|
|
│ │ ├── ble_service.dart ← BLE scan/advertise logic
|
|
│ │ ├── api_service.dart ← HTTP client (register, match)
|
|
│ │ └── ws_service.dart ← WebSocket client (nudge receiver)
|
|
│ └── models/
|
|
│ ├── interest.dart
|
|
│ ├── session.dart
|
|
│ └── nudge.dart
|
|
├── android/
|
|
├── ios/
|
|
└── pubspec.yaml
|
|
```
|
|
|
|
## Screens
|
|
|
|
### Onboarding (first launch)
|
|
- Choose interest categories (multi-select chips)
|
|
- Brief explanation of how the app works
|
|
- Consent acknowledgement
|
|
|
|
### Home
|
|
- Large "Open to talk" toggle — the primary interaction
|
|
- When active: scanning indicator
|
|
- Nudge card appears when a match is found
|
|
- Shows shared interests (no name, no face, no location)
|
|
- "Say hello" is just a reminder — no in-app chat
|
|
|
|
### Settings
|
|
- Manage interest categories
|
|
- Reset ephemeral identity
|
|
- Privacy information
|
|
|
|
## State Management
|
|
|
|
For MVP simplicity: use Flutter's built-in `Provider` or `Riverpod`.
|
|
Avoid complex state management (no BLoC in MVP).
|
|
|
|
## Running Locally
|
|
|
|
```bash
|
|
cd app
|
|
flutter pub get
|
|
flutter run # runs on connected device or emulator
|
|
flutter run -d android
|
|
flutter run -d ios
|
|
```
|
|
|
|
**Prerequisites:**
|
|
- Flutter SDK ≥ 3.x
|
|
- Android Studio (for Android emulator) or Xcode (for iOS simulator)
|
|
- Physical device recommended for BLE testing — emulators do not support BLE scanning
|