RxSwift将可观察对象数组与对象数组组合

时间:2020-04-07 03:05:50

标签: swift firebase observable rx-swift

我正在尝试使用RxSwift从Firebase获取数据。我正在使用this来执行API调用。

所以我的数据库看起来像这样: 集合类别(具有属性:标题,关于等)在其中包含另一个名为 Manifests 的集合。要获取清单,我需要使用类别集合中的documentId。所以这是两个不同的API调用,但我想合并结果

那是我到目前为止所拥有的:

    func fetchCategories() -> Observable<[ManifestCategory]> {
        let ref = self.db.collection(FirebaseCollection.manifestCategories.collectionPath)

        return ref.rx.getDocuments().map({ snapshot in
            return snapshot.documents.map({ doc in
                var category = ManifestCategory.init(JSON: doc.data())

                category?.documentId = doc.documentID

                return category
                }).compactMap({ $0 })
        })
    }

    func fetchManifests(categoryId: String) -> Observable<[Manifest]> {
        let ref = self.db.collection(FirebaseCollection.manifests(categoryId: categoryId).collectionPath)

        return ref.rx.getDocuments().map({ snapshot in
            return snapshot.documents.map({ doc in
                var manifest = Manifest.init(JSON: doc.data())

                manifest?.documentId = doc.documentID

                return manifest
            }).compactMap({ $0 })
        })
    }

有什么方法可以将 Manifests 数组放入 Category 对象?

谢谢!

1 个答案:

答案 0 :(得分:1)

您应该尝试这样的事情:

func fetchCategories() -> Observable<[ManifestCategory]> {
    let ref = self.db.collection(FirebaseCollection.manifestCategories.collectionPath)

    return ref.rx.getDocuments()
        .map { snapshot in
            return snapshot.documents
                .map { doc in
                    var category = ManifestCategory.init(JSON: doc.data())
                    category?.documentId = doc.documentID
                    return category
                }
                .compactMap { $0 }
        }
        .flatMapLatest { [weak self] categories -> Observable<[ManifestCategory]> in
            guard let self = self else {
                return .empty()
            }

            let observables = categories.map { category -> ([Manifest], String) in
                self.fetchManifests(categoryId: category.documentId)
                    .map { ($0, category.documentId) }
            }

            return Observable.zip(observables)
                .map { tuple -> [ManifestCategory] in
                    tuple.compactMap { manifests, id in
                        if var category = categories.first(where: { $0.documentId == id }) {
                            category.manifests = manifests
                            return category
                        }
                        return nil
                    }
                }
        }
}