プロジェクトに「PhotoAnnotation.swift」ファイルを追加しましょう。[ナビゲータエリア]上の[PhotoMap]項目を右クリックして、出てきたメニューの[New File]を選択します。
テンプレート選択画面が表示されるので、[Cocoa Touch Class]を選択し、[Next]をクリックします。
追加するクラスのオプションについて以下のように入力し、[Next]をクリックします。
ファイルの保存先を選択します。以前の記事で作成した「ViewController.swift」ファイルと同じフォルダーを選択し、[Create]をクリックします。
これで「PhotoAnnotation.swift」ファイルがプロジェクトに追加されます。
実装する内容は以下の通りです。順に説明していきます。
import UIKit import MapKit import Photos class PhotoAnnotation: NSObject, MKAnnotation { var coordinate: CLLocationCoordinate2D var title: String? var subtitle: String? var address :String? var image :UIImage? let asset :PHAsset? init(asset aAsset:PHAsset) { asset = aAsset coordinate = aAsset.location.coordinate super.init() self.executeGeocode() } private func executeGeocode() { if let aAsset = self.asset { CLGeocoder().reverseGeocodeLocation( aAsset.location, completionHandler: {(placemarks, error) -> Void in if error == nil && placemarks.count > 0 { if let placemark = placemarks.first as? CLPlacemark { self.title = placemark.name self.subtitle = (placemark.administrativeArea ?? "") + (placemark.locality ?? "") self.address = (self.subtitle ?? "") + (placemark.thoroughfare ?? "") } } } ) } } }
MapKitフレームワークとPhotosフレームワークをimportする記述を追加します。
任意のクラスを注釈オブジェクトとして使用するには、「MKAnnotation」プロトコルを採用する必要があります。
「プロトコル」はメソッドやプロパティの宣言が集まったものです。例えば、MKAnnotationプロトコルの場合は、注釈オブジェクトが持つべきメソッドやプロパティが定義されています。プロトコルを採用するために必要なことは、「クラス名: 」の後に採用するプロトコル名を記述し、定義されたメソッドやプロパティを実装することです。
プロトコルで定義されるメソッドやプロパティの中には、実装が任意のものと必須ものがあります。PhotoAnnotationクラスがMKAnnotationプロトコルを採用するに当たって実装が必須なのはcoordinateプロパティのみとなっています。
6〜8行目の「coordinate」「title」「subtitle」プロパティは、MKAnnotationプロトコルで定義されているものです。「title」「subtitle」は値がnilになる場合があるので「String?」型にしています。
10行目のaddressプロパティには撮影場所の住所を格納しておき、後に作成する詳細画面で使用します。11行目のimageプロパティには注釈ビューで使用するサムネイル画像のUIImageを格納します。
address/imageプロパティに関しても値がnilになる場合があるので、それぞれ「String?」と「UIImage?」型にしています。
13行目のassetプロパティにはフォトライブラリから取得した画像のPHAssetを格納します。
次に説明するinitメソッド内で値を格納した後は値を再代入しないので定数にしています。型は「PHAsset?」です。
PhotoAnnotationクラスでは、引数がPHAsset1つのイニシャライザーを定義しています。
15行目で定義しているイニシャライザーは「指定イニシャライザー」に分類されるイニシャライザーであり、そのクラスで定義している全てのプロパティに初期値を与えなければなりません。
PhotoAnnotationクラス場合は、coordinate以外のプロパティはオプショナル型なので初期値は自動的にnilになります。ですので、最低限、coordinateプロパティに初期値を与えれば問題ありません。
また、イニシャライザーの実装の中でスーパークラス(PhotoAnnotationの場合はNSObject)のイニシャライザーを呼ぶ必要がありますが、その前に全てのプロパティに初期値を与える必要があります。
「スーパークラスで定義されているプロパティへの値の設定」や「selfを使ったアクセス」は、スーパークラスのイニシャライザーを呼んだ後であれば可能です。
20行目で呼び出しているexecuteGeocodeメソッドについては次に説明します。
executeGeocodeメソッドでは、CLGeocoderのreverseGeocodeLocationメソッドを使用して緯度経度データから住所文字列を作成しています。
31と32行目ではnil結合演算子「??」を使用しています。「??」の前の変数の値がnilでなければその変数の値が使われ、nilであれば「??」の後ろの値が使われます。
self.subtitle = (placemark.administrativeArea ?? "") + (placemark.locality ?? "")
Copyright © ITmedia, Inc. All Rights Reserved.