ユーザーページの画像をアップロードする

[このページ](https://qiita.com/SHOBLOG/items/a3aa8c6676bff3046d29)の続きです。
<img width="340" alt="スクリーンショット 2019-07-07 9.30.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/f8b16527-c4f7-b305-f7c5-42fa9f55bda9.png"> ⇨　<img width="340" alt="スクリーンショット 2019-07-07 9.36.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/7d67f3b7-bb6c-b620-0aff-e10bf20e406d.png">
これが完成形です。

###事前に
❶画像を拾ってくる。
❷画像をNCMBにアップロード
❸画像をユーザーページに読み込む。
の手順でやっていきたいと思います。

<img width="337" alt="スクリーンショット 2019-07-06 9.22.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/6d86297d-bb53-a694-68ac-21e86264709f.png">

まずは部品の接続、TextField,TextViewのDelegate接続、userIdTextFieldに現在ログインしているユーザーの取得を行なっていきます。

```
import UIKit
import NCMB

class EditProfileViewController: UIViewController,UITextViewDelegate,UITextFieldDelegate {

    @IBOutlet weak var userImageView: UIImageView!
    
    @IBOutlet weak var userIdTextField:UITextField!
    
    @IBOutlet weak var userNameTextField: UITextField!
    
    @IBOutlet weak var introductionTextView: UITextView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        userIdTextField.delegate = self
        userNameTextField.delegate = self
        introductionTextView.delegate = self
        
        let userId = NCMBUser.current()?.userName
        userIdTextField.text = userId

    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
    
    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        textView.resignFirstResponder()
        return true
    }
    
    @IBAction func close(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }

}
```
以下のような挙動になると思います。
<img width="337" alt="スクリーンショット 2019-07-06 8.59.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/5551f4ae-d9c1-2a3c-c07b-9a74f51aa8b9.png">

そしてここからカメラとフォトライブラリーの取得に入っていきます。
またその機能に移る前に、iOS10以降ではプライバシーを扱う前にInfo.plistに書かなければいけないことがあります。
<img width="739" alt="スクリーンショット 2019-07-06 9.13.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/106848df-9c19-741e-3bc2-1d48d81973a9.png">
赤色で囲んでいるところを追加し、適当にカメラとフォトライブラリを使うときの文言を書いてください。
###UIImagePickerController

```
EditProfileViewController.swift
~~~省略~~~
@IBAction func selectImage(_ sender: Any) {
        
        let alertController = UIAlertController(title: "画像の選択", message: "選択してください", preferredStyle:.actionSheet)
        
        let cameraAction = UIAlertAction(title: "カメラ", style: .default) { (action) in
            // カメラ起動
            //カメラが使えたら
            if UIImagePickerController.isSourceTypeAvailable(.camera) == true {
                let picker = UIImagePickerController()
                picker.sourceType = .camera
                picker.allowsEditing = true
                picker.delegate = self
                self.present(picker, animated: true, completion: nil)
            } else {
                print("この機種ではカメラが使用出来ません。")
            }
        }
        let albumAction = UIAlertAction(title: "フォトライブラリ", style: .default) { (action) in
            // アルバム起動
            if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) == true {
                let picker = UIImagePickerController()
                picker.sourceType = .photoLibrary
                picker.allowsEditing = true
                picker.delegate = self
                self.present(picker, animated: true, completion: nil)
            } else {
                print("この機種ではフォトライブラリが使用出来ません。")
            }
        }
        let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in
            alertController.dismiss(animated: true, completion: nil)
        }
        alertController.addAction(cameraAction)
        alertController.addAction(albumAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
        
    }
```
<img width="338" alt="スクリーンショット 2019-07-06 9.19.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/11e860b4-43ea-5dcd-8298-e626e847f52f.png">

次に選ばれた画像をImageViewに表示するという処理を作っていきます。
とその前に、縦長や横長の画像を表示するために一手間加えます。
UIImageViewを選択した状態で、
<img width="259" alt="スクリーンショット 2019-07-06 9.28.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/ef0af926-4a78-7e98-eb3e-e9e32978d7c6.png">
ContentModeをAspectFillに、またCliptoBoundsにチェックを入れてください。

```
EditProfileViewController.swift
~~~省略~~~
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        
        userImageView.image = selectedImage
        
        picker.dismiss(animated: true, completion: nil)
    }
~~~省略~~~
```

<img width="337" alt="スクリーンショット 2019-07-06 9.33.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/58e11421-7e49-4f42-dfb9-660a5bd57f58.png">
画像が表示されました。

これでは画像が保存されません。
そのため拾ってきた画像をNCMBに保存し、アップロードする必要があります。。

###NCMBに画像をアップロード
その前にiPhoneで取ってきた画像は大きすぎるのでリサイズする必要があります。
そのために今回は簡単なライブラリを紹介します。
[NYXImagesKit](https://github.com/Nyx0uf/NYXImagesKit)です。
これをPodfileに

```
pod 'NYXImagesKit'
```

と追加し、pod installを行なってください。

```
 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        
        //NYXImagesKitライブラリでリサイズを行う。
        let resizedImage = selectedImage.scale(byFactor: 0.4)
        
        
        picker.dismiss(animated: true, completion: nil)
        
        //data型に変換
        let data = resizedImage!.pngData()
        
        //型を変換
        let file = NCMBFile.file(withName: NCMBUser.current()?.objectId,data:data) as! NCMBFile

        file.saveInBackground({ (error) in
            if error != nil{
                print(error)
            }else{
                self.userImageView.image = selectedImage
                
            }
        }) { (progress) in
            print(progress)
        }
        
    }
    
```
これで以下のようにNCMBに保存されるようになりました。
<img width="723" alt="スクリーンショット 2019-07-07 8.37.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/e650da1a-137b-916e-f7e4-4d4cb80d8816.png">

次にアップロードした画像を読み込みます。
###ユーザーページに読み込む。

```
ViewController.swift

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //丸くするコード
        userImageView.layer.cornerRadius = userImageView.bounds.width / 2.0
        userImageView.layer.masksToBounds = true
    }
    
    override func viewWillAppear(_ animated: Bool) {
        if let user = NCMBUser.current() {
            
            let file = NCMBFile.file(withName: (user.objectId)!, data: nil) as! NCMBFile
            
            file.getDataInBackground { (data, error) in
                if error != nil{
                    print(error)
                }else{
                    if let image = UIImage(data: data!){
                        self.userImageView.image = image
                    }
                    
                }
            }
        }else{
            // NCMBUser.current()がnilだったとき
            let storyboard = UIStoryboard(name: "SignIn", bundle: Bundle.main)
            let rootViewController = storyboard.instantiateViewController(withIdentifier: "SignInController")
            UIApplication.shared.keyWindow?.rootViewController = rootViewController
            
            // ログイン状態の保持
            let ud = UserDefaults.standard
            ud.set(false, forKey: "isLogin")
            ud.synchronize()
        }
        
    }
    
```

<img width="332" alt="スクリーンショット 2019-07-07 9.30.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/dcdac2f5-c9a2-0eb5-02c9-44d294aadaeb.png">

また、[このような画像](https://www.google.com/url?sa=i&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwiV3qj-yKHjAhWMH3AKHYC6DXgQjRx6BAgBEAU&url=%2Furl%3Fsa%3Di%26source%3Dimages%26cd%3D%26ved%3D%26url%3Dhttp%253A%252F%252Fgamble.marketing%252Faboutus%252Fperson-placeholder%252F%26psig%3DAOvVaw011sLvUi4Fqsb4CQGQwxMt%26ust%3D1562546364526820&psig=AOvVaw011sLvUi4Fqsb4CQGQwxMt&ust=1562546364526820)をImageViewのImageに設定しておけば、画像が読み込まれる前に表示することができます。
以上で完成です。