【发布时间】:2023-03-05 11:49:01
【问题描述】:
基本上,前两个函数(FetchOriginCoordinates 和 FetchDestCoordinates)将街道名称作为输入并返回其坐标。然后使用坐标在函数FetchOriginID 和FetchDestID 中查找附近的公交车站。这些函数返回巴士站 ID,然后在最后一个函数中使用 (FetchTrip)。在该函数中使用的 URL 中有四个可修改的参数:originExtId、destExtId、date 和 time。 originExtId 和 destExtId 是从 FetchOriginID 和 FetchDestID 获取的值。 date 和 time 参数对应变量arrivalTime 和travelDate。
我只在按下body 中的Button 时调用FetchTrip 函数。第一次调用函数时的变量:self.originLat、self.originLon、self.destLat、self.destLon、self.originID 和 self.destID 都是 nil。第二次self.originID 和self.destID 是nil。第三次函数工作(返回正确的值)。
我是 swift 新手,所以我不完全确定这是为什么。但我确实相信这是因为嵌套函数继续运行而无需等待其他函数完成。因此,我认为它与Closures 有关,但我不完全确定如何应用它。有人可以帮我吗?
@State var arrivalTime = String()
@State var travelDate = String()
@State var originInput = String()
@State var destInput = String()
@State var originLat = String()
@State var originLon = String()
@State var destLat = String()
@State var destLon = String()
@State var originID = String()
@State var destID = String()
@State var destName = String()
@State var destTime = String()
@State var originTime = String()
@State var originName = String()
@State var Trips = [String]()
@State var tripIndex = Int()
var body: some View {
VStack {
List(Trips, id: \.self) { string in
Text(string)
}
TextField("From", text: $originInput).padding()
TextField("To", text: $destInput).padding()
TextField("00:00", text: $arrivalTime).padding()
TextField("yyyy-mm-dd", text: $travelDate).padding()
Button("FetchAPI"){FetchTrip()}.padding()
}
}
func FetchOriginCoordinates(completion: @escaping ([NominationStructure]) -> ()) {
let locationUrl = URL(string: "https://nominatim.openstreetmap.org/search?country=Sweden&city=Stockholm&street=\(self.originInput)&format=json")
print(locationUrl)
URLSession.shared.dataTask(with: locationUrl!) {data, response, error in
if let data = data {
do {
if let decodedJson = try? JSONDecoder().decode([NominationStructure].self, from: data) {
DispatchQueue.main.async {
completion (decodedJson)
}
}
} catch {
print(error)
}
}
}.resume()
}
func FetchDestCoordinates(completion: @escaping ([NominationStructure]) -> ()) {
// Same as the function above but using self.destInput instead of self.originInput
}
func FetchOriginID(completion: @escaping (NearbyStopsStructure) -> ()) {
DispatchQueue.main.async {
FetchOriginCoordinates { (cors) in
self.originLat = cors[0].lat
self.originLon = cors[0].lon
}
}
let nearbyStopsKey = "MY API KEY"
let stopIDUrl = URL(string: "http://api.sl.se/api2/nearbystopsv2.json?key=\(nearbyStopsKey)&originCoordLat=\(self.originLat)&originCoordLong=\(self.originLon)&maxNo=1")
print(stopIDUrl)
URLSession.shared.dataTask(with: stopIDUrl!) {data, response, error in
if let data = data {
do {
if let decodedJson = try? JSONDecoder().decode(NearbyStopsStructure.self, from: data) {
DispatchQueue.main.async {
completion (decodedJson)
}
}
} catch {
print(error)
}
}
}.resume()
}
func FetchDestID(completion: @escaping (NearbyStopsStructure) -> ()) {
// Same as the function above but using self.destLat and self.destLon instead of self.originLat and self.originLon
}
func FetchTrip() {
DispatchQueue.main.async {
FetchOriginID { (stops) in
self.originID = stops.stopLocationOrCoordLocation[0].StopLocation.mainMastExtId
}
FetchDestID { (stops) in
self.destID = stops.stopLocationOrCoordLocation[0].StopLocation.mainMastExtId
}
}
let tripKey = "MY API KEY"
let tripUrl = URL(string: "http://api.sl.se/api2/TravelplannerV3_1/trip.json?key=\(tripKey)&originExtId=\(self.originID)&destExtId=\(self.destID)&Date=\(self.travelDate)&Time=\(self.arrivalTime)&searchForArrival=1")
print(tripUrl)
// Logic here
}
【问题讨论】:
-
请尝试合并。
标签: json swift xcode api swiftui