質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2793閲覧

画面遷移時に情報を渡そうとすると、Thread 1: signal SIGABRT エラーが出る。

naoharuiwai

総合スコア18

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/09/17 19:36

編集2018/09/18 01:38

前提・実現したいこと

Swift初心者です。
勉強のために、以下の処理を行うマップアプリを作ろうとしています。

  1. アプリ起動時に、現在位置を中心としたマップを表示。

  2. 検索バーに「コンビニ」などとキーワードを入れ、検索ボタンを押す。

  3. 現在地周辺の、キーワードに合致する場所にピンが建てられる。

  4. ピンをタップすると、吹き出しが表示される。

  5. 吹き出し内の「追加」ボタンを押すと、画面が遷移し、場所の名称と住所が表示される。

上記5の処理を行う際、Thread 1: signal SIGABRTエラーが出てしまいました。
どうやら画面遷移を実行する際にエラーが出ているようです。
どなたか詳しい方、教えていただけないでしょうか。

発生している問題・エラーメッセージ

Thread 1: signal SIGABRT
以下のソースコード内、

sendAddress = placemark.subtitle

が呼び出される際にエラー発生

追記
ログ内に以下のようなエラーメッセージが出ていました。

TrackMap[48246:18256971] -[MKPlacemark subtitle]: unrecognized selector sent to instance 0x1c4c096b0 TrackMap[48246:18256971] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKPlacemark subtitle]: unrecognized selector sent to instance 0x1c4c096b0'

きちんと認識できておらず申し訳ありません。

該当のソースコード

Swift

1//ViewController.swift 2 3import UIKit 4import MapKit 5import CoreLocation 6 7class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate { 8 9 // 検索した地点名、 10 11 //CLLocationManagerの入れ物を生成 12 var myLocationManager = CLLocationManager() 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16 // Do any additional setup after loading the view, typically from a nib. 17 18 // 位置情報を利用して良いか許可を得る 19 myLocationManager.delegate = self 20 myLocationManager.requestWhenInUseAuthorization() 21 myLocationManager.startUpdatingLocation() 22 23 searchText.delegate = self 24 mapView.delegate = self 25 // TrackingMode変更のためのボタンを追加 26 let button = MKUserTrackingButton(mapView: mapView) 27 button.frame = CGRect(x: (self.mapView.bounds.width-50), y: 620, width: 40, height: 40) 28 self.view.addSubview(button) 29 self.view.bringSubviewToFront(button) 30 31 } 32 33 34 @IBOutlet weak var mapView: MKMapView! 35 @IBOutlet weak var searchText: UISearchBar! 36 37 // 地図上でLongPressが行われたときに実行される処理 38 @IBAction func longPressMap(_ sender: UILongPressGestureRecognizer) { 39 // マップ上のピンを削除 40 mapView.removeAnnotations(mapView.annotations) 41 //マップビュー内のタップした位置を取得する。 42 let location:CGPoint = sender.location(in: mapView) 43 //長押し終了 44 if (sender.state == UIGestureRecognizer.State.ended){ 45 46 //タップした位置を緯度、経度の座標に変換する。 47 let mapPoint:CLLocationCoordinate2D = mapView.convert(location, toCoordinateFrom: mapView) 48 let location = CLLocation(latitude:mapPoint.latitude, longitude: mapPoint.longitude) 49 50 //座標を住所に変換する。 51 let myGeocoder:CLGeocoder = CLGeocoder() 52 myGeocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error) in 53 54 if(error == nil) { 55 for placemark in placemarks! { 56 57 //ピンを地図に刺す。 58 let annotation = MKPointAnnotation() 59 annotation.coordinate = CLLocationCoordinate2DMake(mapPoint.latitude, mapPoint.longitude) 60 annotation.title = "住所" 61 annotation.subtitle = "(placemark.administrativeArea!)(placemark.locality!)(placemark.thoroughfare!)(placemark.subThoroughfare!)" 62 self.mapView.addAnnotation(annotation) 63 } 64 } else { 65 print("error") 66 } 67 }) 68 } 69 } 70 71 72 73 // CLLocationManagerのデリゲートメソッド。現在地情報を随時アップデートする。 74 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 75 // 最新の現在地情報を格納する 76 guard let newLocation = locations.last else { 77 return 78 } 79 // 格納した位置情報を元に再度緯度経度情報を作成 80 let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude) 81 82 let span = MKCoordinateSpan.init(latitudeDelta: 0.01, longitudeDelta: 0.01) // 表示する範囲を設定 83 let region = MKCoordinateRegion.init(center: location, span: span) // 中心を現在地に、表示する範囲を設定した範囲にする 84 mapView.setRegion(region, animated: false) // mapViewに反映 85 //mapView.userTrackingMode = MKUserTrackingMode.follow// 自分が移動しても常にmapの中心を自分の位置にするように設定 86 87 manager.stopUpdatingLocation() 88 89 } 90 91 //位置情報取得に失敗したときに呼び出されるメソッド 92 func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { 93 print("error") 94 } 95 96 97 98 // 検索ボタンを押したときに実行されるメソッド 99 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 100 // キーボードを閉じる 101 searchText.resignFirstResponder() 102 // ピンを削除する 103 mapView.removeAnnotations(mapView.annotations) 104 // 検索条件を作成する 105 let request = MKLocalSearch.Request() 106 request.naturalLanguageQuery = searchText.text 107 // 検索範囲はマップビュー上に表示されている範囲と同じにする 108 request.region = mapView.region 109 // ローカル検索を実行する 110 let localSearch: MKLocalSearch = MKLocalSearch(request: request) 111 localSearch.start(completionHandler: {(result,error) in 112 113 for placemark in (result?.mapItems)! { 114 if(error == nil){ 115 // 検索された場所にピンを刺す 116 let annotation = MKPointAnnotation() 117 annotation.coordinate = CLLocationCoordinate2DMake(placemark.placemark.coordinate.latitude, placemark.placemark.coordinate.longitude) 118 annotation.title = placemark.placemark.name 119 annotation.subtitle = placemark.placemark.title 120 self.mapView.addAnnotation(annotation) 121 } else { 122 print(error) 123 } 124 } 125 }) 126 127 } 128 129 130 // viewForAnnotationデリゲートメソッド。ピンが生成される直前に呼ばれる。 131 // 吹き出しを表示するようにし、右側に「追加」ボタンを生成するようにする。 132 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 133 if annotation is MKUserLocation{ 134 return nil 135 } else { 136 137 let identifier = "annotation" 138 if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier){ 139 // 再利用できる場合はそのまま返す 140 return annotationView 141 } else { 142 // 再利用できるアノテーションが無い場合(初回など)は生成する 143 let myPinIdentifier = "PinAnnotationIdentifier" 144 //ピンをインスタンス化 145 let pinByLongPress = MKPointAnnotation() 146 //アノテーションビュー生成 147 let annotationView = MKPinAnnotationView(annotation: pinByLongPress, reuseIdentifier: myPinIdentifier) 148 //ピンが降ってくるアニメーションをつける 149 annotationView.animatesDrop = true 150 //吹き出しを表示させる 151 annotationView.canShowCallout = true 152 // 吹き出し内の右側に「追加」ボタンを作成 153 let rightButton = UIButton() 154 rightButton.frame = CGRect(x: 0, y: 0, width: 80, height: 40) 155 rightButton.setTitle("追加", for: UIControl.State.normal) 156 rightButton.backgroundColor = UIColor.blue 157 rightButton.tag = 1 158 annotationView.rightCalloutAccessoryView = rightButton 159 160 return annotationView 161 } 162 } 163 164 } 165 166 167 // 次の画面に渡す情報を格納するための変数 168 var sendName: String? // 名称格納用 169 var sendAddress: String? // 住所格納用 170 171 // 吹き出しがタップされた場合に呼ばれるメソッド 172 func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { 173 // ピンの位置情報を得る 174 let coordinate = CLLocationCoordinate2DMake((view.annotation?.coordinate.latitude)!, (view.annotation?.coordinate.longitude)!) 175 let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: nil) 176 177 sendName = placemark.title 178 sendAddress = placemark.subtitle 179 180 self.performSegue(withIdentifier: "goConfirm", sender: nil) 181 } 182 183 // 画面遷移する時に情報を渡す 184 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 185 if let nextViewController = segue.destination as? ConfirmViewController{ 186 // 次の画面のインスタンスに取得した画像を渡す 187 nextViewController.name = sendName 188 nextViewController.address = sendAddress 189 print("情報は渡された") // ログ 190 } 191 } 192 193 194 195 196}
// ConfirmViewController.swift import UIKit class ConfirmViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. nameLabel.text = name addressLabel.text = address } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ var name:String? // 前画面から渡された名称を格納する変数 var address:String? // 同じく住所を格納する変数 @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var addressLabel: UILabel! }

試したこと

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)

内にbreakpointを設定してデバッグしたところ、どうやら

sendAddress = placemark.subtitle

が呼び出される際にエラーが起こっているようでした。

補足情報(FW/ツールのバージョンなど)

Swift4.2
Xcode10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/09/18 00:55

セグエの Identifier に goConfirm を設定していますか?
naoharuiwai

2018/09/18 00:58

はい、設定しています。
fuzzball

2018/09/18 01:01

print("情報は渡された") は表示されていますか?
naoharuiwai

2018/09/18 01:03

いえ、そのログは表示されていません、、。
fuzzball

2018/09/18 01:06

StoryboardのConfirmViewControllerにアウトレットのゴミが残ってないでしょうか?Connections inspectorで確認して下さい。(黄色いマークが付いていないかどうか)
naoharuiwai

2018/09/18 01:26

見たところ、黄色いマークは付いておらず、きちんとコネクションはできているようでした。あとすみません、エラーメッセージをきちんと書けていなかったので、修正しました。
fuzzball

2018/09/18 01:33

一つ上の sendAddress = placemark.subtitle で落ちてません?
naoharuiwai

2018/09/18 01:39 編集

確認不足でした。そうですね、申し訳ありません、、。 これは、「placemark.subtitleに該当するものが無いよー」という意味のエラーメッセージでしょうか?
fuzzball

2018/09/18 01:49

subtitleそのものが無い(値が無いのではなく)というエラーですね。なんでだろ。print(type(of: placemark)) の出力を教えてもらえますか?
naoharuiwai

2018/09/18 01:53

print(type(of: placemark))の出力は、 MKPlacemark でした。
guest

回答1

0

ベストアンサー

MKPlacemarkにsubtitleはありません。

MKPlacemarkはMKAnnotationプロトコルに準拠していますが、titleもsubtitleもoptionalです。
MKPlacemarkはtitleにしか対応していないということだと思います。

swift

1optional public var title: String? { get } 2optional public var subtitle: String? { get }

投稿2018/09/18 01:56

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

naoharuiwai

2018/09/18 02:08

ご教授ありがとうございます。試しにsendaddress = placemark.subtitleを削除して実行すると、うまく画面遷移されました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問