I just started playing around with Clean Architecture in Android. In my app, I'd like to use a public Api for which people can get a personal Api key. I want to connect to the service using Retrofit and the users key. My app user will be responsible for providing this key.
What is a clean way of getting this data from the android components into the Retrofit component?
First thing that came to mind was using shared preferences, but that doesn't seem the right way since I'd still depend on Android / the context. Maybe I should store it some other way. Any suggestions?
(just thinking about the proper architecture for this problem)
First thing that came to mind was using shared preferences, but that doesn't seem the right way
Yes, you are right - that doesn't seem to be the right way. But not from the clean architecture perspective but from the security perspective. Let me explain:
First, clean architecture is not there to limit your dependency choices. As you said:
I'd still depend on Android / the context
That is totally right - ultimately you will depend on some concrete third-party library. But this should not concern you. What you should be concerned about is where to exactly situate that dependency.
Since clean architecture approach is supposed to separate business logic from the implementation details you should consider creating an interface to some local data storage that would define an access to the API key. Maybe something like this:
interface LocalDataManager {
fun setRemoteDataAccessKey(key: String)
fun getRemoteDataAccessKey(): String
}
An interface like this should be situated in a domain-specific application layer.
An implementation should be situated in some data-specific application layer - that layer can actually have third-party dependencies:
class LocalDataManagerImpl(
private val sharedPreferences: SharedPreferences // Android dependency
) : LocalDataManager {
...
}
Now, from the security perspective - you should probably not be using classic SharedPreferences
for sensitive data like API keys. There is an out-of-the-box library called EncryptedSharedPreferences
- you should give it a look and use it as a dependency for LocalDataManagerImpl
.
That is all I can help you right now with the information you've provided. Hopefully I've helped you to better understand how you can come about getting access to sensitive local data while sticking to the clean architecture principles.