티스토리 뷰

이번 포스팅은 iOS에서 제공하는 UIImagePickerController 클래스를 사용하여 카메라로 사진이나 동영상을 촬영하여 포토라이브러리에 저장하거나, 포토 라이브러리에 있는 사진이나 동영상을 어플로 불러오는 기능을 실습해보려고 한다.

 

아직 iOS 개발자로 등록하지 않아서 단말로 직접 카메라 테스트는 불가능하지만, 코드를 한번 익혀본다는 생각으로 진행하려고 한다.

 

바로 들어가보자.


우선 아래와 같이 이미지뷰 하나와 버튼 4개로 스토리보드를 구성하자.

 

모든 Item은 다음과 같이 스택뷰 내부에 삽입하였다.


코드는 아래와 같이 outlet 변수와 액션 함수를 먼저 선언해주고, 각 카메라에서 미디어를 가져오는지 라이브러리에서 가져오는 지 확인하기 위한 플래그와 필요한 변수들을 선언해준다.

import UIKit
import MobileCoreServices


class ViewController: UIViewController, UINavigationControllerDelegate,
    UIImagePickerControllerDelegate{

    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var videoURL: URL!
    var flagImageSave = false
    
    
    @IBOutlet var imgView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    @IBAction func btnTakePhoto(_ sender: UIButton) {
       
    }
    
    @IBAction func btnRecordVideo(_ sender: UIButton) {
    
   	}

    @IBAction func btnLoadPhoto(_ sender: UIButton) {
        
    }
    
    
    @IBAction func btnLoadVideo(_ sender: UIButton) {
      
    }

}

 

이후에 카메라나 포토 라이브러리에 연결하지 못했을 경우, 알림창이 뜨도록 myAlert 메서드를 작성해주자.

func myAlert(_ title: String, message: String) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)

    let action = UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil)

    alert.addAction(action)

    self.present(alert, animated: true, completion: nil)
}

 

다음으로 각 버튼의 액션 함수를 아래와 같이 기능별 미디어를 가져올 수 있도록 작성한다. 

//
//  ViewController.swift
//  example_project14
//
//  Created by choonham on 2022/12/22.
//

import UIKit
import MobileCoreServices


class ViewController: UIViewController, UINavigationControllerDelegate,
    UIImagePickerControllerDelegate{

    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var videoURL: URL!
    var flagImageSave = false
    
    
    @IBOutlet var imgView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    @IBAction func btnTakePhoto(_ sender: UIButton) {
        // 카메라 사용 가능 여부 확인
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            // 이미지 저장 허용
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            
            // 미디어 타입 설정
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            
            // 현재 View Controller를 Image picker로 대체
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera. ")
        }
    }
    
    @IBAction func btnRecordVideo(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera

            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = false

            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera. ")
        }
    }

    @IBAction func btnLoadPhoto(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Photo album inaccessable", message: "Application cannot access the Photo album. ")
        }
    }
    
    
    @IBAction func btnLoadVideo(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Photo album inaccessable", message: "Application cannot access the Photo album. ")
        }
    }
    
    func myAlert(_ title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        
        let action = UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil)
        
        alert.addAction(action)
        
        self.present(alert, animated: true, completion: nil)
    }
    
}

 

마지막으로 ImagePickerController 뷰에서 정상적으로 미디어를 가져왔을 때, 이미지 뷰에 해당 미디어를 삽입하거나 라이브러리에 해당 미디어를 저장하고 해당 뷰를 종료하는 메서드와 취소를 눌렀을 때 해당 뷰를 종료하는 UIImagePickerControllerDelegate 오버라이드 메서드를 재정의 해주면 모두 끝이 난다.

 

전체 코드는 아래와 같다.

import UIKit
import MobileCoreServices


class ViewController: UIViewController, UINavigationControllerDelegate,
    UIImagePickerControllerDelegate{

    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var captureImage: UIImage!
    var videoURL: URL!
    var flagImageSave = false
    
    
    @IBOutlet var imgView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    @IBAction func btnTakePhoto(_ sender: UIButton) {
        // 카메라 사용 가능 여부 확인
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            // 이미지 저장 허용
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            
            // 미디어 타입 설정
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            
            // 현재 View Controller를 Image picker로 대체
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera. ")
        }
    }
    
    @IBAction func btnRecordVideo(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
            flagImageSave = true
            
            imagePicker.delegate = self
            imagePicker.sourceType = .camera

            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = false

            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Camera inaccessable", message: "Application cannot access the camera. ")
        }
    }

    @IBAction func btnLoadPhoto(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Photo album inaccessable", message: "Application cannot access the Photo album. ")
        }
    }
    
    
    @IBAction func btnLoadVideo(_ sender: UIButton) {
        if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
            flagImageSave = false
            
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.mediaTypes = [kUTTypeMovie as String]
            imagePicker.allowsEditing = true
            
            present(imagePicker, animated: true, completion: nil)
        } else {
            myAlert("Photo album inaccessable", message: "Application cannot access the Photo album. ")
        }
    }
    
    func myAlert(_ title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        
        let action = UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil)
        
        alert.addAction(action)
        
        self.present(alert, animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 미디어 종류 확인
        let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
        
        // 미디어의 종류가 사진인 경우
        if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
            
            // 사진을 가져와서 captureImage에 저장
            captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
            
            // 저장 모드인 경우 포토라이브러리에 해당 사진 저장
            if flagImageSave {
                UIImageWriteToSavedPhotosAlbum(captureImage, self, nil, nil)
            }
            
            imgView.image = captureImage
        } else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
            if flagImageSave {
                videoURL = (info[UIImagePickerController.InfoKey.mediaURL] as! URL)
                
                UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)
            }
            
        }
        
        //현재 View Controller 제거
        self.dismiss(animated: true, completion: nil)
        
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.dismiss(animated: true, completion: nil)
    }
    
}

 

 

 

끝!!

반응형
Comments