README.md
June 10, 2026 Β· View on GitHub
Critical Maps iOS App
What's "Critical Mass"?
Critical Mass has been described as 'monthly political-protest rides', and characterized as being part of a social movement.
http://en.wikipedia.org/wiki/Critical_Mass_(cycling)
What's this app?
This iOS app is made for Critical Maps. It tracks your location and shares it with all other participants of the Critical Mass bicycle protest.
How the App Works
Critical Maps connects cyclists during Critical Mass rides through real-time location sharing and communication.
Core Functionality
- πΊοΈ Real-time Location Tracking: Your location is shared anonymously with other riders on an interactive map
- π¬ Live Chat System: Communicate with all participants in real-time during rides
- π Next Ride Events: Discover upcoming Critical Mass events in your area
- π Social Integration: Stay connected through an integrated Mastodon feed
- π Privacy-Focused: Anonymous participation with observationmode. Additional protection through privacy zones.
- π¨ Customizable Experience: Personalize your rider appearance and app settings
Project Setup
The iOS client's logic is built in the The Composable Architecture and the UI is built in SwiftUI.
Minimum platform requirements: iOS 17.0
Architecture Overview
Modular Design Philosophy
The application follows a hyper-modularized architecture with feature modules:
Core Features:
AppFeature- Main app coordination and navigationMapFeature- Interactive map with real-time rider locationsChatFeature- Real-time messaging systemNextRideFeature- Event discovery and managementSettingsFeature- User preferences and app configurationSocialFeature- Mastodon feed integration
Supporting Modules:
ApiClient- Network layer and API communicationSharedModels- Data structures (e.g.Rider,Location,Coordinate)Styleguide- Design system and UI componentsL10n- Internationalization and localizationIDProvider- Unique identifier generation for anonymous riders
Benefits of Modularization
- Faster Build Times: Work on individual features without building the entire app
- Improved SwiftUI Previews: More stable preview environments for each feature
- Independent Development: Features can be developed and tested in isolation
- Mini-Apps: Each feature can be built as a standalone app for development
- Scalable Architecture: Easy to add new features without affecting existing code
Data Flow & State Management
The app uses TCA's unidirectional data flow:
- Actions represent user interactions and system events
- Reducers handle state mutations and side effects
- Effects manage asynchronous operations (API calls, location services)
- State is the single source of truth for each feature
Example: Location sharing flow
User enables tracking β LocationAction β LocationReducer β API Effect β State Update β UI Re-render
Getting Started
This repo contains both the client for running the entire Critical Maps application, as well as an extensive test suite.
Quick Start
- Clone the repository:
- Open the Xcode project:
CriticalMaps.xcodeproj - Run the app: Select the
Critical Mapstarget in Xcode and run (βR)
Install dependencies individually:
make bootstrap # Install Swift tools (SwiftLint, SwiftFormat, SwiftGen)
make ruby # Install Ruby dependencies (bundler, fastlane)
Assets & Code Generation
SwiftGen Integration
The project uses type-safe assets generated with SwiftGen:
# After adding new images or localization strings
make assets
This generates strongly-typed Swift code for:
- Images:
Asset.Images.iconNameinstead of"icon-name" - Localizations:
L10n.buttonSaveinstead ofNSLocalizedString
Testing
The project includes comprehensive testing across all feature modules:
Running Tests
# Run all tests
βU in Xcode
# Run specific feature tests
xcodebuild test -scheme MapFeatureTests -destination 'platform=iOS Simulator,name=iPhone 17 Pro'
Test Architecture
- Unit Tests: Logic and reducer testing with TCA's testing utilities
- Snapshot Tests: UI component visual regression testing
- Integration Tests: Feature-level behavior testing
Test Coverage by Module:
AppFeatureTests- Main app flow and navigationChatFeatureTests- Messaging functionalityMapFeatureTests- Location and map interactionsSettingsFeatureTests- User preference management- And more...
Local development with a mock server
To develop the live map against fake but realistic ride data (instead of the
production API), use the local mock server. It lives in its own repository,
criticalmaps-mock-server,
and plays back a moving cluster of riders on a Berlin loop.
There is no build dependency between the app and the server β the app only talks to it over HTTP. To use it:
- Clone and start the server (it listens on
http://localhost:8080):git clone https://github.com/mltbnz/critical-maps-mock-server cd criticalmaps-mock-server && swift run - In Xcode, select the
Critical Maps (Local)scheme and run. This build sets aDEBUG_LOCALflag (viaConfig/Debug-Local.xcconfig) so the app injects aServerConfigurationpointing at the local server with a fast poll interval β seeiOS/AppConfiguration.swift. - The boot log prints the active environment (
environment=LOCAL β¦), and the server logs each incoming request. Set the simulator location to Berlin (Simulator β Features β Location β Custom:52.515, 13.366) to see the ride.
The normal Critical Maps scheme is unaffected and always uses production.
Contribute
- Please report bugs or feature requests with GitHub issues.
- If you can code please check the build & contribute guide below.
- If you have some coins left you can help to finance the project on Open Collective.
How to contribute
In general, we follow the "fork-and-pull" Git workflow.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch. Please add your changes also to the
CHANGELOG. We're following the standard of Keep a Changelog - Push your work back up to your fork
- Submit a Pull request so that we can review your changes
Development Guidelines
- Follow the existing code style and SwiftLint rules but not a hard rule
- Write tests for new features and bug fixes
- Run
make assetsafter adding new images or localization strings - Ensure all CI checks pass before requesting review
Pre-commit Hooks
The project uses pre-commit hooks to automatically format and lint code before commits:
Manual Setup:
make install-pre-commit # Install hooks only
What runs on each commit:
- SwiftFormat - Automatically formats Swift code
- SwiftLint Auto-fix - Fixes violations that can be corrected automatically
- SwiftLint - Reports remaining violations (warnings only, won't block commits)
Note
Pre-commit hooks currently only process Swift files. Other file types (YAML, JSON, etc.) are not automatically processed.
Manual pre-commit run:
make pre-commit-run # Run on all files
pre-commit run --files changed_file.swift # Run on specific files
Notes:
- Be sure to merge the latest from "upstream" before making a pull request!
- For significant changes, consider opening an issue first to discuss the approach
- Pre-commit hooks ensure code consistency across all contributors
Open Source & Copying
CriticalMaps is licensed under the MIT License, which means you can freely use, modify, and distribute the code.
However, we kindly request that you don't republish this exact app on the App Store under your own account. Instead, we encourage you to:
- Contribute improvements back to this project
- Fork it to create something new and different
- Support the project on Open Collective
This is a community request, not a legal restriction.
Credits
Copyright & License
Copyright (c) 2025 headione - Released under the MIT license.
