Ios 如何用多个链接URL请求和请求依赖项填充单个模型对象?
我有一个数据模型对象,我必须填充多个网络请求 我的模型看起来像这样Ios 如何用多个链接URL请求和请求依赖项填充单个模型对象?,ios,swift,swiftui,combine,urlsession,Ios,Swift,Swiftui,Combine,Urlsession,我有一个数据模型对象,我必须填充多个网络请求 我的模型看起来像这样 struct CO2Data: Identifiable, Codable { let id = UUID() let totalCO2: Double let dailyAverage: Int let calendar = Calendar.current let dateString: String let emissionStats: EmissionStats let
struct CO2Data: Identifiable, Codable {
let id = UUID()
let totalCO2: Double
let dailyAverage: Int
let calendar = Calendar.current
let dateString: String
let emissionStats: EmissionStats
let driveLog: String
// It is an ID to get the trip details
let trip : Trip
// This is what needs to be filled from the next URL request using driveLog
enum CodingKeys: String, CodingKey {
case id
case totalCO2 = "totCO2"
case dateString = "stDt"
case dailyAverage = "avg"
case emissionStats = "emisStats"
case drLogRefId = "drLogRefId"
//Not having case trip here breaks the conformance to codable
// and results in error
}
}
// for CO2Data
[
{
"stDt": "2019-11-17T16:00:00.000+0000",
"totCO2": 50,
"avg": 0,
"emisStats": {
"wea": 10,
"aggDr": 10,
"tfc": 10,
"tirePress": 0,
"ac": 10,
"seatHeater": 10
},
"drLogRefId": "5dc20204199f752c7726a8f0"
}
]
//for Trip
[
{
"id": "5dc20204199f752c7726a8f0",
"startTime": "...",
"startLat: "...",
"startLong: "...",
"endLat: "...",
"endLong": "...",
}
]
这是网络请求和响应的流程
struct CO2Data: Identifiable, Codable {
let id = UUID()
let totalCO2: Double
let dailyAverage: Int
let calendar = Calendar.current
let dateString: String
let emissionStats: EmissionStats
let driveLog: String
// It is an ID to get the trip details
let trip : Trip
// This is what needs to be filled from the next URL request using driveLog
enum CodingKeys: String, CodingKey {
case id
case totalCO2 = "totCO2"
case dateString = "stDt"
case dailyAverage = "avg"
case emissionStats = "emisStats"
case drLogRefId = "drLogRefId"
//Not having case trip here breaks the conformance to codable
// and results in error
}
}
// for CO2Data
[
{
"stDt": "2019-11-17T16:00:00.000+0000",
"totCO2": 50,
"avg": 0,
"emisStats": {
"wea": 10,
"aggDr": 10,
"tfc": 10,
"tirePress": 0,
"ac": 10,
"seatHeater": 10
},
"drLogRefId": "5dc20204199f752c7726a8f0"
}
]
//for Trip
[
{
"id": "5dc20204199f752c7726a8f0",
"startTime": "...",
"startLat: "...",
"startLong: "...",
"endLat: "...",
"endLong": "...",
}
]
根据周围数据的复杂性,查看
- 操作:您可以指定此操作所依赖的其他操作
- DispatchGroup:使用
,DispatchGroup.enter()
和最后的DispatchGroup.leave()
还可以对所执行的已调度任务的依赖关系建模DispatchGroup.notify()
祝你好运 以下是实现目标的方法。在第一次网络呼叫期间,您需要将
Trip
设置为可选,因为您没有要在那里设置的数据。确保在json解码期间正确处理此问题
然后使用flatMap
进行第二次网络调用。
使用zip
等待两个请求完成,并将结果数据传递给扩展CO2Data.init
完整代码,其中fetchCO2TripData
将返回CO2Data
和Trip
:
struct CO2Data: Identifiable, Codable {
let id = UUID()
/// TODO: add other properties
let driveLog: String
let trip : Trip?
}
struct Trip: Codable {
let startTime: String
let endTime: String
let startLat: String
let startLong: String
let endLat: String
let endLong: String
}
func fetchCO2Data() -> AnyPublisher<CO2Data, Error> {
/// TODO: Replace with actual network request
Empty().eraseToAnyPublisher()
}
func fetchTripData(by driveLog: String) -> AnyPublisher<Trip, Error> {
/// TODO: Replace with actual network request
Empty().eraseToAnyPublisher()
}
func fetchCO2TripData() -> AnyPublisher<CO2Data, Error> {
let co2Publisher = fetchCO2Data().share()
let tripPublisher = co2Publisher.flatMap { fetchTripData(by: $0.driveLog) }
return co2Publisher
.zip(tripPublisher)
.map { CO2Data(co2data: $0, trip: $1) }
.eraseToAnyPublisher()
}
extension CO2Data {
init(co2data: CO2Data, trip: Trip) {
self.driveLog = co2data.driveLog
self.trip = trip
}
}