A reactive wrapper built around UIImagePickerController.

Overview

RxMediaPicker

RxMediaPicker is a RxSwift wrapper built around UIImagePickerController consisting in a simple interface for common actions like picking photos or videos stored on the device, recording a video or taking a photo.

Swift Version License Platform Carthage compatible

If you ever used UIImagePickerController you know how it can become quite verbose and introduce some unnecessary complexity, as you use the same class to do everything, from picking photos or videos from the library, recording videos, etc. At the same time, you have all these different properties and methods which can be used when you are dealing with photos, others for when you're dealing with videos, and others in all cases.

If you're interested, check the resulting article RxMediaPicker — picking photos and videos the cool kids’ way!

Note: As RxMediaPicker is still in its early days, the interface may change in future versions.

Features

  • Reactive wrapper built around UIImagePickerController.
  • Provides an interface for common operations like picking photos from the library, recording videos, etc.
  • Handles edited videos properly - something UIImagePickerController doesn't do for you!
  • Decouples the typical UIImagePickerController boilerplate from your code.
  • Reduces the complexity when compared to UIImagePickerController.
  • Easy to integrate and reuse accross your app.

Example

For a more complete example please check the demo app included (ideally run it on a device). This is how you would record a video using the camera:

import RxMediaPicker
import RxSwift

var picker: RxMediaPicker!
let disposeBag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()
    picker = RxMediaPicker(delegate: self)
}

func recordVideo() {
    picker.recordVideo(maximumDuration: 10, editable: true)
        .observeOn(MainScheduler.instance)
        .subscribe(onNext: { url in
            // Do something with the video url obtained!
        }, onError: { error in
            print("Error occurred!")
        }, onCompleted: {
            print("Completed")
        }, onDisposed: {
            print("Disposed")
        })
        .disposed(by: disposeBag)
}

Usage

Available operations

Based on their names, the operations available on RxMediaPicker should be self-explanatory. You can record a video, or pick an existing one stored on the device, and the same thing happens for photos. The only thing to note here is that picking a video will get you the video url, and picking a photo will get you a tuple consisting in the original image and an optional edited image (if any edits were made).

func recordVideo(device: UIImagePickerController.CameraDevice = .rear, 
                 quality: UIImagePickerController.QualityType = .typeMedium, 
                 maximumDuration: TimeInterval = 600,
                 editable: Bool = false) -> Observable<URL>
func selectVideo(source: UIImagePickerController.SourceType = .photoLibrary, 
                 maximumDuration: TimeInterval = 600,
                 editable: Bool = false) -> Observable<URL>
func takePhoto(device: UIImagePickerController.CameraDevice = .rear, 
               flashMode: UIImagePickerController.CameraFlashMode = .auto, 
               editable: Bool = false) -> Observable<(UIImage, UIImage?)>
func selectImage(source: UIImagePickerController.SourceType = .photoLibrary, 
                 editable: Bool = false) -> Observable<(UIImage, UIImage?)>

RxMediaPickerDelegate

func present(picker: UIImagePickerController)
func dismiss(picker: UIImagePickerController) 

To be able to use RxMediaPicker you will need to adopt the protocol RxMediaPickerDelegate. This is required to indicate RxMediaPicker how the camera/photos picker should be presented. For example, you may want to present the photos library picker in a popover on the iPad, and use the entire screen on the iPhone.

Requirements

  • iOS 8.0+
  • Xcode 7.0+

Instalation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate RxMediaPicker into your Xcode project using CocoaPods, include this in your Podfile:

platform :ios, '8.0'
use_frameworks!

pod 'RxMediaPicker'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate RxMediaPicker into your Xcode project using Carthage, specify it in your Cartfile:

github "RxSwiftCommunity/RxMediaPicker" "master"

Run carthage to build the framework and drag the built RxMediaPicker.framework into your Xcode project.

Swift Package Manager

Create a Package.swift file.

// swift-tools-version:5.0

import PackageDescription

let package = Package(
  name: "YOUR_PROJECT_NAME",
  dependencies: [
    .package(url: "https://github.com/RxSwiftCommunity/RxMediaPicker.git", from: "2.0.0")
  ],
  targets: [
    .target(name: "YOUR_PROJECT_NAME", dependencies: ["RxMediaPicker"])
  ]
)

Credits

Owned and maintained by Rui Costa (@ruipfcosta).

Contributing

Bug reports and pull requests are welcome.

License

RxMediaPicker is released under the MIT license. See LICENSE for details.

Comments
  • Updated for RxSwift 3.4, Swift 3.1, and general cleanup

    Updated for RxSwift 3.4, Swift 3.1, and general cleanup

    This project seems to not be maintained for a while but I saw an issue to support RxSwift 3.1 so I fixed it up a bit. See issue https://github.com/RxSwiftCommunity/RxMediaPicker/issues/7

    I didn't change implementation details here except for setting maximumVideoDuration on UIImagePickerController, but mainly worked on updating the Podspec, Cartfile and also getting the Example project to compile since it did not.

    opened by freak4pc 8
  • Cancel emits an error instead of a next event

    Cancel emits an error instead of a next event

    I'm not sure if is it good to send an Error event when use cancels during picking an image. Even more, my app crash when I press cancel, what is the reason?

    fatal error: Binding error to variable: canceled: file /Users/adamsmaka/Dropbox/Projects/TakeActionInspire/Pods/RxCocoa/RxCocoa/RxCocoa.swift, line 154

    screen shot 2017-05-26 at 1 43 16 pm help wanted question 
    opened by adamsmaka 7
  • No edit photos will have a problem

    No edit photos will have a problem

    func processPhoto(info: [String : AnyObject],
                      observer: AnyObserver<(UIImage, UIImage?)>) {
    

    // guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage, // let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage else { // observer.on(.error(RxMediaPickerError.generalError)) // return // }

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage
    
        observer.on(.next(image, editedImage))
        observer.on(.completed)
    }
    
    opened by ilumanxi 4
  • Error when picking photo with editable: false

    Error when picking photo with editable: false

    Hi, when I use function picker.selectImage(editable: true) everything is fine But when I change editable to false, then after picking a picture I got error Picker photo error: The operation couldn’t be completed. (RxMediaPicker.RxMediaPickerError error 0.) Why does this happen?

    opened by adamsmaka 3
  • Fix a crash when editable is false

    Fix a crash when editable is false

    The original code tested forcefully that editedImage is available, even though it is not guaranteed to be available (when editing mode is off, there will be no editedImage).

    This PR Fixes that and also fixes a minor issue to protect against a nil MPMoviePlayer.

    opened by freak4pc 2
  • Change RxMediaPicker style more swifty

    Change RxMediaPicker style more swifty

    Change RxMediaPicker style more swifty Update README.md outdated

    // as is
    func presentPicker(picker: UIImagePickerController)
    func dismissPicker(picker: UIImagePickerController) 
    
    // to be
    func present(picker: UIImagePickerController)
    func dismiss(picker: UIImagePickerController) 
    
    opened by cruisediary 0
  • Get the info of a selected image

    Get the info of a selected image

    One question, is there a way to get the info[String: Any] picking an image from the library?

    I need the info to get the URL and work with the fetched PHAsset, get the placeholder... yada, yada, yada... and selectImage function just give me the UIImage's.

    opened by deceroainfinito 0
  • Can't open the Image Picker for the second time

    Can't open the Image Picker for the second time

    Hi, I can't open the ImagePicker for the second time. After looking into the code, here are what I got:

    1. I got the observer will emit onError when the app did cancel the Image Picker, so it will emit onDisposed also.
        open func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            dismiss(picker)
            
            if let action = currentAction {
                switch action {
                case .photo(let observer): observer.on(.error(RxMediaPickerError.canceled))
                case .video(let observer, _): observer.on(.error(RxMediaPickerError.canceled))
                }
            }
        }
    
    1. I got the observer will emit onComplete when the app finishes pick the image, it will emit onDisposed also.
        func processPhoto(info: [UIImagePickerController.InfoKey: Any],
                          observer: AnyObserver<(UIImage, UIImage?)>) {
            guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
                observer.on(.error(RxMediaPickerError.generalError))
                return
            }
            
            let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
            observer.onNext((image, editedImage))
            observer.onCompleted()
        }
    

    That's why I can't open the ImagePicker for the second time. So, these are what I suggest:

    1. Only call dismiss(picker) inside func imagePickerControllerDidCancel(_ picker: UIImagePickerController)
        open func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            dismiss(picker)
        }
    
    1. Call onComplete after picking the image is not necessary
        func processPhoto(info: [UIImagePickerController.InfoKey: Any],
                          observer: AnyObserver<(UIImage, UIImage?)>) {
            guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
                observer.on(.error(RxMediaPickerError.generalError))
                return
            }
            
            let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
            observer.onNext((image, editedImage))
        }
    
    opened by lutluthfi 0
  • CocoaPods - Can't install the latest version compatible with Swift 5

    CocoaPods - Can't install the latest version compatible with Swift 5

    Since the last version of this pod that was published only supports much earlier versions of RxSwift, this pod can't be imported when using cocoapods and RxSwift ~> 5.1. It would be great if we could get this released so those of us who can't upgrade to SPM could use this nice framework.

    opened by musicdev20 0
  • Carthage --platform iOS command doesn't work

    Carthage --platform iOS command doesn't work

    Hello, I tried to add the project through Carthage but doesn't work with the error below.

    image

    I tried with carthage update RxMediaPicker --platform iOS --cache-builds and without --cache-builds command as well, both not working.

    I am using Xcode 12.1 and my cartfile is like below.

    ...
    github "ReactiveX/RxSwift" ~> 5.1.0
    github "RxSwiftCommunity/RxAlamofire" ~> 5.3
    github "RxSwiftCommunity/RxDataSources" ~> 4.0
    github "RxSwiftCommunity/RxAVFoundation"
    github "RxSwiftCommunity/RxRealm" ~> 3.1
    github "RxSwiftCommunity/RxMediaPicker" ~> 2.0
    github "RxSwiftCommunity/RxGesture" ~> 3.0
    github "realm/realm-cocoa" ~> 5.0
    

    Thanks

    opened by hjh5696 0
  • takePhoto method doesn't take into account what is in info.plist

    takePhoto method doesn't take into account what is in info.plist

    Hi, I am having issue because this method doesn't really take into account what is set in info.plist about Privacy - Camera usage. So, when I try to use camera, the system doesn't pop out with an alert about Camera usage description.

    Here is the code:

    func cameraAction() {
           if UIImagePickerController.isSourceTypeAvailable(.camera) {
               picker.takePhoto(editable: true).subscribe(onNext:{ [weak self] value in
                   guard let `self` = self else{ return }
                   if let editedImage = value.1{
                       self.viewModel.profileNewImageInput.accept(editedImage)
                   }
                   else{
                       self.viewModel.profileNewImageInput.accept(value.0)
                   }
               }).disposed(by: dispose)
           }
       }
    

    Am I supposed to do all checks by myself, or ?

    opened by Wh1rlw1nd 0
Releases(2.0.0)
Owner
RxSwift Community
RxSwift ecosystem projects
RxSwift Community
RxSwift wrapper around the elegant HTTP networking in Swift Alamofire

RxAlamofire RxAlamofire is a RxSwift wrapper around the elegant HTTP networking in Swift Alamofire. Getting Started Wrapping RxSwift around Alamofire

RxSwift Community 1.6k Jan 3, 2023
A testable RxSwift wrapper around MultipeerConnectivity

A testable RxSwift wrapper around MultipeerConnectivity RxMultipeer is a RxSwift wrapper for MultipeerConnectivity. Using the adapter pattern, we can

RxSwift Community 69 Jul 5, 2022
Reactive Programming in Swift

Rx is a generic abstraction of computation expressed through Observable<Element> interface, which lets you broadcast and subscribe to values and other

ReactiveX 23.1k Jan 5, 2023
A Swift Reactive Programming Kit

ReactiveKit is a lightweight Swift framework for reactive and functional reactive programming that enables you to get into the reactive world today. T

Declarative Hub 1.2k Dec 29, 2022
Simple and lightweight Functional Reactive Coding in Swift for the rest of us

The simplest Observable<T> implementation for Functional Reactive Programming you will ever find. This library does not use the term FRP (Functional R

Jens Ravens 1.1k Jan 3, 2023
Reactive Keyboard in iOS

RxKeyboard RxKeyboard provides a reactive way of observing keyboard frame changes. Forget about keyboard notifications. It also perfectly works with U

RxSwift Community 1.4k Dec 29, 2022
Reactive WebSockets

RxWebSocket Reactive extensions for websockets. A lightweight abstraction layer over Starscream to make it reactive. Installation RxWebSocket is avail

Flávio Caetano 57 Jul 22, 2022
RxReduce is a lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way.

About Architecture concerns RxReduce Installation The key principles How to use RxReduce Tools and dependencies Travis CI Frameworks Platform Licence

RxSwift Community 125 Jan 29, 2022
A Swift framework for reactive programming.

CwlSignal An implementation of reactive programming. For details, see the article on Cocoa with Love, CwlSignal, a library for reactive programming. N

Matt Gallagher 304 Oct 25, 2022
A powerful, minimal and composable architecture for building reactive iOS apps with SwiftUI or UIKit

SourceArchitecture A simple yet powerful framework for reactive programming with only a minimal optimized set of types. Sources are self-contained, hi

Daniel Hall 6 Nov 1, 2022
Swift Reactive Programming.

ReactKit Swift Reactive Programming. How to install See Wiki page. Example For UI Demo, please see ReactKit/ReactKitCatalog. Key-Value Observing // cr

ReactKit 1.2k Nov 6, 2022
ReactiveCocoa wrapper for CLLocationManager.

ReactiveSwift wrapper to observe location Our wrapper automatically asks for permission. It determines what kind of permission your app requires by ch

Ackee 24 Sep 6, 2022
🟣 Verge is a very tunable state-management engine on iOS App (UIKit / SwiftUI) and built-in ORM.

Verge.swift ?? An effective state management architecture for iOS - UIKit and also SwiftUI ?? _ An easier way to get unidirectional data flow _ _ Supp

VergeGroup 478 Dec 29, 2022
This package integrates a UIImagePickerController into a SwiftUI app.

This Swift Package integrates a UIImagePickerController into a SwiftUI app and allows a user to select, scale and position an image to be cropped and saved as a conatct's photo, similar to the stock iOS Contacts app.

Rillieux 58 Dec 26, 2022
Mock UIImagePickerController for testing camera based UI in simulator

Mock UIImagePickerController to simulate the camera in iOS simulator.

Yonat Sharon 18 Aug 18, 2022
A wrapper around UICollectionViewController enabling a declarative API around it's delegate methods using protocols.

Thunder Collection Thunder Collection is a useful framework which enables quick and easy creation of collection views in iOS using a declarative appro

3 SIDED CUBE 4 Nov 6, 2022
Reactive WebSockets - A lightweight abstraction layer over Starscream to make it reactive.

RxWebSocket Reactive extensions for websockets. A lightweight abstraction layer over Starscream to make it reactive. Installation RxWebSocket is avail

Flávio Caetano 57 Jul 22, 2022
RxSwift reactive wrapper for view gestures

RxGesture Usage To run the example project, clone the repo, in the Example folder open RxGesture.xcworkspace. You might need to run pod install from t

RxSwift Community 1.3k Dec 30, 2022
Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.

ReactiveSwift offers composable, declarative and flexible primitives that are built around the grand concept of streams of values over time. These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation.

null 20k Jan 3, 2023
A reactive, card-based UI framework built on UIKit for iOS developers.

CardParts - made with ❤️ by Intuit: Example Requirements Installation Communication & Contribution Overview Quick Start Architecture CardsViewControll

Intuit 2.5k Jan 4, 2023