しょうき === ###### tags: `Life is Tech!` # Realmに写真を保存する方法 ## Realmをインストールする方法 - Cocoapodsでインストール - Swift Package Managerでインストール どっちも教科書にあるよ! ## 写真を撮影する 写真を撮影するには、まずViewControllerに写真を撮ることを伝えてあげる必要があるよ! ```ViewController.swift:Swift class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { ``` このようにしてカメラを起動するViewControllerに設定しよう! ## データを保存する型を作る (Realm) 新しいファイルを作って、保存するデータの型を作ろう! このような画面が出たら`Swift File`を選ぼう! ![](https://i.imgur.com/aAEMDog.png) 例 (状況に応じて変更しよう!) ```:Swift import Foundation import RealmSwift class PictureData: Object { // 写真を保存するdata @objc dynamic var data: NSData! // 写真の説明を保存するtitle @objc dynamic var title = "" } ``` ## ボタンを押したときにカメラを起動しよう! ```ViewController.swift:Swift @IBAction func addImage() { // 写真のピッカーを設定する let picker = UIImagePickerController() // 写真をカメラから取得するように設定する picker.sourceType = .camera // 写真を選ぶピッカーの管理者を自分(self)に設定する picker.delegate = self // ピッカー(カメラ)を起動する present(picker, animated: true, completion: nil) } ``` ```ViewController.swift:Swift func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // Realmの初期化 let realm = try! Realm() // 撮影した写真の取得 let image = info[.originalImage] as! UIImage // 写真を変換 let data = NSData(data: image.jpegData(compressionQuality: 0.9)!) // Realmにデータを保存する let pictureData = PictureData() // 写真を設定 pictureData.data = data // 写真の説明を設定 pictureData.title = "Test" // Realmにデータを書き込む try! realm.write { realm.add(pictureData) } // カメラを終了する self.dismiss(animated: true, completion: nil) } ``` ## タイトルを聞くアラートの表示 変数をViewDidLoadの前で定義する ```:Swift var pictureTitle = "" ``` ボタンを押したときにアラートが出るようにする ```:Swift // アラートの表示 let ac = UIAlertController(title: "タイトルを入力", message: "", preferredStyle: .alert) let ok = UIAlertAction(title: "OK", style: .default, handler: {[weak ac] (action) -> Void in guard let textFields = ac?.textFields else { return } for text in textFields { if text.tag == 1 { self.pictureTitle = text.text } } }) let cancel = UIAlertAction(title: "キャンセル", style: .cancel, handler: nil) //textfiledの追加 ac.addTextField(configurationHandler: {(text:UITextField!) -> Void in text.tag = 1 }) ac.addAction(ok) ac.addAction(cancel) present(ac, animated: true, completion: nil) ``` ## カスタムCollectionView Cellの設定 ### BluePrintViewControllerに以下のコードを追加して関連づけしよう! ```:Swift import UIKit import RealmSwift class BluePrintCollectionViewCell: UICollectionViewCell { @IBOutlet var imageView: UIImageView! @IBOutlet var titleLabel: UILabel! } class BluePrintViewController: UIViewController { // 後略 ``` ### CollectionViewの設定をしていこう! CollectionViewを関連付けしよう! ```:Swift // 前略 class BluePrintViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView! // 後略 ``` ### Realmのデータを取得する #### 取得したデータを保存する配列を作ろう Realmでは配列(例: [String])を使わずに`Results`型を使うよ! ```:Swift var pictures: Results<PictureData>! ``` #### データを取得する ```:Swift override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Realmの初期化 let realm = try! Realm() // Realmから保存されている写真のデータを取得 pictures = realm.objects(PictureData.self) // CollectionViewを更新 collectionView.reloadData() } ``` #### Realmの情報を表示しよう! ```:Swift // CollectionViewに何個表示するかを伝える func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // picturesの配列の中身の数を表示する return pictures.count } // さっき作ったCollectionViewのセルにアイテムを表示 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // Main.StoryboardのCellを探してくる let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BluePrintCollectionViewCell // imageViewに写真を表示 cell.imageView.image = UIImage(data: pictures[indexPath.row].data) // Labelにタイトルを表示 cell.titleLabel.text = pictures[indexPath.row].title // Cellに適用する return cell } ```