[swift5]iOSアプリでカメラ機能を実装

iPhoneに入っているカメラアプリのようなカメラを呼び出す機能を実装する方法を紹介します！
本ページでは、UIImagePickerController を利用します。

自分でカスタマイズしたカメラを実装したい場合は、UIImagePickerController ではなく AVFoundation を利用する必要があります。

## 動作環境

| 対象 | バージョン |
|---|---|
| iOS | 13.3 |
| macOS | Catalina 10.15.2 |
| Xcode | 11.3.1 |
| Swift | 5.1.3 |

## カメラ機能の実装

本ページでは、2画面用意します。

1. ボタンを用意します
2. ボタンを押下すると、カメラ画面に遷移します
3. 写真をとり、写真を利用を押下すると、写真が保存されはじめの画面に戻ります

### Info.plistの修正

Info.plist に2つ項目を追加します。

- Privacy - Camera Usage Description
    - カメラを呼び出すために追加する
- Privacy - Photo Library Addtions Usage  Description
    - 写真を保存する写真アプリを利用するために追加する

### ファイル作成

- Storyboard
    - ここでは、"Camera.storyboard" とします
- ViewController.swift
    - ここでは、"CameraViewController.swift" とします

### 画面を作成

Storyboard に、カメラを呼び出すためのボタンを載っけます。

- カメラ画面は実装する必要がないため、自分自身ではカメラ機能を呼び出す1画面のみ作成します

### 画面とソースの紐付け

カメラを呼び出すためのボタンをソースコード上に紐付けします。

```swift
/// UIImagePickerController カメラを起動する
// - Parameter sender: "UIImagePickerController" ボタン
@IBAction func startUiImagePickerController(_ sender: Any) {
}
```

## カメラを呼び出す

はじめに、Delegate を実装します。

```swift
class CameraTopViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
}
```

次に、ボタン押下時に呼び出されるメソッド内に以下を実装します。

```swift
/// UIImagePickerController カメラを起動する
/// - Parameter sender: "UIImagePickerController"ボタン
@IBAction func startUiImagePickerController(_ sender: Any) {
    let picker = UIImagePickerController()
    picker.sourceType = .camera
    picker.delegate = self
    // UIImagePickerController カメラを起動する
    present(picker, animated: true, completion: nil)
}
```
最後に、カメラを呼び出した後の処理を実装します。

```swift
/// シャッターボタンを押下した際、確認メニューに切り替わる
/// - Parameters:
///   - picker: ピッカー
///   - info: 写真情報
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let image = info[.originalImage] as! UIImage
    // "写真を使用"を押下した際、写真アプリに保存する
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    // UIImagePickerController カメラが閉じる
    self.dismiss(animated: true, completion: nil)
}
```

## ソースコード

```swift
import UIKit

class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    /// UIImagePickerController カメラを起動する
    /// - Parameter sender: "UIImagePickerController"ボタン
    @IBAction func startUiImagePickerController(_ sender: Any) {
        let picker = UIImagePickerController()
        picker.sourceType = .camera
        picker.delegate = self
        // UIImagePickerController カメラを起動する
        present(picker, animated: true, completion: nil)
    }

    /// シャッターボタンを押下した際、確認メニューに切り替わる
    /// - Parameters:
    ///   - picker: ピッカー
    ///   - info: 写真情報
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let image = info[.originalImage] as! UIImage
        // "写真を使用"を押下した際、写真アプリに保存する
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        // UIImagePickerController カメラが閉じる
        self.dismiss(animated: true, completion: nil)
    }
}
```