如何使用dataTaskPublisher链接多个API调用?

时间:2019-08-12 02:33:48

标签: ios swift swiftui combine

我想从REST API中获取数据,为此,我需要首先获取一个ID数组-第一个调用。之后,我需要使用每个ID进行API调用。我不想使用completionHandlers,但是要使用Combined。我从dataTaskPublishers开始,但是我不确定如何链接它们以使其正常工作?

到目前为止,这是我的代码:

   private func getIDs(for type: DataType) -> AnyPublisher<[ID], Error> {
        guard let url = URL(string: "url")
            else { fatalError("Wrong URL") }

        return session.dataTaskPublisher(for: url)
            .receive(on: RunLoop.main)
            .map { $0.data }
            .decode(type: [ID].self, decoder: decoder)
            .eraseToAnyPublisher()
    }

    private func getData(with id: ID) -> AnyPublisher<MyData, Error> {
        guard let url = URL(string: "url_with_id")
            else { fatalError("Wrong URL") }
        return session.dataTaskPublisher(for: url)
            .receive(on: RunLoop.main)
            .map { $0.data }
            .decode(type: MyData.self, decoder: decoder)
            .eraseToAnyPublisher()
    }

我不太确定如何连接它们以获得可分配给我的状态变量-MyData数组的东西。

1 个答案:

答案 0 :(得分:2)

根据https://stackoverflow.com/a/56786412/1271826中的建议,您可以使用collect()

func getAllData() -> AnyPublisher<[MyData], Error> {
    getIDs().flatMap { ids -> AnyPublisher<[MyData], Error> in
        let publishers = ids.map { self.getData(with: $0) }
        return Publishers.Sequence<[AnyPublisher<MyData, Error>], Error>(sequence: publishers)
            .flatMap { $0 }
            .collect()
            .eraseToAnyPublisher()
    }.eraseToAnyPublisher()
}