|
||
---|---|---|
.idea | ||
app | ||
build-logic | ||
core/ui | ||
data | ||
feature | ||
gradle | ||
.gitignore | ||
build.gradle.kts | ||
gradle.properties | ||
gradlew | ||
gradlew.bat | ||
README.md | ||
settings.gradle.kts |
Description of the Recruitment Task
Introduction
The provided solution is a Proof Of Concept (PoC) and not a final, ideal solution. The code was created to demonstrate my style of working and approach to developing applications and system architecture. Certainly, there are areas in the code that require improvement and optimization.
Getting API key
To fully test the functionality of this code, you need to obtain a free API key from: https://pixabay.com/.
Then pass this API key as the BuildConfig
value in the data
module.
defaultConfig {
...
defaultConfig {
buildConfigField("String", "PIXABAY_API_KEY", "\"<REPLACE_WITH_PIXABAY_API_KEY>\"")
}
}
Areas for Improvement
- API Key Security:
The API is stored in BuildConfig
, which is extremely dangerous. For the purposes of this task, I assumed it would simplify testing and verification of the application. In a real project, the API key would be stored securely, such as in environment variables.
- Lack of Unit and UI Tests:
I completely omitted unit tests and UI tests. However, if you are interested, I can provide code snippets from other projects where such tests have been implemented. I am aware that testing is a key element in the software development process, and in production code, I would ensure appropriate test coverage.
- No Theme Created for the Application:
I did not create a Theme
for the application, although I recognize that this is an area worth dedicating time to. Proper preparation of shape
, color
, and typography
can significantly facilitate the creation of a cohesive application in the future.
- Error Handling on the Details Screen:
On the details screen, I completely omitted error handling for API communication, and in some areas, error handling is general and simplified. I believe that for the purposes of this task, it is sufficient to ensure stable operation.
- Cache for API Responses:
Adding caching for API responses could improve the application's performance and reduce the number of requests to the server.
- Receiving and Storing Data from the API:
I prepared two solutions:
-
The first is a
Pager
that fetches data and displays it on the screen. The ViewModel temporarily stores it in memory, but it is not a long-term cache. -
The second is a
Pager
withRemoteMediator
, where the single source of truth for data is the local Room database, and data fetched from the API is stored there before being displayed on the screen. This allows the application to work offline. However, to work correctly, the order of elements received from the API should be consistent with the order of elements in the local database. Unfortunately, the API has very limited sorting capabilities, so the second pager option is added more as a curiosity than a perfectly functioning solution. To try it out, you need to change the flagconst val USE_CACHE_PAGER = false
.
Style and Architecture
The code was written with readability and modularity in mind. I aimed to apply good programming practices and design patterns wherever possible. In my work, I strive to create code that is easy to maintain and develop by other programmers.
Summary
Despite some simplifications and shortcomings, I hope this solution provides a good insight into my working style and approach to designing applications. I am happy to answer any questions about the code and provide code snippets from other projects that demonstrate my skills.