Skip to content

Instantly share code, notes, and snippets.

@farshadmb
Last active January 14, 2022 22:11
Show Gist options
  • Save farshadmb/72492c31ee6919d2ccb1ff90af8f1f9d to your computer and use it in GitHub Desktop.
Save farshadmb/72492c31ee6919d2ccb1ff90af8f1f9d to your computer and use it in GitHub Desktop.
RxUIImagePickerView Delegation Handler
import Foundation

#if os(iOS)
import RxSwift
import RxCocoa
import UIKit

typealias RxImagePickerControllerDelegate = UIImagePickerControllerDelegate & UINavigationControllerDelegate

extension UIImagePickerController: HasDelegate {

    typealias Delegate = RxImagePickerControllerDelegate
}

private class RxUIImagePickerDelegateProxy: DelegateProxy<UIImagePickerController, RxImagePickerControllerDelegate>
                                            , DelegateProxyType
                                            , RxImagePickerControllerDelegate {

   weak private (set) var controller: UIImagePickerController?

    required init(controller: ParentObject) {
        self.controller = controller
        super.init(parentObject: controller, delegateProxy: RxUIImagePickerDelegateProxy.self)
    }

    static func registerKnownImplementations() {
        register { RxUIImagePickerDelegateProxy(controller: $0) }
    }
    
     static func currentDelegate(for object: UIImagePickerController) -> RxImagePickerControllerDelegate? {
        return object.delegate
    }

    static func setCurrentDelegate(_ delegate: RxImagePickerControllerDelegate?, to object: UIImagePickerController) {
        object.delegate = delegate
    }

}

extension Reactive where Base: UIImagePickerController {

    /// Reactive wrapper for `delegate`.
    ///
    /// For more information take a look at `DelegateProxyType` protocol documentation.
    var pickerDelegate: DelegateProxy<UIImagePickerController, RxImagePickerControllerDelegate> {
        RxUIImagePickerDelegateProxy.proxy(for: base)
    }

    /**
     Reactive wrapper for `delegate` message.
     */
    var didFinishPickingMediaWithInfo: Observable<[UIImagePickerController.InfoKey: AnyObject]> {
        return pickerDelegate
            .methodInvoked(#selector(UIImagePickerControllerDelegate.imagePickerController(_:didFinishPickingMediaWithInfo:)))
            .map({ (infos) in
                return try castOrThrow(Dictionary<UIImagePickerController.InfoKey, AnyObject>.self, infos[1])
            })
    }

    /**
     Reactive wrapper for `delegate` message.
     */
    var didCancel: Observable<()> {
        return pickerDelegate
            .methodInvoked(#selector(UIImagePickerControllerDelegate.imagePickerControllerDidCancel(_:)))
            .map { _ in () }
    }

}

private func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
    guard let returnValue = object as? T else {
        throw RxCocoaError.castingError(object: object, targetType: resultType)
    }

    return returnValue
}

#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment