Posted at

カメラと写真の許可状態の取得をRxSwiftと絡める

More than 1 year has passed since last update.

開発中のアプリでカメラと写真の許可状態を取得しつつ、その状態に合わせてPickerを表示するor許可してくださいの画面を出し分けるというのをRxで組みたかったので小さいextensionを書いた。


写真の許可状態を取得する

extension Reactive where Base: PHPhotoLibrary {

static func requestAuthorization() -> Single<PHAuthorizationStatus> {
return .create { observer in
let status = Base.authorizationStatus()
switch status {
case .notDetermined:
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async {
observer(.success(status))
}
}
default:
observer(.success(status))
}
return Disposables.create()
}
}
}


カメラの許可状態を取得する

extension Reactive where Base: AVCaptureDevice {

static func requestAuthorization(for mediaType: AVMediaType) -> Single<AVAuthorizationStatus> {
return .create { observer in
let status = Base.authorizationStatus(for: mediaType)
switch status {
case .notDetermined:
AVCaptureDevice.requestAccess(for: mediaType) { authorized in
DispatchQueue.main.async {
observer(.success(authorized ? .authorized : .denied))
}
}
default:
observer(.success(status))
}
return Disposables.create()
}
}
}

いずれも事前にstatusが取れるので、取得し、notDetermined ならrequestを行い、ユーザーに許可ダイアログを表示し、その結果を返すようにする。

それ以外の場合はすぐにobserverに値を流し込むようにしている。


利用例

ボタンのイベントなりと組み合わせて、それに応じてPickerを表示したり、許可してねというアラートを出しつつ設定画面に飛ばしたり、を実装している。

albumButton.rx.tap

.flatMap { PHPhotoLibrary.rx.requestAuthorization() }
.map { $0 == .authorized }
.bind { authorized in
if authorized {
// pickerを表示
} else {
// アクセス許可してねというアラートなりを表示
}
}
.disposed(by: disposeBag)