Files
SigHej/Docs/APP.md
Henrik Jess Nielsen 99e9b509a0
Some checks failed
Backend CI / test (push) Has been cancelled
Flutter CI / analyze-and-test (push) Has been cancelled
eksplicit mapping af envs
2026-05-12 18:21:25 +02:00

4.3 KiB

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):

<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):

<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

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