带有完成处理程序输出的 PassthroughSubject?

Posted

技术标签:

【中文标题】带有完成处理程序输出的 PassthroughSubject?【英文标题】:PassthroughSubject with completion handler output? 【发布时间】:2021-09-13 23:27:14 【问题描述】:

我刚刚开始使用 Combine。对于这种情况,我有以下问题:

    是否接受将元组作为 PassthroughSubject 输出? 是否接受将完成处理程序作为 PassthroughSubject 输出的一部分?

示例情况:

一个 SwiftUI 登录视图,我将登录到另一个类并期望返回结果:

struct LogInView: View 
    var loginSubject = PassthroughSubject<(username: String, password: String, completion: (Error?) -> Void), Never>()         

    var body: some View 
        Button 
            loginSubject.send((username: "Jim", password: "qwerty123", completion:  error in
                if let error = error 
                    // handle error
                 else 
                    // navigate to app
                
            ))
         label: 
            Text("Log in")
        
    

我想知道针对这种情况的其他可能解决方案(由于“LogInView”在一个包中并且“登录助手”在在主应用程序中)和/或这是否会被普遍接受为解决方案。

【问题讨论】:

当然可以使用元组类型;这很常见。关于完成处理程序的东西是没有意义的; Combine 的全部意义在于它取代了完成处理程序的使用:“理顺”异步代码正是它的意义所在。如果您有一个不属于您的完成处理程序类型方法,但您想将它与 Combine 一起使用,那就是 Future。 在您的场景中,观察对象在哪里?是否有理由在视图而不是视图模型中执行此操作? 【参考方案1】:
    是的,这很常见。 不,使用像这样的完成处理程序会违背 Combine 的内置完成处理程序。而不是使用直通,您应该有一个函数,该函数接受用户名和密码并生成发布者,订阅该发布者将为您提供完成/输出处理。这样的函数通常存在于ObservableObject 中,您将其作为@EnvironmentObject 注入到视图层次结构中。

延伸阅读:https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views

【讨论】:

环境对象与通过视图init简单地注入类相比如何?是否有理由将其作为可观察对象?感谢您的帮助! EnvironmentObject 是您想要在应用程序的多个位置需要登录信息时使用的对象(几乎所有应用程序最终都有此要求)。 EnvironmentObject 允许您实例化给定类型的单个对象,并且它在注入它的视图下方的所有视图中保持活动状态(因此大多数用例涉及在根视图上注入)。如果您有一个仅在单个视图中需要的视图模型,而不是注入它,最好使用的内置方法是 StateObject,它将实例化一次并在视图刷新时保持活动状态。

以上是关于带有完成处理程序输出的 PassthroughSubject?的主要内容,如果未能解决你的问题,请参考以下文章

等待带有完成处理程序的*特定*(单个)XCTestExpectation?

从 Java Script (TVML) 调用带有完成处理程序的 Swift 函数

使用带有完成处理程序的循环在多个节点上执行单个 SKAction 动画

Swift,带有完成处理程序的网络调用不起作用

使用 UILocalNotifications、带有完成处理程序的远程通知和后台获取

将带有完成处理程序的 Firebase IdToken 添加到每个 AlamoFire 请求