ArcticPath (no.uio.ifi.in2000.team18.titanic)
Aksel Olav Steen (akselos@ifi.uio.no)
Anam Amer (anamam@ifi.uio.no)
Asantewa Kusi (asantewk@ifi.uio.no)
Ingvild Kristine Nyheim (ingvikny@ifi.uio.no)
Nora Lindflaten (noralin@ifi.uio.no)
Yrjar Vederhus (yrjarv@ifi.uio.no)
As we use the AGP 9.2.1, you need Android Studio version 2025.3.4 ("Panda
4") to compile this app.
Start by cloning the repository:
git clone https://github.uio.no/IN2000-V26/team-18/
cd team-18Then, import secrets into the project. If you've been sent this project as a zip file, it might already contain the correct secrets.
secrets.defaults.properties contains all the required fields populated with placeholder tokens.
secrets.properties is gitignored, and we override the default values with
populated info from secrets.properties
First, copy secrets.defaults.properties to secrets.properties. Then, fill in
the following secrets:
MAPBOX_ACCESS_TOKEN: Get from your Mapbox AccountDRIFTY_USER: Username for the Drifty APIDRIFTY_PASSWORD: Password for the Drifty API
This should already be set-up correctly, so no need to make any changes.
If you want to bypass the "prod" reverse proxy, either to directly communicate
with api.met.no/in2000.api.met.no or use another reverse proxy, simply
replace https://titanic.yrjar.tech as the URL in DefaultRequest in
KtorClientProvicer.kt with e.g. https://in2000.api.met.no.
Open the project in Android Studio. Gradle Project Sync should start automatically.
Then, press the "run icon" to start the app on either the emulator of your choice or a physical device.
You should only need to follow "Final steps". titanic.yrjar.tech is set up to
work correctly, and secrets.properties should be included in the project
files.
However, we still included the full instructions in order to be extra thorough.
This app requires permission to:
- Use the Internet - for API calls
- Access network state - to detect when the network is disconnected
- Access fine and coarse location - to show a "puck" at the user's location
- Default Compose project dependencies (like Compose itself, JUnit, etc)
- Android Navigation Compose library - to have a navbar and working navigation in the app
- Android ViewModel Compose library - to have ViewModels
- Kotlin testing library, Kotlin coroutines testing library - to be able to (among other things) test suspend functions
- MockK, to be able to easily mock injected dependencies when testing specific classes
- Preferences DataStore, to store user preferences
- Ktor, for all network communication (i.e. HTTP requests)
- KotlinX serialization and GSON, to deserialize JSON responses from APIs
- Several libraries from UniData, to parse NetCDF files from Drifty
- MapLibre SpatialK, for calculations on the map and to deserialize API responses into
- MapBox for the map shown in the app
- Koin for dependency injection
As the application grew, we recognized the QoL given by a DI library like
Koin. We decided on using Koin as it is less opinionated and more flexible
than Google's own Hilt-Dagger library, but is still widely used in the Android
ecosystem.
We use our own reverse proxy, hosted at titanic.yrjar.tech (158.39.75.119),
which forwards requests to in2000.api.met.no. This is because the IN2000
"proxy" (in2000.api.met.no) is a CNAME to api.met.no, and therefore wouldn't
prevent api.met.no from logging our users' IP addresses. For a
production-ready app, this would be unacceptable without a proper privacy
consent popup, but with our own non-logging reverse proxy this isn't an issue.
For testing, it might not be necessary to use the reverse proxy, as privacy is of lesser importance when testing on your own device/emulator than when real users use the app.
More technical details can be found in the proxy README file.
There is a warning in MapScreen.kt - this is due to the use of MapEffect to
show a puck on the user's location. We have been unable to find a workaround,
and it gets the job done.
Additionally, we have in several places opted-in to an experimental API. This is
because Jetpack Compose's documentation has recommended usage of said
experimental components - one example of this is in MainActivity where we
needed a TopAppBar.