This Android application is designed to help users locate nearby shops at a hackathon based on specific search queries like pizza, juice, and more. The app is built using Kotlin and Jetpack Compose, with a focus on Clean Architecture. It utilizes Koin for dependency injection, Ktor for networking.
The application utilizes the Foursquare API, specifically the Nearby Places API. Foursquare provides a comprehensive location platform that enables developers to access a wide range of venue data, including categories, locations, tips, etc.
The Nearby Places API allows users to search for venues near a specific location. By providing latitude and longitude coordinates, along with search queries, the API returns a list of relevant places, including their names, categories, distances, and more. This feature is essential for our App, as it enables users to discover shops in their vicinity based on their interests.
The project follows Clean Architecture, which ensures a clear separation of concerns and makes the app easy to maintain and scale. Here is a brief overview of each layer:
-
Domain Layer:
- Entities: Represents core UI models, independent of any specific implementation frameworks or libraries.
- Shop Data Source: Encapsulate application-specific business rules by interacting with the dependent functions.
-
Data Layer:
- Remote Data source: Bridge the gap between the domain layer and data sources (API) implementation of our shop data source.
- DTO: Used for mapping models for mapping and transferring data between layers, particularly from our UI layer.
- Network: Manages network operations via Ktor, communicating with the backend API.
-
Presentation Layer:
- ViewModels: Manage the state of the UI, calling data source functions and processing the results.
- UI Components: Built using Jetpack Compose for a modern, declarative UI approach.
-
DI:
- Koin: Dependency injection library for easier object management.
- Kotlin: Primary language for development.
- Jetpack Compose: Modern UI toolkit for Android.
- Ktor: HTTP client used for API calls.
- Koin: Simple dependency injection library for Kotlin and Jetpack Compose.
- StateFlow & Coroutines: For managing asynchronous data flows and state updates.
- Nearby Shops Search: Users can search for shops near their location by entering queries (e.g., "pizza", "juice").
- Clean Architecture: Follows Clean Architecture principles for separation of concerns and scalability.
- Declarative UI: Built entirely with Jetpack Compose for a modern UI experience.
- Dependency Injection: Koin is used to manage dependencies easily throughout the project.
- Efficient Networking: Ktor is used for handling network calls and querying external APIs.
For simplicity and readability, network requests are structured in a clean and minimal way using Ktor. Here's how API parameters are passed dynamically:
httpClient.get(
urlString = constructUrl("/places/nearby")
) {
header("Authorization", BuildConfig.API_KEY)
// Add query parameters dynamically
parameter("ll", "$latitude,$longitude")
parameter("query", items) // For multiple queries like "pizza,juice"
parameter("hacc", range)
}
- The
latitude
,longitude
,items
(search queries), andrange
are passed dynamically as query parameters, making the API request flexible for different searches.
shopDataSource
.getNearbyShops(
40.748817,
-73.985428,
pizza,juice",
"2000"
)
.onSuccess { shops ->
state.update {
it.copy(
isLoading = false,
shops = shops
)
}
}
.onError { error ->
_state.update { it.copy(isLoading = false) }
_events.send(ShopListEvent.Error(error))
}
-- For simplicity of the app I have hard coded the parameters
This recording showcases how users can search for nearby shops and the overall user experience.