Search code examples
iosswiftcombine

conditionally combine anypublisher


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>'


Solution

  • 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")
      }
    }