【超初心者向け】NCMBを利用した画像の複数枚投稿

# 最初に
この記事はswiftを勉強し始めた超初心者による超初心者のためのものになっているので、細かいミスなどが散見されるかもしれませんがご了承ください。

## 投稿の仕方
```swift: PostViewController.swift
import UIKit
import NCMB
import DKImagePickerController
import Photos

class PostViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate {    

    @IBOutlet var collectionView: UICollectionView!
    
    var imageNumber = 0    
    var imageArray: [Any] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.dataSource = self
        collectionView.delegate = self        

        let nib = UINib(nibName: "AddCollectionViewCell", bundle: nil)
        collectionView.register(nib, forCellWithReuseIdentifier: "Cell")

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let size = collectionView.frame.height
        layout.itemSize = CGSize(width: size, height: size)
        collectionView.collectionViewLayout = layout   
    }
      @IBAction func selectImage(_ sender: Any) {
               let alertcontroller = UIAlertController(title: "画像選択", message: "投稿する画像を選択してください", preferredStyle: .actionSheet)
               let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in
                   self.dismiss(animated: true, completion: nil)
               }
               let cameraAction = UIAlertAction(title: "カメラで撮影する", style: .default) { (action) in
                   let cameraPicker = UIImagePickerController()
                   cameraPicker.sourceType = .camera
                   cameraPicker.delegate = self
                   cameraPicker.allowsEditing = true
                   self.present(cameraPicker, animated: true, completion: nil)
               }
          let albumAction = UIAlertAction(title: "アルバムから選択する", style: .default) { (action) in             
              let pickerController = DKImagePickerController()
              pickerController.sourceType = .photo
              pickerController.showsCancelButton = true
              pickerController.modalPresentationStyle = .fullScreen             
              pickerController.navigationBar.backgroundColor = .white
              pickerController.maxSelectableCount = 4
              pickerController.UIDelegate = CustomUIDelegate()
              pickerController.didSelectAssets = {(assets: [DKAsset]) in
                  for asset in assets {                    asset.fetchFullScreenImage(completeBlock: { (image: UIImage?, info) in                        
                      self.imageArray.append(image)
                      print(self.imageArray)
                      self.collectionView.reloadData()
                  })                    
                  }
                  self.collectionView.reloadData()
              }
              self.present(pickerController, animated: true){}             
          }          
          alertcontroller.addAction(cameraAction)
          alertcontroller.addAction(albumAction)
          alertcontroller.addAction(cancelAction)
          self.present(alertcontroller, animated: true, completion: nil)  
      }
    @IBAction func setImage(){
        let pickerController = DKImagePickerController()
        pickerController.didSelectAssets = {(assets: [DKAsset]) in
            for asset in assets {
                asset.fetchFullScreenImage(completeBlock: {
                    (image, info) in
                    let Aimage = image as! UIImage
                    self.imageArray.append(Aimage)
                })
            }            
        }
        self.present(pickerController, animated: true){}
    }
    @IBAction func post(_ sender: Any) {
        var postImageArray: [String] = []         
        for i in 0..<imageArray.count{
           let image = imageArray[i] as! UIImage          
           let data = image.jpegData(compressionQuality: 0.1)
           let file = NCMBFile.file(with: data) as! NCMBFile
           file.saveInBackground { (error) in              
               if error != nil {
                   let errorAlert = UIAlertController(title: "画像のアップロードに失敗しました", message: error?.localizedDescription, preferredStyle: .alert)
                   let okAction = UIAlertAction(title: "OK", style: .default) { (action) in
                 }
                 errorAlert.addAction(okAction)
                 self.present(errorAlert, animated: true, completion: nil)                 
               }              
           }
            let appId = "自分のアプリID"
            let url = "https://mbaas.api.nifcloud.com/2013-09-01/applications/" + appId + "/publicFiles/" + file.name
            postImageArray.append(url)
        }
            let postObject = NCMBObject(className: "Post")
            postObject?.setObject(postImageArray, forKey: "imageUrl")
            //動画投稿（次回記事）のための部分です
            postObject?.setObject(false, forKey: "movie")
            postObject?.saveInBackground({ (error) in
                if error != nil {
                    print(error.debugDescription)
                    return
                }
                self.tabBarController?.selectedIndex = 0
            })
        self.navigationController?.popViewController(animated: true)
        }       
    }

class CustomUIDelegate: DKImagePickerControllerBaseUIDelegate {
  override func createDoneButtonIfNeeded() -> UIButton {
    let button = UIButton(type: UIButton.ButtonType.custom)
    button.setTitle("選択", for: .normal)
    button.setTitleColor(UINavigationBar.appearance().tintColor ?? self.imagePickerController.navigationBar.tintColor, for: .normal)
    button.addTarget(self.imagePickerController, action: #selector(DKImagePickerController.done), for: .touchUpInside)
    return button
  }
  //写真選択超過時のアラートのカスタマイズ
  override func imagePickerControllerDidReachMaxLimit(_ imagePickerController: DKImagePickerController) {
    let alert = UIAlertController.init(title: "注意", message: "これ以上選択できません!", preferredStyle: .alert)
    if UIDevice.current.userInterfaceIdiom == .pad{
      let screenSize = UIScreen.main.bounds
      alert.popoverPresentationController?.sourceRect = CGRect(x: screenSize.size.width/2, y: screenSize.size.height, width: 0, height: 0)
    }
    let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel, handler: nil)
    alert.addAction(okAction)
    imagePickerController.present(alert, animated: true, completion: nil)
  }
  //cancelボタンのカスタマイズ
  override func imagePickerController(_ imagePickerController: DKImagePickerController, showsCancelButtonForVC vc: UIViewController) {
    let cancelButton = UIBarButtonItem()
    cancelButton.title = "戻る"
    cancelButton.style = .plain
    cancelButton.action = #selector(imagePickerController.dismiss as () -> Void)
    cancelButton.target = imagePickerController
    vc.navigationItem.leftBarButtonItem = cancelButton
    vc.navigationController?.navigationBar.tintColor = .white
    vc.navigationController?.toolbar.barTintColor = .white
  }
}




```
## 表示の仕方
```swift:ViewController.swift
import UIKit
import NCMB
import Kingfisher
import Photos

class ViewController: UIViewController, UICollectionViewDelegate, UITableViewDelegate,UITableViewDataSource{
  var resultArray = [NCMBObject]()
  var imageArray:[Any] = []
  var number: Int!

  @IBOutlet var tableView: UITableView!

  override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.tableFooterView = UIView()
    tableView.rowHeight = 400

    let nib = UINib(nibName: "TableViewCell", bundle: nil)
    tableView.register(nib, forCellReuseIdentifier: "Cell")
    let oneNib = UINib(nibName: "oneTableViewCell", bundle: nil)
    tableView.register(oneNib, forCellReuseIdentifier: "oneCell")
    let twonib = UINib(nibName: "TwoTableViewCell", bundle: nil)
    tableView.register(twonib, forCellReuseIdentifier: "twoCell")
    let threenib = UINib(nibName: "ThreeTableViewCell", bundle: nil)
    tableView.register(threenib, forCellReuseIdentifier: "threeCell")
    let fournib = UINib(nibName: "FourTableViewCell", bundle: nil)
    tableView.register(fournib, forCellReuseIdentifier: "fourCell")
    let noNib = UINib(nibName: "NoTableViewCell", bundle: nil)
    tableView.register(noNib, forCellReuseIdentifier: "noCell")

  }
  override func viewWillAppear(_ animated: Bool) {
    loadDate()
  }
  func loadDate(){
    let query = NCMBQuery(className: "Post")
    query?.findObjectsInBackground({ result, error in
      if error != nil{
        print(error)
      }else{
        self.resultArray = result as! [NCMBObject]
        self.reslutArray.reverse()
        self.tableView.reloadData()
      }
    })
  }
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return resultArray.count
  }
 
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let imageArray = resultArray[indexPath.row].object(forKey: "imageUrl")as! [String]
    switch imageArray.count{
    case 1:
      let cell = tableView.dequeueReusableCell(withIdentifier: "oneCell", for: indexPath)as! oneTableViewCell
      cell.oneImageView.kf.setImage(with: URL(string: imageArray[0]))
      return cell
    case 2:
      let cell = tableView.dequeueReusableCell(withIdentifier: "twoCell", for: indexPath)as! TwoTableViewCell
      cell.oneImageView.kf.setImage(with: URL(string: imageArray[0]))
      cell.twoImageView.kf.setImage(with: URL(string: imageArray[1]))
      return cell
    case 3:
      let cell = tableView.dequeueReusableCell(withIdentifier: "threeCell", for: indexPath)as! ThreeTableViewCell
      cell.oneImageView.kf.setImage(with: URL(string: imageArray[0]))
      cell.twoImageView.kf.setImage(with: URL(string: imageArray[1]))
      cell.threeImageView.kf.setImage(with: URL(string: imageArray[2]))
      return cell
    case 4:
      let cell = tableView.dequeueReusableCell(withIdentifier: "fourCell", for: indexPath)as! FourTableViewCell
      cell.oneImageView.kf.setImage(with: URL(string: imageArray[0]))
      cell.twoImageView.kf.setImage(with: URL(string: imageArray[1]))
      cell.threeImageView.kf.setImage(with: URL(string: imageArray[2]))
      cell.fourImageView.kf.setImage(with: URL(string: imageArray[3]))
      return cell
    default:
      let cell = tableView.dequeueReusableCell(withIdentifier: "noCell", for: indexPath)as! NoTableViewCell
      return cell
    }
  }
}

```
保存している画像の枚数に従って別のcellに投稿内容を表示しています。
###### 例）3枚の場合
![スクリーンショット 2022-08-03 午前5.08.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763612/7c0d5405-5ef5-de89-d91b-5497201d8001.png)
###### 例）4枚の場合
![スクリーンショット 2022-08-03 午前5.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763612/092c5679-3d6d-6fab-a11b-6f969e169462.png)


### 最後に
いろいろとミスがあると思うので、ご指摘お願いします。
あと、絶対にもっといい方法あるはず。