gpt4 book ai didi

ios - Rx swift : Combine two network request to return one value

转载 作者:搜寻专家 更新时间:2023-11-01 06:58:45 25 4
gpt4 key购买 nike

我有两个网络请求,我想将结果合并到一个对象数组中。

enum ResultType<T> {
case success(T)
case failure(Error)
}

static func requestPlaceSearch(query: String) -> Observable<ResultType<SearchResult>> {
let urlString = "https://maps.googleapis.com/maps/api/place/autocomplete/json"
let params = ["input": query, "types": "geocode",
"key": "key"]
return placeRequest(url: urlString, params: params)
}

static func requestPlace(with placeId: String) -> Observable<ResultType<Place>> {
let params = ["placeid": placeId, "key": "key"]
let urlString = "https://maps.googleapis.com/maps/api/place/details/json"
return placeRequest(url: urlString, params: params)
}

requestPlaceSearch SearchResult 的返回和可观察性我想遍历 SearchResult.predictions , 获取每个预测的 id 向 requestPlace 发出请求得到 Place附加到 Places 的数组

我希望我的最终数组是

let places = Observable<[Place]> 

let places = [Place]()

最佳答案

我会给你答案,但我会通过解释我是如何得出答案的来把它画出来的。希望您可以模拟该过程,并能够在下一次尝试中自己得出答案。

开始于:

let foo = requestPlaceSearch(query: "")

再看看foo的类型是:Observable<ResultType<SearchResult>> .好的,我们需要从结果类型中提取搜索结果。所以……

let foo = requestPlaceSearch(query: "")
.map { (result: ResultType<SearchResult>) -> SearchResult? in
if case let .success(search) = result {
return search
} else {
return nil
}
}

现在 foo 是什么?的类型? Observable<SearchResult?> .因此,让我们过滤掉可选项。

let foo = requestPlaceSearch(query: "")
.map { (result: ResultType<SearchResult>) -> SearchResult? in
if case let .success(search) = result {
return search
} else {
return nil
}
}
.filter { $0 != nil }.map { $0! }

现在foo是类型:Observable<SearchResult>所以我们可以拉出 predictions .

let foo = requestPlaceSearch(query: "")
.map { (result: ResultType<SearchResult>) -> SearchResult? in
if case let .success(search) = result {
return search
} else {
return nil
}
}
.filter { $0 != nil }.map { $0! }
.map { $0.predictions }

我们将需要该函数来再次提取成功对象,所以让我们将其移至一个单独的函数中:

func extractSuccess<T>(_ result: ResultType<T>) -> T? {
if case let .success(search) = result {
return search
} else {
return nil
}
}

我假设 predictions只是字符串。您可能必须从中提取字符串 ID。所以现在 foo 的类型是 Observable<[String]> .现在我们有了 ID,我们可以调用另一个端点。

let foo = requestPlaceSearch(query: "")
.map(extractSuccess)
.filter { $0 != nil }.map { $0! }
.map { $0.predictions }
.map { $0.map(requestPlace) }

现在foo类型为 Observable<[Observable<ResultType<Place>>]> .接下来让我们把 [Observable] 变成一个 Observable<[T]>。

let foo = requestPlaceSearch(query: "")
.map(extractSuccess)
.filter { $0 != nil }.map { $0! }
.map { $0.predictions }
.map { Observable.combineLatest($0.map(requestPlace)) }

这使得 foo 成为 Observable<Observable<[ResultType<Place>]>> . Observable> 可以很容易地展平。

let foo = requestPlaceSearch(query: "")
.map(extractSuccess)
.filter { $0 != nil }.map { $0! }
.map { $0.predictions }
.flatMap { Observable.combineLatest($0.map(requestPlace)) }

这会将 foo 变成一个 Observable<[ResultType<Place>]>

let foo = requestPlaceSearch(query: "")
.map(extractSuccess)
.filter { $0 != nil }.map { $0! }
.map { $0.predictions }
.flatMap { Observable.combineLatest($0.map {
requestPlace(with: $0)
.map(extractSuccess)
.filter { $0 != nil }.map { $0! }
})
}

我在上面添加的部分与最后一个返回结果类型的部分相同。另外,此时foo类型为 Observable<[Place]>我们完成了。

请注意,此代码不处理任何失败结果。我将把它留给读者作为练习。 :-)

关于ios - Rx swift : Combine two network request to return one value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51851248/

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