gpt4 book ai didi

swift - 链接请求并使用 RxSwift 返回两个结果

转载 作者:行者123 更新时间:2023-12-04 17:32:10 26 4
gpt4 key购买 nike

我有一个 ContentService 请求文章。该文章响应包含一个 authorId 属性。

我有一个 ProfileService,它允许我通过 userId 请求用户配置文件。

我正在尝试从 ContentService 请求一篇文章,一旦请求完成就使用 authorId 属性链接到 ProfileService,然后我想返回一个包含文章和个人资料信息的 ContentArticleViewModel

我的 ArticleInteractor 看起来像这样 -

final class ArticleInteractor: ArticleInteractorInputProtocol {

let fetchArticleTrigger = PublishSubject<String>()

private lazy var disposeBag = DisposeBag()

weak var output: ArticleInteractorOutputProtocol? {
didSet {
configureSubscriptions()
}
}

private func configureSubscriptions() {
guard let output = output else { return }

fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)

dependencies.contentSvc.fetchContentByIdResponse
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}
}

很简单,fetchArticleTrigger 启动一个请求,然后我绑定(bind) dependencies.contentSvc.fetchContentByIdResponse 并获取响应。

我的 ContentService 上的方法是 -

    // MARK:- FetchContentById
// @params: id - String
// return: PublishSubject<ContentArticle>

fetchContentByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getContentById(id: $0)) }
.map { (resp: Result<ContentArticle>) in
guard case .success(let props) = resp else { return ContentArticle() }
return props
}
.bind(to: fetchContentByIdResponse)
.disposed(by: disposeBag)

我在我的 ProfileService 上有一个非常相似的设置 -

    // MARK:- FetchUserProfileById
// @params: id - String
// return: PublishSubject<User>
fetchUserProfileByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getProfileByUserId(id: $0)) }
.map { (resp: Result<User>) in
guard case .success(let props) = resp else { return User() }
return props
}
.bind(to: fetchUserProfileByIdResponse)
.disposed(by: disposeBag)

我想我会为文章创建一个模型,比如 -

struct ContentArticleViewModel {
var post: ContentArticle
var user: User
}

我在我的 ArticleInteractor-

中想象了类似这个伪代码的东西
    dependencies.contentSvc.fetchContentByIdResponse
.flatMapLatest { article in
/* fetch profile using `article.authorId */
}.map { article, profile in
return ContentArticleViewModel(post: article, user: profile)
}
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)

但我完全不知道如何最好地处理这个问题。我看过很多关于链接请求的文章,但我很难成功地应用任何东西。

编辑

我目前有一些工作 -

    private func configureSubscriptions() {
guard let output = output else { return }

fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)

dependencies.contentSvc.fetchContentByIdResponse
.do(onNext: { [unowned self] article in self.dependencies.profileSvc.fetchUserProfileByIdTrigger.onNext(article.creator.userId)})
.bind(to: fetchArticleResponse)
.disposed(by: disposeBag)

let resp = Observable.combineLatest(fetchArticleResponse, dependencies.profileSvc.fetchUserProfileByIdResponse)

resp
.map { [unowned self] in self.enrichArticleAuthorProps(article: $0, user: $1) }
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}

private func enrichArticleAuthorProps(article: ContentArticle, user: User) -> ContentArticle {
var updatedArticle = article
updatedArticle.creator = user
return updatedArticle
}

但是我不确定这是正确的。

最佳答案

我不确定为什么这么小的工作需要这么多代码。下面是一个示例,它执行您描述的操作(下载文章、下载作者简介并发出两者),代码少得多,甚至 比我通常使用的代码还多。

protocol ContentService {
func requestArticle(id: String) -> Observable<Article>
func requestProfile(id: String) -> Observable<User>
}

class Example {
let service: ContentService
init(service: ContentService) {
self.service = service
}

func bind(trigger: Observable<String>) -> Observable<(Article, User)> {
let service = self.service
return trigger
.flatMapLatest { service.requestArticle(id: $0) }
.flatMapLatest {
Observable.combineLatest(Observable.just($0), service.requestProfile(id: $0.authorId))
}
}
}

或者您可能希望在等待作者简介下载时显示文章。在那种情况下是这样的:

func bind(trigger: Observable<String>) -> (article: Observable<Article>, author: Observable<User>) {
let service = self.service
let article = trigger
.flatMapLatest { service.requestArticle(id: $0) }
.share(replay: 1)

let author = article
.flatMapLatest {
service.requestProfile(id: $0.authorId)
}

return (article, author)
}

关于swift - 链接请求并使用 RxSwift 返回两个结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58698552/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com