.sink没有从未来发布者返回承诺值 [英] .sink is not returning the promise values from a Future Publisher

查看:62
本文介绍了.sink没有从未来发布者返回承诺值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在lrvViewModel.swift中有这段代码

I have this code in lrvViewModel.swift

func getVerificationID (phoneNumber: String) -> Future<String?, Error> {

        return Future<String?, Error> { promise in
            PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
                if let e = error {
                    promise(.failure(e))
                    return
                }
                print("verification worked")
                self.defaults.set(verificationID, forKey: "authVerificationID")
                return promise(.success(verificationID))
            }
        }
    }

然后我在另一个这样的文件中呼叫并订阅发布服务器

and then i call and subscribe to the Publisher in another file like this

let _ = lrvViewModel.getVerificationID(phoneNumber: (lrvViewController?.textField.text)!)
                .sink(receiveCompletion: {
                    print("Error worked")
                    // does a bunch of stuff
                }, receiveValue: {
                    print("completion worked")
                    // does a bunch of stuff
                })

我没有收到任何构建时错误,但是每当我运行该应用程序时,GetVerificationID函数都可以正常运行(打印验证工作"),但是.sink中的代码无法运行(我没有得到任何打印语句)).发生了什么事?

I don't get any buildtime errors, but whenever I run the app the GetVerificationID function runs fine (prints "Verification worked"), but the code within .sink doesn't run (I don't get any print statements). What's going on?

我的解决方案是放弃组合,回到代码简单的RXSwift:

My solution was to give up on combine and go back to RXSwift where the code is simply:

 var validateObs = PublishSubject<Any>()

    func getVerificationID (phoneNumber: String) {

        PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
            if let e = error {
                print("v error")
                self.validateObs.onError(e)
                return
            }
            self.defaults.set(verificationID, forKey: "authVerificationID")
            self.validateObs.onCompleted()
            }
    }

lrvViewModel.getVerificationID(phoneNumber: (lrvViewController?.textField.text)!)

            let _ = lrvViewModel.validateObs.subscribe(onError: {
                let e = $0
                print(e.localizedDescription)
                // do stuff
            }, onCompleted: {
                // do stuff

                })

希望不依赖于依赖项,但是RxSwift的实现要容易得多.

Was hoping to not rely on a dependency but RxSwift implementation was much easier.

如果有人知道合并未来"问题的解决方案,请发布!我仍然想知道wtf正在发生.我很有可能(而且很可能)正在使用组合错误.

If someone knows the solution to the Combine Future problem please post! I would still like to know wtf is happening. It's very possible (and likely) I'm just using combine wrong.

使用组合错误.我可以这样复制RXSwift的代码:

Was using combine wrong. I can duplicate the code I had with RXSwift like this:

let verifyPub = PassthroughSubject<Any, Error>()

func getVerificationID (phoneNumber: String) {

    PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
            if let e = error {
                self.verifyPub.send(completion: .failure(e))
                return
            }
            print("verification worked")
            self.defaults.set(verificationID, forKey: "authVerificationID")
        self.verifyPub.send(completion: .finished)
        }
    }

let subs = Set<AnyCancellable>()
let pub = lrvViewModel.verifyPub
                .sink(receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print("Error worked")
                       // do stuff
                    } else {
                        print("completion worked")
                        // do stuff
                    }
                    }, receiveValue: { _ in
                        print("this will never happen")
                    }).store(in: &subs)

我不明白,在合并中,接收器只有两个结果,即完成或值,并且将完成分为多个案例.而在RxSwift中,您具有OnNext,OnComplete和OnError.

I didnt' understand that in combine there are only two results to a sink, a completion or a value, and that completion is split up into multiple cases. Whereas in RxSwift you have OnNext, OnComplete, and OnError.

从raywanderlich.com上大喊结合"一书.好东西.

Shoutout to the book on Combine from raywanderlich.com. Good stuff.

推荐答案

正在发生的情况是,您的 .sink 后面没有 .store 命令,因此管道在任何价值没有机会下降之前就已经不复存在.

What's going on is that your .sink is not followed by a .store command, so the pipeline goes out of existence before any value has a chance to come down it.

您将管道分配给空的 _ 可以有效地掩盖该问题.编译器试图警告您,然后您将其关闭.

Your assignment of the pipeline to the empty _ effectively masks the problem. The compiler tried to warn you, and you shut it down.

这篇关于.sink没有从未来发布者返回承诺值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆