iOS16から使えるようになった「Look Around API」を触ってみた!
この記事は「ニフティグループ Advent Calendar 2022」 12日目の記事です。
はじめに
こんにちは!ニフティライフスタイルでモバイルアプリの開発をしているsaikeiです。
今回はWWDC22で発表されiOS16から使えるようになった「Look Around API」を触ってみた所「思いのほか簡単に実装できた」のでご紹介させていただきます!
目次
今回作ったデモアプリ
入力された緯度軽度をもとに「Look Aroundのスナップショット」(静止画)の取得&操作可能なLook Around画面を開くという簡易的なデモアプリです。
Look Aroundを表示する
手順
MKLookAroundSceneRequest
に緯度経度を渡してリクエストを行いMKLookAroundScene
を取得MKLookAroundViewController
に①で取得したMKLookAroundScene
をセットする- ②で作成した
MKLookAroundViewController
に遷移する
…という僅か3ステップで表示させることができます!
それでは実際にコードを見ていきましょう。
// ① MKLookAroundSceneRequestを使用してリクエストを行う
let coordinate = CLLocationCoordinate2D(latitude: 35.710006, longitude: 139.810660)
let sceneRequest = MKLookAroundSceneRequest(coordinate: coordinate)
sceneRequest.getSceneWithCompletionHandler { scene, error in
guard error == nil, let scene = scene else {
return
}
// ② MKLookAroundViewControllerにsceneをセットする
let lookAroundViewController = MKLookAroundViewController(scene: scene)
// ③ presentで遷移する
present(lookAroundViewController, animated: true)
}
※ 上記を viewDidLoad
にコピペするだけで遷移まで行われます。
解説
AppleがLook Aroundを提供していない地点(緯度経度)の場合、 getSceneWithCompletionHandler
から返却される MKLookAroundScene
は nil
となります。
sceneさえ取得出来れば、あとは MKLookAroundViewController
に MKLookAroundScene
を渡してあげることで、APIとして提供されているLook Around専用のViewControllerが生成されます。
スナップショット(画像)を取得する
Look Aroundは実際に操作できるViewControllerの他に、サムネイルなどとして使用することが出来る「スナップショット」を取得することも出来ます。
手順
MKLookAroundSceneRequest
に緯度経度を渡してリクエストを行いMKLookAroundScene
を取得MKLookAroundSnapshotter
に①で取得したMKLookAroundScene
を渡す- ②で返却される
UIImage
をUIImageView
などにセットする
// ① MKLookAroundSceneRequestを使用してリクエストを行う
let coordinate = CLLocationCoordinate2D(latitude: 35.710006, longitude: 139.810660)
let sceneRequest = MKLookAroundSceneRequest(coordinate: coordinate)
sceneRequest.getSceneWithCompletionHandler { scene, error in
guard error == nil, let scene = scene else {
return
}
// ② スナップショットを取得する
let lookAroundSnapshotter = MKLookAroundSnapshotter(scene: scene, options: .init())
lookAroundSnapshotter.getSnapshotWithCompletionHandler{ snapshot, error in
guard let snapshotImage = snapshot?.image else {
return
}
// ③ snapshotImage(UIImage)を画面に表示する
self.snapShotImageView.image = snapshotImage
}
}
解説
①に関しては先ほどと変わらないので省略します。
②では MKLookAroundSnapshotOptions
でサイズ等のオプションも指定することができます。また、先ほどと同様に該当の地点でスナップショットが取得できなかった場合は nil
が返却されるのでこのタイミングで NotFound画像
などに差し替えることもできます。
さいごに
WWDC22で発表された際にはどの様に実装するのかな?と思っていましたが、実際に触ってみるととても少ないコードでLook Around機能を実装することができました。
今回は書き慣れているクロージャーで書きましたが、もちろんSwift Concurrencyにも対応しています!
また今回は「取り敢えず触ってみる」を目的としていましたが、調べていくと細かいオプションやカスタマイズも出来そうだったので色々と活用できるのかなと思いました。これだけの機能ですら無料で提供されているのは驚きですね!
最後に「おまけ」として、冒頭のデモアプリの全体コードとレイアウトを置いておくので、ぜひお手元でも試してみてください!
おまけ
※ デモ用のため例外処理などを省略しています
全体コード
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController {
// スナップショットを表示するUIImageView
@IBOutlet weak private var snapShotImageView: UIImageView!
// 緯度経度の受け取り
@IBOutlet weak private var inputLatitude: UITextField!
@IBOutlet weak private var inputLongitude: UITextField!
// 「取得」のタップイベント
@IBAction private func didTapSearchLocationButton(_ sender: Any) {
guard let latString = inputLatitude?.text,
let lonString = inputLongitude?.text,
let lat = CLLocationDegrees(latString),
let lon = CLLocationDegrees(lonString) else {
return
}
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
searchLookAround(coordinate: coordinate)
}
// 「LookAroundViewControllerを開く」ボタン
@IBOutlet weak private var openLookAroundViewButton: UIButton!
@IBAction private func didTapOpenLookAroundViewButton(_ sender: Any) {
guard let lookAroundViewController = lookAroundViewController else {
return
}
present(lookAroundViewController, animated: true)
}
// 「LookAroundViewController」を保持する
private var lookAroundViewController: MKLookAroundViewController? {
didSet {
openLookAroundViewButton.isEnabled = (lookAroundViewController != nil)
}
}
private func searchLookAround(coordinate: CLLocationCoordinate2D) {
let sceneRequest = MKLookAroundSceneRequest(coordinate: coordinate)
sceneRequest.getSceneWithCompletionHandler { scene, error in
guard error == nil, let scene = scene else {
self.setNotFound()
return
}
// スナップショットを作成
let lookAroundSnapshotter = MKLookAroundSnapshotter(scene: scene, options: .init())
lookAroundSnapshotter.getSnapshotWithCompletionHandler{ snapshot, error in
guard let snapshotImage = snapshot?.image else {
self.setNotFound()
return
}
// スナップショットをUIImageViewにセット
self.snapShotImageView.image = snapshotImage
// 「LookAroundViewControlelrを開く」ボタンを活性化
self.openLookAroundViewButton.isEnabled = true
// 「lookAroundViewController」プロパティにセット
self.lookAroundViewController = MKLookAroundViewController(scene: scene)
}
}
}
private func setNotFound() {
// NoImage画像をUIImageViewにセット
self.snapShotImageView.image = UIImage(systemName: "mappin.slash.circle.fill")
// 「LookAroundViewControlelrを開く」ボタンを無効化
self.openLookAroundViewButton.isEnabled = false
// 「lookAroundViewController」プロパティをnilにする
self.lookAroundViewController = nil
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
レイアウト
明日は @ShibataRyusei さんの「Flutterについての何かを書く」です。お楽しみに!
掲載内容は、記事執筆時点の情報をもとにしています。