しょうき
===
###### tags: `Life is Tech!`
# Realmに写真を保存する方法
## Realmをインストールする方法
- Cocoapodsでインストール
- Swift Package Managerでインストール
どっちも教科書にあるよ!
## 写真を撮影する
写真を撮影するには、まずViewControllerに写真を撮ることを伝えてあげる必要があるよ!
```ViewController.swift:Swift
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
```
このようにしてカメラを起動するViewControllerに設定しよう!
## データを保存する型を作る (Realm)
新しいファイルを作って、保存するデータの型を作ろう!
このような画面が出たら`Swift File`を選ぼう!

例 (状況に応じて変更しよう!)
```: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
}
```