How to load image from camera or photo library in Swift

13,093

Full update for Swift 5+ including Github Repo

First of all we want to organize everything into a dedicated class.

import MobileCoreServices
import UIKit

class CameraProvider: NSObject {

    enum PhotoLibraryTypes {
        case photoLibrary, savedPhotosAlbum
        var casted: UIImagePickerController.SourceType {
            switch self {
            case .photoLibrary: return UIImagePickerController.SourceType.photoLibrary
            case .savedPhotosAlbum: return UIImagePickerController.SourceType.savedPhotosAlbum
            }
        }
    }

    public typealias SourceType = UIImagePickerController.SourceType
    public typealias ImagePicker = UIImagePickerController
    public typealias Delegate = UINavigationControllerDelegate & UIImagePickerControllerDelegate

    private let delegate: Delegate

    init(delegate: Delegate) {
        self.delegate = delegate
    }

    // MARK: - Public

    public func getImagePicker(source: PhotoLibraryTypes,
                               canEditPhotos: Bool = true,
                               onlyImages: Bool = false) throws -> ImagePicker {

        do {
            return try getBaseController(
                source: source.casted,
                allowsEditing: canEditPhotos,
                onlyImages: onlyImages
            )
        } catch {
            throw error
        }
    }

    public func getCamera(canEditPhotos: Bool = true,
                          onlyImages: Bool = false) throws -> ImagePicker {

        do {
            let picker = try getBaseController(
                source: .camera,
                allowsEditing: canEditPhotos,
                onlyImages: onlyImages
            )

            if UIImagePickerController.isCameraDeviceAvailable(.rear) {
                picker.cameraDevice = .rear
            } else if UIImagePickerController.isCameraDeviceAvailable(.front) {
                picker.cameraDevice = .front
            } else {
                throw "No known camera type available"
            }

            picker.showsCameraControls = true
            return picker
        } catch {
            throw error
        }
    }

    // MARK: - Private

    private func getBaseController(source: SourceType,
                                   allowsEditing: Bool,
                                   onlyImages: Bool) throws -> ImagePicker {

        guard UIImagePickerController.isSourceTypeAvailable(source) else {
            throw "Requested source not available"
        }

        let picker = UIImagePickerController()
        let imageType = kUTTypeImage as String
        picker.sourceType = source
        picker.allowsEditing = allowsEditing
        picker.delegate = self.delegate

        if onlyImages,
           let mediaTypes = UIImagePickerController.availableMediaTypes(for: source),
           mediaTypes.contains(imageType){
            picker.mediaTypes = [imageType]
        }

        return picker
    }
}

extension String: LocalizedError {
    public var errorDescription: String? { return self }
}

Lastly we call our CameraProvider as following.

import UIKit

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let provider = CameraProvider(delegate: self)

        do {
            let picker = try provider.getImagePicker(source: .photoLibrary)
            present(picker, animated: true)
        } catch {
            NSLog("Error: \(error.localizedDescription)")
        }
    }
}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let image = (
            info[UIImagePickerController.InfoKey.editedImage] as? UIImage ??
            info[UIImagePickerController.InfoKey.originalImage] as? UIImage
        )
        picker.dismiss(animated: true, completion: nil)
    }
}
Share:
13,093
Dimitre Bogdanov
Author by

Dimitre Bogdanov

Updated on June 04, 2022

Comments

  • Dimitre Bogdanov
    Dimitre Bogdanov almost 2 years

    How do you take a photo with the camera or pick an image from the photo library to be able to display it in an imageView for example?

    Any help on this would be appreciated.