Womble
Womble

Reputation: 5290

Convert Subject/Publisher to another Publisher

Given an existing CurrentValueSubject instance, the goal is to create a new Publisher that will take the subject's stream of Strings, and in turn will output Ints.

My approach is to map the subject to AnyPublisher:

let subject: CurrentValueSubject<String, Never> = ...

func intPublisher() -> AnyPublisher<Int, Never>
{
    return subject.map { string in
        let value = Int(string) ?? 0
        return AnyPublisher<Int, Never>(value) // Error: Generic parameter P could not be inferred.
    }
}

However, I cannot create a new AnyPublisher this way. Clearly, my understanding of Publishers is flawed. Could someone please enlighten me?

Upvotes: 0

Views: 1780

Answers (1)

New Dev
New Dev

Reputation: 49590

You're just a bit off.

.map maps values, so you need to return a new value, not a new publisher. Then use .eraseToAnyPublisher to create the AnyPublisher publisher:

func intPublisher() -> AnyPublisher<Int, Never> {
   subject.map { Int($0) ?? 0 }
          .eraseToAnyPublisher()
}

You can also use AnyPublisher(subject.map { Int($0) ?? 0 }) as well (the init parameter is a publisher, not a value).


For completeness, you can return a publisher for each value, but then you'd need to use a flatMap. The following achieves the same result as above, but just in an unnecessarily convoluted way:

subject.flatMap { string in
      Just( Int(string) ?? 0 )
   }.eraseToAnyPublisher()

Upvotes: 4

Related Questions