Weather-Sample
Introduction
Weather Sample is a simple weather app showcasing some of the material principles.
The app is multi-module, written in Kotlin using Jetpack Compose for the UI. The app consists of 3 screens, a city search screen, a weather screen for a specific city split into current weather and forecast, and a carousel of favorite cities displaying current weather and forecast for each city.
Getting set up
- Clone the project
$ git clone git@github.com:fvilarino/Weather-Sample.git
- Obtain a key from RapidApi for both the Geo Cities and the Open Weather Map
- Create a file named
keys.properties
inside thecerts
folder with your key, following this formatrapid_api_key=<your key here>
- Create a file named
release.properties
inside thecerts
folder with the release signing credentials, following this formatstore=./certs/release.keystore.jks (use your own release keystore here) alias=<you alias> storePass=<your store password> keyPass=<your key password>
- Build the project, using the following command
$ ./gradlew assembleDebug -PbuildNumber=1
Architecture
The app is split into 4 layers:
-
UI - This is the feature Layer that the user interacts with. This layer is split into 2 sections, a Feature layer that contains each app feature, and a Shared layer containing a set of ui specific utilities to be used by the features.
-
Domain - This is the business logic layer that is shared by all features.
-
Data - This layer contains the repositories providing the data to the app. This layer only contains repositories, on a more complex app we would also include a 2nd
Data Source
layer that feeds the repositories, but that additional complexity is not warranted in such a small app. -
Core - This layer contains foundational components that support all other modules in the app.
The dependencies on these layers must always point down - the UI
modules depend only on Domain
modules; Domain
modules depend only on Data
modules or other Domain
modules, Core
, being a foundational layer, can have no external dependencies, while all other layers (UI
, Domain
, Data
) can depend on Core
.
Within a layer modules are split into a public API module and a private implementation module. Only the API module is visible to other modules; this helps avoid cyclic dependencies that would be incurred if implementation modules depended on other implementation modules. At the same time, this split between Api
and Impl
improves build performance as changes to implementation details do not affect any other modules.
Deeplinks
The app can be opened to the weather and favorite screens via deeplinks, using these schemas
- weather:
weatherapp://weather/<city>/<country code>
(e.g.weatherapp://weather/vancouver/ca
) - favorites:
weatherapp://favorite
This can be exercised with this ADB command (note that the package name for debug builds ends in .dev
):
$ adb shell am start -W -a android.intent.action.VIEW -d "weatherapp://weather/vancouver/ca" com.francescsoftware.weathersample
Tech stack:
- Kotlin
- Coroutines & Flows
- Jetpack Compose
- Dependency Injection (Dagger + Anvil)
- Circuit
- Room
- Protobuf Datastore
- Retrofit
weather.mp4
License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.