RxSwiftを使い、UIImagePickerControllerをラップしたクラス。
import Foundation
import UIKit
import Photos
import RxSwift
import RxCocoa
final class RxImagePicker: NSObject {
private let didFinishPickingMediaSubject: PublishSubject<UIImage> = PublishSubject<UIImage>()
private let didCancelSubject: PublishSubject<Void> = PublishSubject<Void>()
public var didFinishPickingMedia: Observable<UIImage> { return didFinishPickingMediaSubject.asObserver() }
public var didCancel: Observable<Void> { return didCancelSubject.asObserver() }
public func selectImage(viewController fromViewController: UIViewController, tintColor: UIColor? = nil, allowEditing: Bool = false) {
checkPermission()
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraAction = UIAlertAction(title: "写真を撮る", style: .default) { (UIAlertAction) -> Void in
self.selectFromCamera(fromViewController: fromViewController, allowEditing: allowEditing)
}
let libraryAction = UIAlertAction(title: "アルバムから選ぶ", style: .default) { (UIAlertAction) -> Void in
self.selectFromLibrary(fromViewController: fromViewController, allowEditing: allowEditing)
}
let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (UIAlertAction) -> Void in
fromViewController.dismiss(animated: true, completion: nil)
}
alertController.view.tintColor = tintColor
alertController.addAction(cameraAction)
alertController.addAction(libraryAction)
alertController.addAction(cancelAction)
fromViewController.present(alertController, animated: true, completion: nil)
}
func checkPermission() {
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized:
print("Access is granted by user")
case .notDetermined:
PHPhotoLibrary.requestAuthorization({
(newStatus) in
print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized {
/* do stuff here */
print("success")
}
})
print("It is not determined until now")
case .restricted:
// same same
print("User do not have access to photo album.")
case .denied:
// same same
print("User has denied the permission.")
}
}
private func selectFromCamera(fromViewController: UIViewController, allowEditing: Bool) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = UIImagePickerControllerSourceType.camera
imagePickerController.allowsEditing = allowEditing
fromViewController.present(imagePickerController, animated: true, completion: nil)
} else {
print("カメラ許可をしていない時の処理")
}
}
private func selectFromLibrary(fromViewController: UIViewController, allowEditing: Bool) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePickerController.allowsEditing = allowEditing
fromViewController.present(imagePickerController, animated: true, completion: nil)
} else {
print("カメラロール許可をしていない時の処理")
}
}
}
extension RxImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
didCancelSubject.onNext(())
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
didFinishPickingMediaSubject.onNext(image)
}
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
didFinishPickingMediaSubject.onNext(image)
}
picker.dismiss(animated: true, completion: nil)
}
}