Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What’s the alternative for 'Publishers.Once'?

Tags:

swift

combine

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?

like image 317
Sudara Avatar asked Jul 19 '19 04:07

Sudara


2 Answers

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()
like image 112
rob mayoff Avatar answered Oct 04 '22 14:10

rob mayoff


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.

like image 28
Manabu Avatar answered Oct 04 '22 15:10

Manabu