このページとこのページを参考にしました
独自に座標を取得して逆ジオコーディングをしピンを置き、ピンをタップした吹き出しの中に経路ボタンを実装した所までは出来たのですが、経路ボタンを押すと
下記のコード内の
// 現在地と目的地を含む表示範囲を設定する
self.showUserAndDestinationOnMap()
} as! MKDirections.DirectionsHandler)
にThread 1: signal SIGABRTが出てしまいます
変数userLocationとdestLocationを強制アンラップしているからアプリが落ちてしまうのではないかと予測を立てていますが、はっきりとした原因はわかっていません。
アドバイス頂ければ嬉しいです。よろしくお願いします。
class FirstViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var mapView: MKMapView! let locationManager = CLLocationManager() let geocoder = CLGeocoder() let annotation = MKPointAnnotation() var userLocation: CLLocationCoordinate2D! var destLocation: CLLocationCoordinate2D! let regionRadius: CLLocationDistance = 1000 override func viewDidLoad() { super.viewDidLoad() locationManager.delegate = self as CLLocationManagerDelegate self.mapView.delegate = self } func geocoding() { //逆ジオコーディング let location = CLLocation(latitude: {doubleLatitude(独自に取得した緯度です)}(), longitude: {doubleLongitude(独自に取得した経度です)}()) CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in guard let placemark = placemarks?.first, error == nil else { return } self.destLocation = CLLocationCoordinate2DMake(placemark.location!.coordinate.latitude, placemark.location!.coordinate.longitude) print("逆ジオコーディングの中") //ピン self.annotation.coordinate = CLLocationCoordinate2DMake(doubleLatitude, doubleLongitude);self.mapView.addAnnotation(self.annotation) self.mapView.addAnnotation(self.annotation) print("ピンを置きました") //アノテーション let artwork = Artwork(title: "後で決める", locationName: "後で決める", discipline: "後で決める", coordinate: CLLocationCoordinate2D(latitude: doubleLatitude, longitude: doubleLongitude)) self.mapView.addAnnotation(artwork) } }) } //経路表示 @objc func buttonEvent(_ sender: UIButton) { // 現在地と目的地のMKPlacemarkを生成 let fromPlacemark = MKPlacemark(coordinate:userLocation, addressDictionary:nil) let toPlacemark = MKPlacemark(coordinate:destLocation, addressDictionary:nil) // MKPlacemark から MKMapItem を生成 let fromItem = MKMapItem(placemark:fromPlacemark) let toItem = MKMapItem(placemark:toPlacemark) // MKMapItem をセットして MKDirectionsRequest を生成 let request = MKDirections.Request() request.source = fromItem request.destination = toItem request.requestsAlternateRoutes = false // 単独の経路を検索 request.transportType = MKDirectionsTransportType.any let directions = MKDirections(request:request) directions.calculate(completionHandler: { (response:MKDirections.Response!, error:NSError!) -> Void in response.routes.count if (error != nil || response.routes.isEmpty) { return } let route: MKRoute = response.routes[0] as MKRoute // 経路を描画 self.mapView.addOverlay(route.polyline) // 現在地と目的地を含む表示範囲を設定する self.showUserAndDestinationOnMap() //Thread 1: signal SIGABRTのエラーです(エラー内容は下記に記載↓) } as! MKDirections.DirectionsHandler) } //地図上に現在地、目的地、経路がちょうど収まるように表示 func showUserAndDestinationOnMap() { // 現在地と目的地を含む矩形を計算 let maxLat:Double = fmax(userLocation.latitude, destLocation.latitude) let maxLon:Double = fmax(userLocation.longitude, destLocation.longitude) let minLat:Double = fmin(userLocation.latitude, destLocation.latitude) let minLon:Double = fmin(userLocation.longitude, destLocation.longitude) // 地図表示するときの緯度、経度の幅を計算 let mapMargin:Double = 1.5; // 経路が入る幅(1.0)+余白(0.5) let leastCoordSpan:Double = 0.005; // 拡大表示したときの最大値 let span_x:Double = fmax(leastCoordSpan, fabs(maxLat - minLat) * mapMargin); let span_y:Double = fmax(leastCoordSpan, fabs(maxLon - minLon) * mapMargin); let span:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: span_x, longitudeDelta: span_y); // 現在地を目的地の中心を計算 let center:CLLocationCoordinate2D = CLLocationCoordinate2DMake((maxLat + minLat) / 2, (maxLon + minLon) / 2); let region:MKCoordinateRegion = MKCoordinateRegion(center: center, span: span); mapView.setRegion(mapView.regionThatFits(region), animated:true); } func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { switch status { case .notDetermined: locationManager.requestWhenInUseAuthorization() case .authorizedWhenInUse: locationManager.startUpdatingLocation() default: break } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { //無理やり!でアンラップしました←ここが間違っている? userLocation = CLLocationCoordinate2DMake(manager.location!.coordinate.latitude, manager.location!.coordinate.longitude) if let coordinate = locations.last?.coordinate { // 現在地を拡大して表示する let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01) let region = MKCoordinateRegion(center: coordinate, span: span) mapView.region = region } guard let newLocation = locations.last else { return } self.latitude.text = "".appendingFormat("%.4f", newLocation.coordinate.latitude) self.longitude.text = "".appendingFormat("%.4f", newLocation.coordinate.longitude) let location = locations.first let latitude = location?.coordinate.latitude let longitude = location?.coordinate.longitude print("緯度: (latitude!)\n経度: (longitude!)") } // 位置情報取得に失敗した時に呼び出されるデリゲート. func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){ print("locationManager error") } func centerMapOnLocation(location: CLLocation) { let coordinateRegion = MKCoordinateRegion(center: location.coordinate, latitudinalMeters: regionRadius, longitudinalMeters: regionRadius) mapView.setRegion(coordinateRegion, animated: true) } } extension FirstViewController: MKMapViewDelegate { // 1 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { // 2 guard let annotation = annotation as? Artwork else { return nil } // 3 let identifier = "marker" var view: MKMarkerAnnotationView // 4 if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView { dequeuedView.annotation = annotation view = dequeuedView } else { // 5 view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier) view.canShowCallout = true view.calloutOffset = CGPoint(x: -5, y: 5) //右ボタンをアノテーションビューに追加する。 let button = UIButton() button.frame = CGRect(x: 0,y: 0,width: 70,height: 50) button.setTitle("経路", for: .normal) button.backgroundColor = UIColor.green button.setTitleColor(UIColor.white, for:.normal) button.addTarget(self, action: #selector(buttonEvent(_:)), for: UIControl.Event.touchUpInside) view.rightCalloutAccessoryView = button } return view } }
エラー内容
Could not cast value of type '(Swift.Optional<__C.MKDirectionsResponse>, Swift.Optional<__C.NSError>) -> ()' (0x1e172caf8) to '(Swift.Optional<__C.MKDirectionsResponse>, Swift.Optional<Swift.Error>) -> ()' (0x1e172cc30).
修正後コード
directions.calculate(completionHandler: { (response:MKDirections.Response?, error:Error?) -> Void in response!.routes.count if (error != nil || response!.routes.isEmpty) { return } let route: MKRoute = response!.routes[0] as MKRoute // 経路を描画 self.mapView.addOverlay(route.polyline) // 現在地と目的地を含む表示範囲を設定する self.showUserAndDestinationOnMap() })
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/25 03:46 編集
2019/12/25 07:10
2019/12/25 11:25
2019/12/25 21:18