写真撮影アプリ最小構成(Swift)

#写真撮影App
##1. ユーザ許可

info.plistでカメラが使えるように設定する。
今回は、*Privacy - Camera Usage Description*と*Privacy - Photo Library Additions Usage Description*の二項目を加える。
<div align="center">
<img width="500" alt="スクリーンショット 2018-09-13 14.53.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/256340/80016172-995c-9cef-e13c-6e42c8419854.png">
</div>

##2. コード入力
```swift:ViewController.swift
import UIKit
import AVFoundation

//ジャスチャー
struct CommonStructure {
    static var tapGesture = UITapGestureRecognizer()
    //static var swipeGestureUP = UISwipeGestureRecognizer()
}

class ViewController: UIViewController, AVCapturePhotoCaptureDelegate {

    var cameraView = UIImageView()
    
    //キャプチャセッションに入力（オーディオやビデオなど）を提供し、ハードウェア固有のキャプチャ機能のコントロールを提供するデバイス。
    var captureDevice  = AVCaptureDevice.default(for: .video)
    var photoOutput: AVCapturePhotoOutput? = AVCapturePhotoOutput() //静止画、ライブ写真、その他の写真ワークフローの出力をキャプチャします。
    
    override func viewDidLoad() {
        super.viewDidLoad()

        var deviceInput_pre: AVCaptureDeviceInput!//3入力
        var deviceInput_nex: AVCaptureDeviceInput!//3入力
        let captureSesion = AVCaptureSession()//2セッション

        captureSesion.sessionPreset = AVCaptureSession.Preset.hd1920x1080// 解像度の設定
        
        cameraView.frame = view.frame
        if cameraView.frame.width != 0 {
            captureSesion.beginConfiguration()//一連の構成変更の開始を示します。
            captureSesion.commitConfiguration()//一連の構成変更をコミットします。
        }
        
        do {
            deviceInput_pre = try AVCaptureDeviceInput(device: captureDevice!)
            deviceInput_nex = try AVCaptureDeviceInput(device: captureDevice!)
            // 入力
            if  captureSesion.canAddInput(deviceInput_nex) {
                captureSesion.removeInput(deviceInput_pre)
                captureSesion.addInput(deviceInput_nex)
                // 出力
                if (captureSesion.canAddOutput(photoOutput!)) {
                    captureSesion.addOutput(photoOutput!)
                    
                    captureSesion.startRunning()// カメラ起動
                    
                    //プレビュー
                    let previewLayer: AVCaptureVideoPreviewLayer? = AVCaptureVideoPreviewLayer(session: captureSesion)//キャプチャされているときにビデオを表示できるコアアニメーションレイヤ-
                    previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill// アスペクトフィット
                    previewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait// カメラの向き
                    previewLayer?.frame =  cameraView.frame
                    cameraView.layer.addSublayer(previewLayer!)
                }
            }
        } catch {
            print(error)
        }
        view.addSubview(cameraView)
        //ジャスチャー
        CommonStructure.tapGesture = UITapGestureRecognizer(target: self,action:#selector(tapGesture))
        self.view.addGestureRecognizer( CommonStructure.tapGesture)
    }

    @objc func tapGesture(sender:UITapGestureRecognizer) {
        self.photoOutput?.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
    }
    // フォトライブラリへの保存メソッド
    func photoOutput(_ output: AVCapturePhotoOutput,
                     didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

        let photoData = photo.fileDataRepresentation()
        
        //A. DocumentsDirectoryに保存
        let documentsPath = NSHomeDirectory() + "/Documents"
        let storeURL = URL(fileURLWithPath:documentsPath).appendingPathComponent(UUID().uuidString)
        do {
            let _ = try photoData?.write(to: storeURL)
        } catch {
            print("error")
            return // FIXME: Alert error
        }
        //B. フォトライブラリに保存
        //UIImageWriteToSavedPhotosAlbum(UIImage(data: photoData!)!, nil, nil, nil)
    }
 }