I am working on an Interactor file where I make decision to fetch some objects from local storage if available otherwise from remote storage. This interactor is called from ViewModel, so my data flow is like following:
ViewModel(GetCode()) >> Interactor(GetCode()-> AnyPublisher<String, Error>) >> Local/Remote Storage -> AnyPublisher<String?, Error>)
Now in interactor it will first check if the code is already in local database as following:
LocalDataSourceProvider:
func fetchCode(id: String) -> AnyPublisher<String?, Error>
If it is not present in local database(returned nil above), get it from remote database(api call) with following RemoteDataSourceProvider:
func fetchCode(id: String) -> AnyPublisher<String, Error>
How do I process above local and remote calls in my interactor method?
Updated code after making changes mentioned by Fabio:
local.fetchCode(voucherId).flatMap {
if let code = $0 {
return Just(code).eraseToAnyPublisher()
}
return remote.fetchCode(Id: Id).eraseToAnyPublisher()
}
Now I am getting following error in flatMap:
No 'flatMap' candidates produce the expected contextual result type 'AnyPublisher<String?, Error>'
Update You just need to help the compiler a bit and I didn't add all the details before.
flatMap
is what you need:
local.fetchCode(id: "id").flatMap { code -> AnyPublisher<String, Error> in
if let code = code {
return Just(code)
.mapError { $0 as Error }
.eraseToAnyPublisher()
} else {
return remote.fetchCode(id: "id")
}
}