ダーヤス.com プレミアム

ダーヤス.comにようこそ。プレミアムな情報で、ワークライフバランスの充実を図りませんか。

【Swift】【iOS】プライマリ言語を日本語、MKMapViewの地図内に現在位置を表示、ピンをタップしたタイミングで処理を行うようにするなど。

      2016/05/25

宇都宮育自アプリ

MKMapViewの地図内に現在位置を表示

とりあえず、栃木県宇都宮市の赤ちゃんの駅と幼稚園一覧を地図表示するアプリを作ってみる。で書いたように、宇都宮の育自に役立つ場所等の情報が宇都宮市のオープンデータから取得できることがわかったので、地図上にピンでマッピングできるアプリを作って申請してみました。

今回の目的はまあ宇都宮市での育自に役立つアプリを作ることなのですが、自分としては別に、以下の3点を試してみることを目標としていました。

1.プライマリ言語を日本語、配布テリトリを日本だけにする。
2.MKMapViewの地図内に現在位置を表示する。
3.ピンをタップしたタイミングで処理を行うようにする。

1.プライマリ言語を日本語、配布テリトリを日本だけにする。

これ一度やってみたかったのですが、今まで二の足を踏んでいました。

というのも、アプリの審査ってアメリカでされているような気がして、そうすると必然的に英語必要。
iTunesConnectからの情報を基本英語だしxcodeも英語基本だから、日本語みたいなマイナー言語だけしか使ってないアプリは審査官の方が読めないから拒絶になるんじゃなかろうかと。
でも日本語オンリーのアプリなんて世の中いくらでもあるし、問題ないのかなあとも思ったり、でもそういうのは信頼のおける企業とか団体が作っているからであって、私のような素性の知れない一個人が作ってるものなんかあっさり拒絶になるんじゃないかと。

そういうわけで、いつもプライマリ言語を英語、ローカライズで日本語を採用して、いつも頑張って英語を書いているわけです。

が、別に配布エリアを一部の地域のみに限定する選択肢もあるし、別に英語を言語として選ばない選択肢も選べるわけだから、本当に英語がないとダメなのかどうか一度確認してみる必要がある。
というわけで、絶対日本でしか必要とされないようなアプリを作ってみることにしまして、上記のような栃木県宇都宮でしか使われないアプリの作成を試みたわけです。
配布地域も日本のみ、言語も日本語のみとして申請してみましたので、来週の審査結果が楽しみです。

2.MKMapViewの地図内に現在位置を表示する。

これ意外と苦労しましたわ。
2年くらい前に、objective-cでやっていた時はあっさり参考書に書いてあったのですが、最近のxcodeの仕様でかつswiftでやる場合にどうしていいのか戸惑いました。
結果、swiftで現在地と目的地を結ぶ経路を地図に表示するに助けられました。
とても助かった部分を引用。

位置情報の取得許可を設定するため、Supporting Files の Info.plistを右クリックから「Open as」-「Source Code」で開いて以下の4行を追加
Info.plist

・・・ここから・・・
NSLocationAlwaysUsageDescription
I have learned more on stack overflow than anything else
NSLocationWhenInUseUsageDescription
The spirit of stack overflow is coders helping coders
・・・ここまで・・・

この設定やらないでずっと苦しんでましたわ。。。
あるいは、上記のように直接書き込まなくても、Info.plistを普通に開いて、keyに「NSLocationAlwaysUsageDescription」(候補として出てこないので自分で打つしかない)、typeを「string」、valueに「I have learned more on stack overflow than anything else」を打つ(あるいは空欄でもいいような気がしますけど)を設定してもいけると思います。
まあ、自分でテキストファイルに打った方が楽ですが。

あと注意点としては、targets-general-Linked frameworks and librariesで「MapKit.framework」と「CoreLocation.framework」を選んでおくのを忘れずに。
(と書きましたが、これもしかしたら自分でやらなくても、後述のimport文とデリゲート宣言を書いておけば、run時に自動的に補填されたような気がしたのですが、私の妄想かな。。。。)

viewController.swiftに、
import MapKit
import CoreLocation
を書き、クラスの宣言のところで
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
と書いておく。

そして実際のコーディングはこちらのページに助けられました。
はたけアーカイブ 【技術】swiftで地図情報を利用してみた

今回、ジオフェンスは使ってないので、「位置情報を取得する為の設定」の項目と「地図を表示する為の設定」、「現在地の取得を開始」がとても助かりました。
最初にvar locationManager:CLLocationManager!を宣言しておいて、別途self.locationManager=CLLocationManager()を設定しなきゃいけないのかどうかはまだ試してないですが。。。
(var locationManager:CLLocationManager = CllocationManager()ではダメ?)

「locationManager.requestAlwaysAuthorization() 」、「locationManager.delegate=self」、「mapView.delegate=self」、「mapView.showsUserLocation=true 」は必須でしょうね。
特に最後のは、つい書くの忘れてて、ずっと苦しみました。

「現在地の情報を取得(startUpdatingLocationを呼ぶと自動的に呼ばれる)」の項目でAnyObjectを使ってますが、今はswiftの仕様が変わって、多分CLLocationになっているかもしれません。

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {}

これを応用して、「今」ボタンを押せば現在地に移動し、「宮駅」ボタンを押せば宇都宮駅を中心に移動する機能が実装できました。
前者のコードはこちら。
「今」ボタンを押すと「nowPosition」のメソッドが行われます。

    func nowPosition() {
        //現在地を基準に地図を表示
        let manager: CLLocationManager = CLLocationManager()
        let centerCoordinate : CLLocationCoordinate2D = CLLocationCoordinate2DMake(manager.location!.coordinate.latitude,manager.location!.coordinate.longitude)
        let span = MKCoordinateSpanMake(0.1, 0.1)
        let centerPosition = MKCoordinateRegionMake(centerCoordinate, span)
        mapView.setRegion(centerPosition, animated: true)
        
    }

3.ピンをタップしたタイミングで処理を行うようにする。

今回、ピンをタップすると、タイトル欄に「施設名」、サブタイトルにその他の住所とか電話番号とかを設定しているのですが、明らかに吹き出しの面積が小さすぎて、途中で途切れて「・・・」になっちゃうのですよ。
そういうわけで、地図の下にUILabelを設けて、ピンをタップすると、subTitleの全文がそこのラベルに表示されるようにしたかったのです。

結果、ここで参考になる質問をされている人がいらっしゃって、助かりました。

stack overflow MKMapのピンを押したタイミングで処理を行いたい

これによれば、「MKMapViewDelegateのdidSelectAnnotationView」を使うと成し遂げられるらしい。
というわけで、以下のように書いてみましたところうまくいった。

//アノテーションがタップされると行う処理
    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
        let annotation = view.annotation//タップされたアノテーションを取得
        self.statusLabel.text = "\(annotation!.title!!)\r\(annotation!.subtitle!!)"//アノテーションに設定されたタイトルとサブタイトルをラベルに表示
        
    }

あといろいろ苦労した点ありますけど、主にはこんな感じ。

 - アプリ開発