Dimitre Bogdanov Dimitre Bogdanov - 2 months ago 22
iOS Question

Loading image from camera/photos in swift

I'm working on a Swift app in which there is a UIView and where I would like to allow the user to select an image from their Camera Roll or to open the Camera to take one and once the image has been selected, to save it if it's from the camera or if its from the saved images to somehow save the image or the path to retrieve it at a later time and display it.

Any help on this would be appreciated.

Answer

I'm using the following:

Camera Class as helper class:

import Foundation
import MobileCoreServices

class Camera {

    var delegate: protocol<UINavigationControllerDelegate, UIImagePickerControllerDelegate>?

    init(delegate_: protocol<UINavigationControllerDelegate, UIImagePickerControllerDelegate>) {
        delegate = delegate_
    }

    func presentPhotoLibrary(target: UIViewController, canEdit: Bool) {

        if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) && !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum) {

            return
        }

        let type = kUTTypeImage as String
        let imagePicker = UIImagePickerController()

        if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {

            imagePicker.sourceType = .PhotoLibrary

            if let availableTypes = UIImagePickerController.availableMediaTypesForSourceType(.PhotoLibrary) {

                if (availableTypes as NSArray).containsObject(type) {

                    imagePicker.mediaTypes = [type]
                    imagePicker.allowsEditing = canEdit
                }
            }
        } else if UIImagePickerController.isSourceTypeAvailable(.SavedPhotosAlbum) {

            imagePicker.sourceType = .SavedPhotosAlbum

            if let availableTypes = UIImagePickerController.availableMediaTypesForSourceType(.SavedPhotosAlbum) {

                if (availableTypes as NSArray).containsObject(type) {

                    imagePicker.mediaTypes = [type]
                }

            }
        } else {

            return
        }

        imagePicker.allowsEditing = canEdit
        imagePicker.delegate = delegate
        target.presentViewController(imagePicker, animated: true, completion: nil)
    }

    func presentPhotoCamera(target: UIViewController, canEdit: Bool) {

        if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {

            return
        }

        let type1 = kUTTypeImage as String
        let imagePicker = UIImagePickerController()

        if UIImagePickerController.isSourceTypeAvailable(.Camera) {

            if let availableTypes = UIImagePickerController.availableMediaTypesForSourceType(.Camera) {

                if (availableTypes as NSArray).containsObject(type1) {

                    imagePicker.mediaTypes = [type1]
                    imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
                }
            }

            if UIImagePickerController.isCameraDeviceAvailable(.Rear) {

                imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.Rear

            } else if UIImagePickerController.isCameraDeviceAvailable(.Front) {

                imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.Front
            }

        } else {

            return
        }

        imagePicker.allowsEditing = canEdit
        imagePicker.showsCameraControls = true
        imagePicker.delegate = delegate
        target.presentViewController(imagePicker, animated: true, completion: nil)
    }
}

Called within your desired ViewController by:

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    func optionsMenu() {

        let camera = Camera(delegate_: self)

        let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
        optionMenu.popoverPresentationController?.sourceView = self.view

        let takePhoto = UIAlertAction(title: "Camera", style: .Default) { (alert : UIAlertAction!) in
            camera.presentPhotoCamera(self, canEdit: true)
        }
        let sharePhoto = UIAlertAction(title: "Library", style: .Default) { (alert : UIAlertAction) in
            camera.presentPhotoLibrary(self, canEdit: true)
        }

        let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (alert : UIAlertAction) in
            //
        }

        optionMenu.addAction(takePhoto)
        optionMenu.addAction(sharePhoto)

        optionMenu.addAction(cancel)

        self.presentViewController(optionMenu, animated: true, completion: nil)
    }
}

At the last you need to implement the handler after the Image Picker got closed, also within the ViewController class:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

    let image = info[UIImagePickerControllerEditedImage] as! UIImage

    // what to do with your image?

    picker.dismissViewControllerAnimated(true, completion: nil)
}