#はじめに
唐突ですが、あなたはパン屋を検索できるアプリを作っているとします。
オートコンプリートで簡単に検索できる機能を実装しようとしますが、関係のないお店が出てきてしまうかもしれません。
今回はパン屋のみを検索できるように改善してみようと思います。
参考:WWDC19 What’s New in MapKit and MapKit JS
https://developer.apple.com/videos/play/wwdc2019/236/
#開発環境
Xcode 13.0
Swift 5.5
#オートコンプリートとは
文字を途中まで入力すると、候補を出してくれる機能のことです。
MapkitのMKLocalSearchCompleterで簡単に実装できます。
#POIとは
Point Of Interestの略で、学校や動物園などの場所のことを示します。
Mapkitの場合、MKPointOfInterestCategoryのようにカテゴリーが用意されていて、40種類以上あります。
#基本の実装
まずは簡単に検索機能を実装してみます。
StoryBoard
TextFieldとTableViewのシンプルなものにします。
TableViewCellのCellStyleをsubtitleにし、Identifierはcellとします。
オートコンプリートを実装
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var tableView: UITableView!
var searchCompleter = MKLocalSearchCompleter()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchCompleter.delegate = self
}
@IBAction func textEditingChanged(_ sender: Any) {
searchCompleter.queryFragment = textField.text ?? ""
}
}
extension ViewController: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
tableView.reloadData()
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
print("error: \(error)")
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {![Something went wrong]()
return searchCompleter.results.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else { return UITableViewCell() }
return cell
}
}
とても簡単に実装できました。
これでTextFieldに入力するとパン屋が検索できるはずです!
試しに僕の好きな『パンのトラ』を検索してみます。
検索はできてますね。
でも、パン屋以外の検索結果も表示されてしまいます。
パン屋を検索するアプリとしてはダメです。
#POIフィルタリングする
ここからが本題です。
pointOfInterestFilterとResultTypeを使って改善していきます。
let pointOfInterestFilter = MKPointOfInterestFilter(including: [.bakery])
まずはMKPointOfInterestFilterのカテゴリーを設定します。今回はベーカリーです。
override func viewDidLoad() {
super.viewDidLoad()
searchCompleter.pointOfInterestFilter = pointOfInterestFilter
searchCompleter.resultTypes = .pointOfInterest
}
viewDidLoad()にこの二行を追加します。
searchCompleter.pointOfInterestFilter = pointOfInterestFilter
これでsearchComleterにpointOfInterestFilterを適用しています。
searchCompleter.resultTypes = .pointOfInterest
こちらは、searchCompleterのresultTypesをPOIに制限しています。
ちなみに、POIに制限しないと...
このように、地名なども検索に引っかかってしまいます。
では、実際に動かしてみましょう。
ご覧の通り、パン屋だけが検索結果として返ってきています。
うまくいきました。
これらの検索結果を利用してLocalSearchにかけてあげれば、緯度経度なども取得できるようになります。
また別でその記事を書いてみようかなと思います。
では、良きパンライフを!