函数返回数组不会在 for 循环 Swift 中获取追加



我是请求路线的新手,并且遵循hackingwithswift(https://www.hackingwithswift.com/example-code/location/how-to-find-directions-using-mkmapview-and-mkdirectionsrequest(的文章,在跟踪新路线时,我能够获得我刚刚跟踪的路线的替代路线。我的目标是输入一个[CLLocation]MKDirection获取路线。问题是在跟踪它时,我确实得到了一条替代路线,但是当从保存的路线请求它时(与我刚刚跟踪的路线相同(,我收到一条带有错误消息的零response

方向错误:错误域=MKError域代码=1"Indicazioni stradali non disponibili" UserInfo={NSLocalizedFailureReason=Le informazioni sull'itinerario non sono attualmente disponibili., MKErrorGEOError=-12, MKErrorGEOErrorUserInfo={ NSDebugDescription = "mapItem 不能为零";}, MKDirectionsErrorCode=3, NSLocalizedDescription=Indicazioni stradali non disponibili}

路线相同,因此起点和终点相同。你能看到我在这里做错了什么吗? 一如既往地非常感谢。

func repositionLocation(route: [CLLocation]) -> [CLLocation] {
var repositioned: [CLLocation] = []
let request = MKDirections.Request()
request.requestsAlternateRoutes = false
request.transportType = .walking
let directions = MKDirections(request: request)
let a = route.first?.coordinate
let b = route.last?.coordinate
print("a is: (String(describing: a)), b is (String(describing: b))") // prints correct CLLocationCoordinate2D
request.source = MKMapItem(placemark: MKPlacemark(coordinate: a!))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b!))
directions.calculate { [unowned self] response, error in
if let err = error {
print("direction error : (err)")
}
guard let unwrappedResponse = response else {print("no suggested routes available"); return } // here always returns
guard let coord = unwrappedResponse.routes.first?.steps else {return}
for location in coord {
let point: CLLocation = CLLocation(latitude: location.polyline.coordinate.latitude, longitude: location.polyline.coordinate.longitude)
repositioned.append(point)
}
}
return repositioned
}

更新:

我正在缩小问题的范围,要么我发出太多请求(但我只发出一个(并且服务器停止响应,要么作为异步响应,函数在实际获得有效响应之前退出,因为我从 TableView 调用它。 我将如何等待cellForRow的响应?

更新 2:

在宝贵的建议之后,它现在请求路由并获得响应,我从中为每个步骤创建一个新CLLocation,并将其附加到完成后返回的repositioned数组中。 我实际上看到在打印新CLLocation时在for循环中正确创建,但数组的大小不会增加,并且返回的数组将仅具有输入路由的第一个附加。

该函数的较新版本是:

func repositionLocation(route: [CLLocation], completion: @escaping ([CLLocation]) -> Void) {
var pos = 0
var repositioned = [CLLocation]()
repositioned.append(route.first!)
guard route.count > 4 else {print("Reposision Location failed, not enough positions");return}
let request = MKDirections.Request()
request.requestsAlternateRoutes = false
request.transportType = .walking
while pos < route.count - 4 {
let a = repositioned.last!.coordinate
let b = route[pos + 4].coordinate
request.source = MKMapItem(placemark: MKPlacemark(coordinate: a))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b))
let directions = MKDirections(request: request)
directions.calculate { [unowned self] response, error in
if let err = error {
print("direction error : (err)")
}
guard let unwrappedResponse = response else {print("no suggested routes available"); return }
print("Response is: (unwrappedResponse.debugDescription)")
guard let coord = unwrappedResponse.routes.first?.steps else {print("No coordinates");return}
print("coord is: (coord)")
for location in coord {
let point: CLLocation = CLLocation(latitude: location.polyline.coordinate.latitude, longitude: location.polyline.coordinate.longitude)
print("point is: (point)") // prints a correct CLLocation with coordinates
repositioned.append(point)
print("repositioned in for loop is : (repositioned)") // prints just first appended location CLLocation with coordinates
}
}
print("repositioned in while loop is : (repositioned)")
pos += 5
}
// last segment.
//        let a = repositioned.last?.coordinate
//        let b = route.last?.coordinate
//
//        request.source = MKMapItem(placemark: MKPlacemark(coordinate: a!))
//        request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b!))
//
//        let directions = MKDirections(request: request)
//
//        directions.calculate { [unowned self] response, error in
//            if let err = error {
//                print("direction error : (err)")
//            }
//            guard let unwrappedResponse = response else {print("no suggested routes available"); return }
//            print("Response is: (unwrappedResponse.debugDescription)")
//            guard let coord = unwrappedResponse.routes.first?.steps else {print("No coordinates");return}
//            for location in coord {
//                let point: CLLocation = CLLocation(latitude: location.polyline.coordinate.latitude, longitude: location.polyline.coordinate.longitude)
//                repositioned.append(point)
//            }
print("repositioned at completion is : (repositioned)")
completion(repositioned)
//        }
}

不要看注释掉的部分,这将处理输入路由的最后一位,超过循环内处理的部分while

有几个问题:

首先,您正在尝试建立一条穿越整个美国的步行路线-这个问题无法通过常规方法解决。我建议将点的坐标设置在更近的距离。我已经在更近的地方测试了您的代码,并且出现了路线。

其次,您可以使用以下代码:

func repositionLocation(route: [CLLocation], completion: @escaping ([CLLocation]) -> Void) {
var repositioned = [CLLocation]()
let request = MKDirections.Request()
request.requestsAlternateRoutes = false
request.transportType = .walking
let a = route.first?.coordinate
let b = route.last?.coordinate
request.source = MKMapItem(placemark: MKPlacemark(coordinate: a!))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b!))
let directions = MKDirections(request: request)
print("a is: (String(describing: a)), b is (String(describing: b))") // prints correct CLLocationCoordinate2D
request.source = MKMapItem(placemark: MKPlacemark(coordinate: a!))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b!))
directions.calculate { response, error in
if let err = error {
print("direction error : (err)")
}
guard let unwrappedResponse = response else {print("no suggested routes available"); return } // here always returns
for route in unwrappedResponse.routes {
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
guard let coord = unwrappedResponse.routes.first?.steps else {return}
for location in coord {
let point: CLLocation = CLLocation(latitude: location.polyline.coordinate.latitude, longitude: location.polyline.coordinate.longitude)
repositioned.append(point)
}
completion(repositioned)
}
}

您可以设置let directions = MKDirections(request: request),但只有这样才能配置request.sourcerequest.destination。除此之外,您可以异步获取结果,因此我为结果添加了completion

对于测试,您可以调用:

repositionLocation(route: [CLLocation(latitude: 40.7127, longitude: -74.0059), CLLocation(latitude: 40.79, longitude: -74.011)]) { result in
print(result)
}

UPD2:

@Vincenzo如我所见,您错误地使用完成处理程序进行闭包,我建议您阅读有关异步和闭包的信息。

我建议使用以下代码:

func repositionLocation(route: [CLLocation], completion: @escaping ([CLLocation]) -> Void) {
var pos = 0
var repositioned = [CLLocation]()
repositioned.append(route.first!)
guard route.count > 4 else {print("Reposision Location failed, not enough positions");return}
let request = MKDirections.Request()
request.requestsAlternateRoutes = false
request.transportType = .walking
while pos < route.count - 4 {
let a = repositioned.last!.coordinate
let b = route[pos + 4].coordinate
request.source = MKMapItem(placemark: MKPlacemark(coordinate: a))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: b))
let directions = MKDirections(request: request)
directions.calculate { [unowned self] response, error in
if let err = error {
print("direction error : (err)")
}
guard let unwrappedResponse = response else {print("no suggested routes available"); return }
print("Response is: (unwrappedResponse.debugDescription)")
guard let coord = unwrappedResponse.routes.first?.steps else {print("No coordinates");return}
print("coord is: (coord)")
for location in coord {
let point: CLLocation = CLLocation(latitude: location.polyline.coordinate.latitude, longitude: location.polyline.coordinate.longitude)
print("point is: (point)") // prints a correct CLLocation with coordinates
repositioned.append(point)
print("repositioned in for loop is : (repositioned)") // prints just first appended location CLLocation with coordinates
}
completion(repositioned)
}
print("repositioned in while loop is : (repositioned)")
pos += 5
}
}

最新更新