函数返回数组没有在 for 循环 Swift 中获得追加
Posted
技术标签:
【中文标题】函数返回数组没有在 for 循环 Swift 中获得追加【英文标题】:function returning array doesn't get the appends inside the for loop Swift 【发布时间】:2019-12-19 17:43:57 【问题描述】:我是请求路线的新手,并关注 hackingwithswift (https://www.hackingwithswift.com/example-code/location/how-to-find-directions-using-mkmapview-and-mkdirectionsrequest) 的一篇文章,在跟踪新路线时,我能够获得刚刚跟踪的路线的替代路线。我的目标是输入[CLLocation]
从MKDirection
获取路线。问题是,在跟踪它时,我确实得到了一条替代路线,但是当从保存的路线(我刚刚跟踪的相同)请求它时,我得到一个 nil response
并显示错误消息:
方向错误:错误域=MKErrorDomain Code=1 "Indicazioni stradali non disponibili" UserInfo=NSLocalizedFailureReason=Le infoazioni sull'itinerario non sono attualmente disponibili., MKErrorGEOError=-12, MKErrorGEOErrorUserInfo= NSDebugDescription = "mapItem 不能为 nil"; , MKDirectionsErrorCode=3, NSLocalizedDescription=Indicazioni stradali 不可分配
路线是一样的,所以起点和终点都是一样的。你能看到我在这里做错了什么吗? 一如既往,非常感谢。
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
loop 内正确创建,但数组的大小不会增加,返回的数组只会有输入路由的第一个追加。
较新版本的函数是:
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
循环内处理的部分。
【问题讨论】:
如果我的回答有用且正确,请查看 【参考方案1】:有几个问题:
首先,您正在尝试建立一条穿越整个美国的步行路线——这个问题无法通过常规方法解决。我建议将点的坐标设置在更近的距离。我已经在更近的地方测试了您的代码并出现了路线。
其次,你可以使用这个代码:
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.source
和request.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
【讨论】:
太好了,您回答时我正在更新问题。我确实认为这是一个异步问题。我不是把它打电话给整个美国,我不是一条 1.5 公里的路线.. @Vincenzo,好的。关于您的更新:您可以在单元格中使用回调来在单元格中显示您的结果。 For example 谢谢,我终于成功了,因为我在while
循环中得到了响应,但我最终得到了一个仅包含第一个附加的 repositioned
数组在进入while
循环之前。我猜for
循环内部出了点问题。我在循环内打印point
并显示坐标,但由于某种原因它没有附加到repositioned
array。你明白为什么吗?
@Vincenzo 能否提供代码,因为我不明白您在哪里、为什么以及如何使用 while
循环?
对不起,我在用代码更新问题之前回答了你。以上是关于函数返回数组没有在 for 循环 Swift 中获得追加的主要内容,如果未能解决你的问题,请参考以下文章
在for循环中将PFFile数组转换为UIImage返回空数组Swift