簡體   English   中英

函數返回數組不會在for循環Swift中獲得追加

[英]function returning array doesn't get the appends inside the for loop Swift

我是新來請求路線並關注 hackingwithswift 的文章( https://www.hackingwithswift.com/example-code/location/how-to-find-directions-using-mkmapview-and-mkdirectionsrequest )我能夠在跟蹤新路線時,獲取我剛剛跟蹤的路線的替代路線。 我的目標是輸入一個[CLLocation]MKDirection獲取路線。 問題是,在跟蹤它時,我確實得到了一條替代路線,但是當從保存的路線(與我剛剛跟蹤的路線相同)請求它時,我得到了一個帶有錯誤消息的 nil response

方向錯誤:Error Domain=MKErrorDomain Code=1 "Indicazioni stradali non disponibili" UserInfo={NSLocalizedFailureReason=Le informazioni sull'itinerario non sono attualmente disponibili., MKErrorGEOError=-12, MKErrorGEOErrorUserInfo={ NSDebugDescription be nilmap; }, 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
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM