I'm trying to wrap my head around this call in Combine.
I have two models and calls. One is an array of place data, the second an array for the OpenWeather response. What I need is to pass the latitude and longitude from my first call response into the second call. At the same time I need to keep the response for both calls.
Bear in mind that this is my first chained request.
enum callAPI {
static let agent = Agent()
static let url1 = URL(string: "**jsonURL**")!
static let url2 = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=\(latitude)&lon=\(longitude)&APPID=**APIkey**&unites=metric")! }
extension callAPI {
static func places() -> AnyPublisher<[Place], Error> {
return run(URLRequest(url: url1))
}
static func weather(latitude: Double, longitude: Double) -> AnyPublisher<[ResponseBody], Error> {
return run(URLRequest(url: url2))
}
static func run<T: Decodable>(_ request: URLRequest) -> AnyPublisher<T, Error> {
return agent.run(request)
.map(\.value)
.eraseToAnyPublisher()
}}
func chain() {
let places = callAPI.places()
let firstPlace = places.compactMap { $0.first }
let weather = firstPlace.flatMap { place in
callAPI.weather(latitude: place.latitude, longitude: place.longitude)
}
let token = weather.sink(receiveCompletion: { _ in },
receiveValue: { print($0) })
RunLoop.main.run(until: Date(timeIntervalSinceNow: 10))
withExtendedLifetime(token, {})}
This is the model:
struct Place: Decodable, Identifiable {
let id: Int
let name: String
let description: String
let latitude, longitude: Double
let imageURL: String }
struct ResponseBody: Decodable {
var coord: CoordinatesResponse
var weather: [WeatherResponse]
var main: MainResponse
var name: String
var wind: WindResponse
struct CoordinatesResponse: Decodable {
var lon: Double
var lat: Double
}
struct WeatherResponse: Decodable {
var id: Double
var main: String
var description: String
var icon: String
}
struct MainResponse: Decodable {
var temp: Double
var feels_like: Double
var temp_min: Double
var temp_max: Double
var pressure: Double
var humidity: Double
}
struct WindResponse: Decodable {
var speed: Double
var deg: Double
}}
extension ResponseBody.MainResponse {
var feelsLike: Double { return feels_like }
var tempMin: Double { return temp_min }
var tempMax: Double { return temp_max }}