AVCaptureDeviceDidStartRunningNotification
カメラデバイスの変更を検出する手段として使用できなくなったようです。また、上のcameraDevice
プロパティUIImagePickerController
はKVOでは機能しません。ただし、以下に示すように、カメラデバイスの変更を検出することは可能です(ただし、KVO準拠として明示的にマークされていないプロパティでKVOを使用しているため、このソリューションの長期的なサポートは保証されません)。
import AVFoundation
var context = 0
override func viewDidLoad() {
super.viewDidLoad()
// Register for notifications
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: #selector(handleCaptureSessionDidStartRunning(_:)), name: AVCaptureSessionDidStartRunningNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(handleCaptureSessionDidStopRunning(_:)), name: AVCaptureSessionDidStopRunningNotification, object: nil)
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func handleCaptureSessionDidStartRunning(notification: NSNotification) {
guard let session = notification.object as? AVCaptureSession else { return }
session.addObserver(self, forKeyPath: "inputs", options: [ .Old, .New ], context: &context)
}
func handleCaptureSessionDidStopRunning(notification: NSNotification) {
guard let session = notification.object as? AVCaptureSession else { return }
session.removeObserver(self, forKeyPath: "inputs")
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if context == &self.context {
if let inputs = change?[NSKeyValueChangeNewKey] as? [AnyObject], captureDevice = (inputs.first as? AVCaptureDeviceInput)?.device {
switch captureDevice.position {
case .Back: print("Switched to back camera")
case .Front: print("Switched to front camera")
case .Unspecified: break
}
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}
Swift 4+バージョン:
import AVFoundation
var context = 0
override func viewDidLoad() {
super.viewDidLoad()
// Register for notifications
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStartRunningNotification"), object: nil, queue: nil) { [weak self] notification in
self?.handleCaptureSessionDidStartRunning(notification: notification)
}
notificationCenter.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureSessionDidStopRunningNotification"), object: nil, queue: nil) { [weak self] notification in
self?.handleCaptureSessionDidStopRunning(notification: notification)
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
func handleCaptureSessionDidStartRunning(notification: Notification){
guard let session = notification.object as? AVCaptureSession else { return }
session.addObserver(self, forKeyPath: "inputs", options: [ .old, .new ], context: &context)
}
func handleCaptureSessionDidStopRunning(notification: Notification){
guard let session = notification.object as? AVCaptureSession else { return }
session.removeObserver(self, forKeyPath: "inputs")
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &self.context {
if let inputs = change?[NSKeyValueChangeKey.newKey] as? [AnyObject], let captureDevice = (inputs.first as? AVCaptureDeviceInput)?.device {
switch captureDevice.position {
case .back: print("Switched to back camera")
case .front: print("Switched to front camera")
case .unspecified: break
}
}
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}