9

The new Xcode 11 beta 4 has removed Publishers.Once struct from the Combine framework. What is the alternative?

Just seems the likely candidate, however, it cannot be used for returning a publisher in methods with return type AnyPublisher<Bool, Error> as the associated Failure type for Just is Never.

For example in the following method, I could return a Publishers.Once since the associated Failure type wasn't Never.

func startSignIn() -> AnyPublisher<Void, Error> {
    if authentication.provider == .apple { 
        let request = ASAuthorizationAppleIDProvider().createRequest()
        request.requestedScopes = [.email, .fullName]

        let controller = ASAuthorizationController(authorizationRequests: [request])
        controller.delegate = self
        controller.performRequests()

        return Publishers.Once(()).eraseToAnyPublisher()
    } else {
        return SignInManager.service.startSignIn(auth: authentication)
            .map { (auth) -> Void in
                self.authentication = auth
        }.eraseToAnyPublisher()
    }
}

But now when I change it back to Just I get a compile error complaining that Just cannot be returned since the method should return a publisher with an associated Failure type.

func startSignIn() -> AnyPublisher<Void, Error> {
    if authentication.provider == .apple { 
        let request = ASAuthorizationAppleIDProvider().createRequest()
        request.requestedScopes = [.email, .fullName]

        let controller = ASAuthorizationController(authorizationRequests: [request])
        controller.delegate = self
        controller.performRequests()

        return Just(()).eraseToAnyPublisher() //Error Here
    } else {
        return SignInManager.service.startSignIn(auth: authentication)
            .map { (auth) -> Void in
                self.authentication = auth
        }.eraseToAnyPublisher()
    }
}

Isn't there any alternative to Publishers.Once which can also have associated failure types?

Sudara
  • 4,769
  • 3
  • 34
  • 39

2 Answers2

19

In Xcode 11 beta 4, Publishers.Once was renamed Result.Publisher (where Result is part of the standard library). So write this instead:

return Result.Publisher(()).eraseToAnyPublisher()

Apple also added a publisher property to Result, which is convenient if you already have a Result:

let result: Result<Void, Error> = someFunction()
return result.publisher.eraseToAnyPublisher()
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
5

setFailureType(to:) could be a solution for some paticular cases:

return Just(()).setFailureType(to: Error.self).eraseToAnyPublisher()

But please note that Rob's answer is generally preferable. That is simpler and probably faster.

Manabu Nakazawa
  • 1,983
  • 22
  • 23