iOSでFirebase入門 その2
今回やること
- データの読み込み
- データの書き込み
- 実装
メモ帳みたいな記事なので悪しからず...
読み込みと書き込みで共通のやるべきこと
まず、以下がインストールされていることを確認。
pod 'Firebase/Core' pod 'Firebase/Database' pod 'SwiftyJSON'
RealTime DatabaseとCloud Firestoreの2種類があるが、ここではRealTimeDatabaseを使う。コンソール(Webサイトのやつ)からRealtime Databaseのルールを開き、writeとreadの権限をtrueにする。
次はXcodeのプロジェクト側。データベースへの参照を定義する。
var ref: DatabaseReference! ref = Database.database().reference()
データの読み込み
observeを使うことでデータベースにアクセスできる。observeメソッドはデータベースに変更がある度に自動的に呼び出される。引数によって、変更の種類を選択できる。observeの他にobserveSingleEventというメソッドがあり、こっちは一度だけ実行されるメソッド。結果はsnapShotに格納される。
var username: [String] override func viewDidLoad() { super.viewDidLoad() ref = Database.database().reference() let postRef = ref.child("users") postRef.observe(.value) { (snapShot) in let json = JSON(snapShot.value as? [String : AnyObject] ?? [:]) self.username = [] for (key, val) in json.dictionaryValue { self.username.append(json[key]["username"].stringValue) } } }
データの書き込み
Firebase Realtime DatabaseではJsonオブジェクトで保存される。Jsonは連想配列のようなもの。
{ "users": { "alovelace": { "name": "Ada Lovelace", "contacts": { "ghopper": true }, }, "ghopper": { ... }, "eclarke": { ... } } }
データベースにデータを保存する為のメソッド一覧。(公式からの引用)
メソッド | 一般的な使用例 |
---|---|
setValue | users/ |
childByAutoId | データのリストに追加します。childByAutoId を呼び出すたびに、user-posts/ |
updateChildValues | データのすべてを置換することなく、定義済みのパスのキーの一部を更新します。 |
runTransactionBlock | 同時更新によって破損する可能性がある複合データを更新します。 |
以下のようにすることで、データベースにデータが追加されます。
let data = ["username": "jon", "message": "hello"] let uid = "001" ref.child("users").child(uid).setValue(data)
let data = ["username": "Albert"] let uid = "001"
とし、ユーザー名前だけを変更したい場合、setValueだと前回追加した際に記録されている"message"が消えてしまいます。これはsetValueはchildで指定した階層以下全てを書き換えるためです。他の値を残したいまま、更新したい場合はupdateChildvaluesを用います。
childByAutoIdは自動的にIDを割り振ってくれます。
let data = ["username": "bob","message":"good bye"] ref.child("chat").childByAutoId().setValue(data)
実装
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var ref: DatabaseReference! var username: [String] = [] @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self ref = Database.database().reference() let postRef = ref.child("users") postRef.observe(.value) { (snapShot) in let json = JSON(snapShot.value as? [String : AnyObject] ?? [:]) if json.count == 0 { return } self.username = [] for (key, val) in json.dictionaryValue { self.username.append(json[key]["username"].stringValue) } self.tableView.reloadData() } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.username.count } func numberOfSections(in tableView: UITableView) -> Int { // sectionの数を決める return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "firebase_cell", for: indexPath) cell.textLabel?.text = self.username[indexPath.row] return cell } } class AddDataViewController: UIViewController, UITextFieldDelegate{ @IBOutlet weak var username_textField: UITextField! @IBOutlet weak var message_textField: UITextField! var ref: DatabaseReference! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. ref = Database.database().reference() username_textField.delegate = self message_textField.delegate = self } @IBAction func sendData(_ sender: Any) { let data = ["username": username_textField.text!,"message":message_textField.text!] ref.child("users").childByAutoId().setValue(data) performSegue(withIdentifier: "toTableView",sender: nil) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } }