skip to Main Content

I am learning Swift Combine now, found quite easy video tutorial, however for some reason I get error when I try to use my enum in PassthroughSubject<Int, WeatherError>()

Check this code:

import Combine 

enum WeatherError: Error {
   case thingsJustHappen
   
}
let weatherPublisher = PassthroughSubject<Int, WeatherError>()


let subscriber = weatherPublisher
   .filter {$0 > 10}
   .sink { value in
       print("(value)")
   }

weatherPublisher.send(10)
weatherPublisher.send(30)

".filter" is highlighted and the error is:

Referencing instance method 'sink(receiveValue:)' on 'Publisher' 
requires the types 'Publishers.Filter<PassthroughSubject<Int, WeatherError>>.Failure' 
(aka 'WeatherError') and 'Never' be equivalent

Surprisingly this code works in the video tutorial. How can I make my WeatherError and Never to be equivalent???

3

Answers


  1. You need to provide both handlers, the completion one, and the value one:

    let subscriber = weatherPublisher
        .filter { $0 > 10 }
        .sink(receiveCompletion: { _ in }, receiveValue: { value in
           print("(value)")
        })
    

    This is needed because the single-argument sink, is available only for publishers that can never fail:

    extension Publisher where Self.Failure == Never {
        /// ... many lines of documentation omitted
        public func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
    }
    
    Login or Signup to reply.
  2. in Xcode 13 & iOS 15.4 this code needed brackets to compile.

    extension Publisher where Self.Failure ==  Never {
        // because the publisher can NEVER FAIL - by design!
        public  func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable {  }
    }
    
    Login or Signup to reply.
  3. It will work if you change the type to Never:

    let weatherPublisher = PassthroughSubject<Int, Never>()
    

    Or create a new Published variable:

    @Published var weather = 0
    
    let weatherPublisher = PassthroughSubject<Int, WeatherError>()
    
    let weatherSubscriber = weather
       .filter { $0 > 10 }
       .sink { print($0) }
    
    let subscriber = weatherPublisher
       .sink { [weak self] value in
           self?.weather = value
       }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search