Swift4 NotificationCenter と KeyValueObserver

GoogleMap の myLocation の現在位置が更新されたことを感知したい…。

だけど  GMSMapViewDelegate にはそんなメソッドなさそうだなぁ…と思い どうしたものかとググっていました。

Cocoaフレームワークには、KVOと呼ばれるオブザーバの機能を標準で擁しています。基本的な考え方は、KVO用に作られたメソッドを経由してプロパティを操作することで、適切にその変化をオブザーバに通知する、という仕組みです。KV...

KVO (Key Value Observer ?) …? プロパティの値の変化を監視することができる…!

 

…KVOについて、いくつかの記事をググったのですが、一番自分にグッときたのがこちらでした。

## はじめにKVOとはKey-Value Observingの略で、Objective-Cの時代からあるCoCoaフレームワークの基本的な機能です。フレームワークとしてはFoundationに含まれ、Notificationsに...

KeyPath<T, Value> がどうしたらいいかわからず困っていたけど、このサイトの “\.プロパティ名” の記述を試したら、うまくいきました。 KeyPath についてちゃんと飲み込まないと気持ち悪いけど…とりあえず良しで ^^;

 

しかし…最後のクロージャーの部分が色々な記述ができるというのが…まだ慣れてない… ^^;
メソッドの引数なのに、()の中を飛び越えて?、()の後ろに { … } と記述できる発想がまだ出来ない… ^^;

 

そんな感じで、ググった記事を元に実装した内容は以下になります。

/**
* KVO (Key Value Observer)
*
* GMSMapView (GoogleMap) の myLocation (CLLocation) の内容が変化したら...を取得
*/
import UIKit
import GoogleMaps
import CoreLocation
class MapViewController: UIViewController {
//GoogleMap
@IBOutlet weak var mapView: GMSMapView!
//KVO
private var keyValueObservations = [NSKeyValueObservation]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// MapView 初期化
self.initMapView(self.mapView)
//状態監視
if (true) {
//NotificationCenterの例
if (true) {
let center = NotificationCenter.default
//フォアグラウンドに復帰
center.addObserver(self,
selector: #selector(MapViewController.viewWillEnterForeground(_:)),
name: NSNotification.Name.UIApplicationWillEnterForeground,
object: nil)
//バックグラウンドに退避
center.addObserver(self,
selector: #selector(MapViewController.viewDidEnterBackground(_:)),
name: NSNotification.Name.UIApplicationDidEnterBackground,
object: nil)
}
//KVO (プロパティの変化を監視)
if (true) {
//GoogleMapの現在位置(myLocation)の更新を監視
let keyValueObservation = self.mapView.observe(\.myLocation, options: [.new, .old], changeHandler: { (mapView, change) in
//change.old:変更前、 change.new: 変更後
print(change)
})
//こんな感じにクロージャーを()の中から追い出して記述することもできた (まだこの発想に慣れていない)
//let keyValueObservation = self.mapView.observe(\.myLocation, options: [.new, .old]) { (mapView, change) in /* ... */ }
//あとで破棄するので、作成した NSKeyValueObservation を保持しておく
self.keyValueObservations.append(keyValueObservation)
}
}
}
//破棄
deinit {
//監視解除
if (true) {
//NotificationCenter
if (true) {
let center = NotificationCenter.default
center.removeObserver(self,
name: NSNotification.Name.UIApplicationWillEnterForeground,
object: nil)
center.removeObserver(self,
name: NSNotification.Name.UIApplicationDidEnterBackground,
object: nil)
}
//KVO
if (true) {
for keyValueObservation in self.keyValueObservations {
keyValueObservation.invalidate()
}
self.keyValueObservations.removeAll()
}
}
}
}
// MARK: - NotificationCenter
extension MapViewController {
//フォアグラウンドに復帰したとき
@objc internal func viewWillEnterForeground(_ notification: Notification) {
}
//バックグラウンドに退避したとき
@objc internal func viewDidEnterBackground(_ notification: Notification) {
}
}


Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です