見出し画像

【徒然iOS】気ままにUIKit59〜MKLocalSearch 店名やキーワードで検索してピンを刺す〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をハイ、レッツゴ🕺

前準備

念の為、

  1. バックアップ

  2. 新しいクラス

  3. ビューコントローラの追加

  4. イニシャルビューの変更

をいつも通りやってから本題へ💃

こんな感じかな💦

本題

と、今回のサイト記事は後半に、

Google Place API

が絡んでるんだけど、

CocoaPodsなんかが絡んでくる
記事のとおりの仕様と年数も経っていて、
APIのやり方や名前自体も変わってる可能性が高い
👉作業コストが膨大になるので、前半のみの操作をやる〜〜〜🕺

やりたい人は自分でやってね〜〜〜

⒈VerticalStackViewの中にSearchBarとMapKit配置

まずはMapKit〜〜〜
選んで〜〜〜
追加すると赤いエラーが発生
IOS13.0以降だと、、、、
コイツがデプロイ(実装)できないって言ってるみたいだね👀
削除するとエラー消えた〜〜〜🕺
VStackに制約を追加すると〜〜〜
赤いコンフリクト警告も消えた〜〜〜
幅を調整してもコンフリクトは起きてないね👀
シミュレータで実行しても、入力欄も含めて問題なさげ👀

⒉コードを参考に、パーツをアウトレット接続

//
//  ViewController.swift
//
import UIKit
import MapKit
class ViewController: UIViewController, UISearchBarDelegate{
    @IBOutlet weak var testSearchBar: UISearchBar!
    @IBOutlet weak var testMapView: MKMapView!
    var testManager:CLLocationManager = CLLocationManager()
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //中心座標
        let center = CLLocationCoordinate2DMake(35.690553, 139.699579)
        //表示範囲
        let span = MKCoordinateSpanMake(0.001, 0.001)
        //中心座標と表示範囲をマップに登録する。
        let region = MKCoordinateRegionMake(center, span)
        testMapView.setRegion(region, animated:true)
        //デリゲート先を自分に設定する。
        testSearchBar.delegate = self
    }
    //検索ボタン押下時の呼び出しメソッド
    func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        //キーボードを閉じる。
        testSearchBar.resignFirstResponder()
        //検索条件を作成する。
        let request = MKLocalSearchRequest()
        request.naturalLanguageQuery = testSearchBar.text
        //検索範囲はマップビューと同じにする。
        request.region = testMapView.region
        //ローカル検索を実行する。
        let localSearch:MKLocalSearch = MKLocalSearch(request: request)
        localSearch.startWithCompletionHandler({(result, error) in
            for placemark in (result?.mapItems)! {
                if(error == nil) {
                    //検索された場所にピンを刺す。
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = CLLocationCoordinate2DMake(placemark.placemark.coordinate.latitude, placemark.placemark.coordinate.longitude)
                    annotation.title = placemark.placemark.name
                    annotation.subtitle = placemark.placemark.title
                    self.testMapView.addAnnotation(annotation)
                } else {
                    //エラー
                    print(error)
                }
            }
        })
    }
}

を確認すると、どちらもアウトレット接続だけみたいなので、

接続〜〜〜
接続〜〜〜
ハイ、完了🕺

⒊⒉のコードを参考にコードを組み込む〜〜〜

手直しして組み込み後に出てきたけど、PINが新しいままだから気に入らない。

例の如く、コードにアノテーションメソッドを追加〜〜〜

今回のコード(まとめ)

class MapSearchingViewController: UIViewController, UISearchBarDelegate, MKMapViewDelegate {
    @IBOutlet weak var mySearchBar: UISearchBar!
    @IBOutlet weak var myMapKitView: MKMapView!
    
    let x = 139.692101
    let y = 35.689634
    let latitudeDelta = 0.01
    let longitudeDelta = 0.01
    
    var testManager:CLLocationManager = CLLocationManager()
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //中心座標
        let center = CLLocationCoordinate2DMake(y, x)
        //表示範囲
        let span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
        //中心座標と表示範囲をマップに登録する。
        let region = MKCoordinateRegion(center: center, span: span)
        myMapKitView.setRegion(region, animated:true)
        //デリゲート先を自分に設定する。
        myMapKitView.delegate = self
        mySearchBar.delegate = self
    }
    //検索ボタン押下時の呼び出しメソッド
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        //キーボードを閉じる。
        mySearchBar.resignFirstResponder()
        //検索条件を作成する。
        let request = MKLocalSearch.Request()
        request.naturalLanguageQuery = mySearchBar.text
        //検索範囲はマップビューと同じにする。
        request.region = myMapKitView.region
        //ローカル検索を実行する。
        let localSearch:MKLocalSearch = MKLocalSearch(request: request)
        localSearch.start(completionHandler: {(result, error) in
            for placemark in (result?.mapItems)! {
                if(error == nil) {
                    //検索された場所にピンを刺す。
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = CLLocationCoordinate2DMake(placemark.placemark.coordinate.latitude, placemark.placemark.coordinate.longitude)
                    annotation.title = placemark.placemark.name
                    annotation.subtitle = placemark.placemark.title
                    self.myMapKitView.addAnnotation(annotation)
                } else {
                    //エラー
                    print(error)
                }
            }
        })
    }
    //アノテーションビューを返すメソッド
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let myView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
        //吹き出しを表示可能にする。
        myView.canShowCallout = true
        return myView
    }
}

⒋シミュレータで実行

PINが旧型に戻った〜〜〜

と見てみると、サイト記事では10件とか言ってたけど、全然10件以上出てきてないか?🤔

なので、やはり当時と違って、機能が改善されてるっぽいいいいい🕺

てか正直、

近くのキーワード検索で、

10件以上とかヒット必要か?
10件以上とか出てきても、
情報が多くて目移りして個人的には困る💦
最直近の店しかどうせ行かないし。

なので、冒頭に述べたとおり今回のサイト記事の内容は以上。

ブラッシュアップは今回もここまでで終わってるので、お遊び

「国会議事堂周辺のコンビニを確認してみたい」

ので〜〜〜
やり方は色々あろうが、
中心の緯度経度を国会議事堂に変更して👀

ふむふむ👓
変更した🕺
入力して
検索結果でめちゃくちゃ出てきたね🕺
参議院はファミマ
衆議院はMマート

もし自分が国会議員になるなら、一回も行ったことないから、衆議院のMマートに心惹かれるが、場所が遠いなああorz
ファミマもいいけど💦

とまあ、

地図アプリって無限に遊べるよね〜〜〜〜

今回のポイント

サイトの記事なんかを参考にするだけで、実際に動かしてみないと、
すでに機能が改善されていたり、API自体が存在しなくなっていることも多いので、
動かしてもいないのにネットの記事を要求決定段階で鵜呑みにしない。

百聞は一見に如かず。
百見は一触に如かず。

情報だけを見て、聞いてそうだと思い込まずに、

「今でも本当にそのとおりか?」

と疑って、

とにかく動かして確認する🕺

要求段階で、ネットの記事だけでできると判断して、エンジニアさんに依頼とかすると、結構、パワハラにしかならなかったりする。

特にGoogleAppsScriptを使ってる現場で多いのだが藁🤣

Apple公式

さて次回は

をレッツゴする🕺

この記事が気に入ったらサポートをしてみませんか?