Rewrite dev setup docs with tested, copy-pasteable instructions

Replaces the vague "Latest stable version" prerequisites in DEVELOPER.md
with concrete commands tested on a fresh macOS machine. Adds Android SDK
setup without Android Studio, documents the gen_icons_splashes.sh
requirement, and fixes the OAuth2 config to reference build_keys.conf
instead of the removed keys.dart.example. Also includes Flutter SDK
auto-migrations (iOS 13.0 min, gradle minSdk).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Doug Borg
2026-02-09 13:45:19 -07:00
parent ed38e9467c
commit 3827a6fa1d
6 changed files with 96 additions and 22 deletions

View File

@@ -800,33 +800,104 @@ The app uses a **clean, release-triggered workflow** that rebuilds from scratch
## Build & Development Setup ## Build & Development Setup
### Prerequisites ### Prerequisites
- **Flutter SDK**: Latest stable version
- **Xcode**: For iOS builds (macOS only) **macOS** (required for iOS builds; Android-only contributors can use macOS or Linux):
- **Android Studio**: For Android builds
- **Git**: For version control | Tool | Install | Notes |
|------|---------|-------|
| **Homebrew** | [brew.sh](https://brew.sh) | Package manager for macOS |
| **Flutter SDK** | `brew install --cask flutter` | Installs Flutter + Dart |
| **Xcode** | Mac App Store | Required for iOS builds |
| **CocoaPods** | `brew install cocoapods` | Required for iOS plugin resolution |
| **Android SDK** | See below | Required for Android builds |
| **Java 17+** | `brew install --cask temurin` | Required by Android toolchain (skip if already installed) |
After installing, verify with:
```bash
flutter doctor # All checks should be green
```
### Android SDK Setup (without Android Studio)
You don't need the full Android Studio IDE. Install the command-line tools and let Flutter's build system pull what it needs:
```bash
# 1. Install command-line tools
brew install --cask android-commandlinetools
# 2. Create the SDK directory and install required components
mkdir -p ~/Library/Android/sdk/licenses
# Write license acceptance hashes
printf "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > ~/Library/Android/sdk/licenses/android-sdk-license
printf "\n84831b9409646a918e30573bab4c9c91346d8abd" > ~/Library/Android/sdk/licenses/android-sdk-preview-license
# 3. Install platform tools and the SDK platform Flutter needs
/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin/sdkmanager \
--sdk_root=/Users/$USER/Library/Android/sdk \
"platform-tools" "platforms;android-36" "build-tools;35.0.0"
# 4. Copy cmdline-tools into the SDK root (Flutter expects them there)
mkdir -p ~/Library/Android/sdk/cmdline-tools
cp -R /opt/homebrew/share/android-commandlinetools/cmdline-tools/latest \
~/Library/Android/sdk/cmdline-tools/latest
# 5. Point Flutter at the SDK and accept licenses
flutter config --android-sdk ~/Library/Android/sdk
yes | flutter doctor --android-licenses
```
> **Note:** The first `flutter build apk` will auto-download additional components it needs (NDK, CMake, etc). This is normal and only happens once.
### OAuth2 Setup ### OAuth2 Setup
**Required registrations:** To run the app with working OSM authentication, register OAuth2 applications:
1. **Production OSM**: https://www.openstreetmap.org/oauth2/applications 1. **Production OSM**: https://www.openstreetmap.org/oauth2/applications
2. **Sandbox OSM**: https://master.apis.dev.openstreetmap.org/oauth2/applications 2. **Sandbox OSM**: https://master.apis.dev.openstreetmap.org/oauth2/applications
**Configuration:** For local builds, create `build_keys.conf` (gitignored):
```bash ```bash
cp lib/keys.dart.example lib/keys.dart cp build_keys.conf.example build_keys.conf
# Edit keys.dart with your OAuth2 client IDs # Edit build_keys.conf with your OAuth2 client IDs
``` ```
### iOS Setup You can also pass keys directly via `--dart-define`:
```bash ```bash
cd ios && pod install flutter run --dart-define=OSM_PROD_CLIENTID=your_id --dart-define=OSM_SANDBOX_CLIENTID=your_id
``` ```
### First Build
```bash
# 1. Install dependencies
flutter pub get
# 2. Generate icons and splash screens (gitignored, must be regenerated)
./gen_icons_splashes.sh
# 3. Build Android
flutter build apk --debug \
--dart-define=OSM_PROD_CLIENTID=your_id \
--dart-define=OSM_SANDBOX_CLIENTID=your_id
# 4. Build iOS (macOS only, no signing needed for testing)
flutter build ios --no-codesign \
--dart-define=OSM_PROD_CLIENTID=your_id \
--dart-define=OSM_SANDBOX_CLIENTID=your_id
```
> **Important:** You must run `./gen_icons_splashes.sh` before the first build. The generated icons and splash screen assets are gitignored, so the build will fail without this step.
### Running ### Running
```bash ```bash
flutter pub get # Run on connected device or simulator
./gen_icons_splashes.sh flutter run --dart-define=OSM_PROD_CLIENTID=your_id --dart-define=OSM_SANDBOX_CLIENTID=your_id
flutter run --dart-define=OSM_PROD_CLIENT_ID=[your OAuth2 client ID]
# Or use the build script (reads keys from build_keys.conf)
./do_builds.sh # Both platforms
./do_builds.sh --android # Android only
./do_builds.sh --ios # iOS only
``` ```
### Testing ### Testing

View File

@@ -92,9 +92,12 @@ A comprehensive Flutter app for mapping public surveillance infrastructure with
**Quick setup:** **Quick setup:**
```shell ```shell
flutter pub get brew install --cask flutter # Install Flutter SDK
cp lib/keys.dart.example lib/keys.dart brew install cocoapods # Required for iOS
# Add OAuth2 client IDs, then: flutter run flutter pub get # Install dependencies
./gen_icons_splashes.sh # Generate icons & splash screens (required before first build)
cp build_keys.conf.example build_keys.conf # Add your OSM OAuth2 client IDs
./do_builds.sh # Build both platforms
``` ```
**Releases**: The app uses GitHub's release system for automated building and store uploads. Simply create a GitHub release and use the "pre-release" checkbox to control whether builds go to app stores - checked for beta releases, unchecked for production releases. **Releases**: The app uses GitHub's release system for automated building and store uploads. Simply create a GitHub release and use the "pre-release" checkbox to control whether builds go to app stores - checked for beta releases, unchecked for production releases.

View File

@@ -39,7 +39,7 @@ android {
// ──────────────────────────────────────────────────────────── // ────────────────────────────────────────────────────────────
// oauth2_client 4.x & flutter_web_auth_2 5.x require minSdk 23 // oauth2_client 4.x & flutter_web_auth_2 5.x require minSdk 23
// ──────────────────────────────────────────────────────────── // ────────────────────────────────────────────────────────────
minSdk = 23 minSdk = flutter.minSdkVersion
targetSdk = 36 targetSdk = 36
// Flutter tool injects these during `flutter build` // Flutter tool injects these during `flutter build`

View File

@@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>12.0</string> <string>13.0</string>
</dict> </dict>
</plist> </plist>

View File

@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '12.0' # platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@@ -455,7 +455,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@@ -588,7 +588,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@@ -639,7 +639,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;