首页 > 解决方案 > 订阅返回 Void 而不是 AnyCancelable

问题描述

我目前有一个发布者,其类型是AnyPublisher<[MyClass], Error>我试图附加订阅者并捕获结果的AnyCancelable. Xcode 的自动完成功能说我应该能够做到这一点,但是当实际输入代码时,我遇到了一个编译器错误,说返回的类型不是AnyCancelable,但是()

这是我的代码示例:

let networkController = NetworkController()
let viewState = MyViewState()

let publisher: AnyPublisher<[MyClass], Error> = networkController.createPublisher()
let cancelable: AnyCancellable = publisher.subscribe(viewState)
Cannot convert value of type '()' to specified type 'AnyCancellable'

我的目标是在组合框架中包装一个现有的异步函数,它可以被多次调用,这样我就可以有一个很好的方法在重新分配请求时取消它,如下所示:

... self.cancelable = cancelable

标签: swiftcombine

解决方案


AnyPublisher两种 subscribe将 a 附加Subscriber到 a 的方法Publisher。它从Publisher协议中继承了两者。他们来了:

func subscribe<S>(_ subscriber: S)
    where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input

func subscribe<S>(_ subject: S) -> AnyCancellable
    where S : Subject, Self.Failure == S.Failure, Self.Output == S.Output

所以,我猜你的MyViewState类型不符合Subject协议。因此,您不能使用subscribe返回的版本AnyCancellable

Subject是它的子协议,Publisher它公开send了用于注入Subject然后发布的值的方法。你想让你的MyViewState班级成为一个Publisher? 我怀疑不是。

您可能想要做的是将您的MyViewState类型更改为甚至不符合Subscriber. 相反,使用AnyPublisher'ssink方法(也继承自Publisher)将发布者连接到您的viewState. 该sink方法返回一个Sink符合以下条件的对象Cancellable

func sink(
    receiveCompletion: ((Subscribers.Completion<Failure>) -> Void)? = nil,
    receiveValue: @escaping ((Output) -> Void))
    -> Subscribers.Sink<Output, Failure>

如果需要,您可以将返回Cancellable的包裹起来。AnyCancellable因此:

let can = publisher.sink(
    receiveCompletion: { viewModel.receive(completion: $0) },
    receiveValue: { viewModel.receive($0) })
let anyCan = AnyCancellable(can)

推荐阅读