4

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.

David Seek
  • 16,783
  • 19
  • 105
  • 136
Dimitre Bogdanov
  • 395
  • 1
  • 5
  • 18
  • I've posted an answer for you, but you're getting all the downvotes because this is no site to "code for you". you have to provide code and we're helping you to find errors and better your code. so for the next time, try to google solutions and receive help if you get stuck. for now: i've posted a fully functional option for you. have fun – David Seek Oct 02 '16 at 01:08
  • 1
    I understand that this is not a place for people to do the work for me, I'm simply asking for some kind of indication as to where I could start. I don't expect anyone to write it out for me, though I appreciate the answer you posted. – Dimitre Bogdanov Oct 02 '16 at 01:49
  • 1
    i didn't wanted to offend you or anything mate. just wanted to tell you, why you're getting all the down-voted. you got an upvote by me, so it will not get too bad and if my work helps you, i'm happy to have your question answered so you can check it. if you need further assistance, just let me know. – David Seek Oct 02 '16 at 01:53

1 Answers1

24

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)
    }
}
David Seek
  • 16,783
  • 19
  • 105
  • 136
  • 2
    Nice answer David thx for sharing – Drew Oct 15 '16 at 23:38
  • sure mate, you're welcome – David Seek Oct 15 '16 at 23:39
  • Your code worked fine, except when loading from library with canEdit: false when I choose an image it just crashes – Pedro Cavaleiro Jun 19 '17 at 13:36
  • Never mind, I found what I was doing wrong. let image = info[UIImagePickerControllerEditedImage] as! UIImage is from when the image can be edited and this when you want the original let image = info[UIImagePickerControllerOriginalImage]as! UIImage – Pedro Cavaleiro Jun 19 '17 at 13:56
  • Also refer this simple method, and it supports Swift 3 : https://stackoverflow.com/questions/41717115/how-to-uiimagepickercontroller-for-camera-and-photo-library-in-the-same-time-in/41717882#41717882 – anas.p Jul 19 '17 at 08:25
  • 1
    Very useful answer. Thanks for this. But there is a little mistake i guess. You checked isPhotoLibraryAvailable twice in getPhotoLibraryOn. Second one should be isSavedPhotoAlbumAvailable. – AtaerCaner Aug 02 '17 at 09:12
  • 2
    Amazing one! works perfectly. Thanks for that – Mo Zaatar Mar 04 '18 at 03:31
  • you're very welcome – David Seek Mar 04 '18 at 04:24