LoginSignup
19
21

More than 3 years have passed since last update.

Swift + Firebaseで簡単なiOSアプリを作成してみよう

Last updated at Posted at 2019-12-04

環境

  • OS:MacOS Catalina 10.15.1
  • Swift 5.1
  • Xcode 11.2.1

作成するアプリのイメージ

ユーザーを管理するアプリを作成します。
理由としては、以下の3点。

  • 自分で定義した型を使う
  • CRUDが全部できる
  • かんたん

ユーザーである必要はないんだけど、型が考えやすいので。

Firebaseの環境設定

環境設定に関しては、下記の記事を参照してください。
iOSでFirebaseを使用して、データベースに対してCRUDを試してみる。 - Qiita

一覧画面を作成しよう

ユーザー型の定義

ユーザーは、以下の要素を持つことにします。

User.swift
import UIKit
import Firebase

struct User {
    var name: String = ""
    var age: Int = 0
    var favoriteFood: String = ""
}

StoryBoardを作成する

画像のように、NavigationControllerとTableView、TableCellを配置します。
TableCellにIDをつけておきましょう。(今回はUserTableCellにしました)

0f63476b.png

TableCellに3つラベルを配置します。後で使うのでTagもつけておきます。

65647859.png

ViewControllerを作成する

Firebaseからの応答は、直接構造体に格納できません。そこで、[String: Any]から自分に代入するメソッドを追加します。

User.swift
import UIKit
import Firebase

struct User {
    var name: String = ""
    var age: Int = 0
    var favoriteFood: String = ""

    /// Dictionaryから、自分自身に代入します。
    /// - Parameter dictionary: User型
    mutating func setFromDictionary(_ dictionary: [String: Any]) {
        name = dictionary["name"] as? String ?? ""
        age = dictionary["age"] as? Int ?? 0
        favoriteFood = dictionary["favoriteFood"] as? String ?? ""
    }
}

TableViewに取得したユーザーを表示するプログラムを書きます。

UsersListViewController.swift
import UIKit
import Firebase

class UsersListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate  {

    @IBOutlet weak var usersTableView: UITableView!
    var users: [User]!

    override func viewDidLoad() {
        super.viewDidLoad()
        usersTableView.dataSource = self
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let ref = Database.database().reference()

        ref.child("Users").observe(.value) { (snapshot) in
            // 初期化
            self.users = []

            for data in snapshot.children {
                let snapData = data as! DataSnapshot
                let dictionarySnapData = snapData.value as! [String: Any]

                var user = User()
                // 取得した内容をユーザー型にセット
                user.setFromDictionary(dictionarySnapData)

                // ユーザーリストに追加
                self.users.append(user)
            }

            // すべてユーザーリストに格納したら、TableViewを更新する。
            self.usersTableView.reloadData()
        }
    }

    // MARK: - TableViewMethod
    // セルの個数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let _users = users else { return 0 }
        return _users.count
    }
    // セルに値をセット
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = usersTableView.dequeueReusableCell(withIdentifier: "UserTableCell", for: indexPath)

        let user = users[indexPath.row]

        let nameLabel = cell.viewWithTag(1) as! UILabel
        nameLabel.text = user.name

        let ageLabel = cell.viewWithTag(2) as! UILabel
        ageLabel.text = String(user.age)

        let favoriteLabel = cell.viewWithTag(3) as! UILabel
        favoriteLabel.text = user.favoriteFood

        return cell
    }
    // セルタップ時
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath as IndexPath, animated: true)
    }

}

652a9db2.png

編集画面を作成しよう

StoryBoardを作成する

新しいViewControllerを配置して、TextField3つとButtonを1つ追加します。
あと一覧画面に遷移用のボタンを追加しておきます。

831c43b3.png

ViewControllerを作成する

Dictionaryでやり取りするので、Userに以下のメソッドを追加します。

User.swift
/// Dictionaryに変換します。
var toDictionary: [String: Any] {
    return [
        "name": name,
        "age": age,
        "favoriteFood": favoriteFood
    ]
}

追加用の処理を書きます。

UserEditViewController.swift

import UIKit
import Firebase

class UsersEditViewController: UIViewController {

    @IBOutlet weak var nameText: UITextField!
    @IBOutlet weak var ageText: UITextField!
    @IBOutlet weak var favoriteFoodText: UITextField!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

    @IBAction func submitButtonTapped(_ sender: UIButton) {

        let ref = Database.database().reference()

        // 入力内容をUserインスタンスに入れる
        var newUser = User()
        newUser.name = nameText.text!
        newUser.age = Int(ageText.text!) ?? 0
        newUser.favoriteFood = favoriteFood.text!

        // データを登録
        ref.child("Users").childByAutoId().setValue(newUser.toDictionary)

        // 登録後 前画面に戻る
        self.navigationController?.popViewController(animated: true)
    }
}

実行結果

b1ce87b4.gif

更新モードを作成しよう

前画面からキーを受け取れるようにし、
キーを指定して、データに値をセットします。
(下記以外にも色々追加していますが、詳細については最後に貼ります。)

UserEditViewController.swift

import UIKit
import Firebase

class UsersEditViewController: UIViewController {

    @IBOutlet weak var nameText: UITextField!
    @IBOutlet weak var ageText: UITextField!
    @IBOutlet weak var favoriteFoodText: UITextField!
    @IBOutlet weak var submitButton: UIButton!

    var user: User!
    // 前画面からキーを受け取る
    var key: String!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // 前画面から受け取った値をセットする
        // (ホントはキーのみ受け取って再検索するほうが良さそう)
        nameText.text = user.name
        ageText.text = String(user.age)
        favoriteFoodText.text = user.favoriteFood
    }

    // MARK: - EventFunctions
    @IBAction func submitButtonTapped(_ sender: UIButton) {

        let ref = Database.database().reference()

        // 入力内容をUserインスタンスに入れる
        var newUser = User()
        newUser.name = nameText.text!
        newUser.age = Int(ageText.text!) ?? 0
        newUser.favoriteFood = favoriteFoodText.text!


        // データを更新
        ref.child("Users").child(key).setValue(newUser.toDictionary)

        // 処理終了後 前画面に戻る
        self.navigationController?.popViewController(animated: true)
    }

3e94725e.gif

削除機能を作成しよう

スワイプ時のTableViewMethodを追加します。

// セルスワイプ時(削除)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) ->
UISwipeActionsConfiguration? {

    let delete = UIContextualAction(style: .destructive, title: "削除") { (action, sourceView, completionHandler) in
completionHandler(true)

        let ref = Database.database().reference()
        ref.child("Users").child(self.keys[indexPath.row]).removeValue()
    }
    let swipeAction = UISwipeActionsConfiguration(actions: [delete])
    swipeAction.performsFirstActionWithFullSwipe = true
    return swipeAction
}

9ad8c400.gif

ソースコード

ソースコードはGitHubに置いてますので、欲しい人はどうぞ。
SampleFirebase

まとめ

とりあえず基本のCRUDをアプリっぽく再現できたぞ!
今回はRealTimeDatabaseを使用しましたが、CloudFireStoreのほうが今はおすすめらしいので、そっちも時間があればやってみます。

19
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21