自分のために備忘録として記載してます。
この記事でやること
- チャット一覧画面作成
- 各チャットタップ時に該当画面へ遷移する機能の実装
- チャット作成ボタンの設置とチャット作成機能の実装
環境
- Xcode 15.0.1
- Swift 5
前提
- 下記まで完了していること
https://qiita.com/taku-ll/items/3af114563f6307b6f3e9
実装方法
StoryBoardの設定
- ViewControllerを設置
- TableViewを設置
- TableViewCellを設置
- TableViewを選択し、右側のインスペクターパネルの中にある「Connections Inspector」(接続インスペクタ)を開き、DataSourceおよびDelegateをControllerViewにドロップする
- TableViewを次章で出てくるtableViewにOutlet接続する
ChatListViewController
全量
import UIKit
import FirebaseFirestore
class ChatListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var chats: [Chat] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
fetchChats()
navigationItem.title = "チャット一覧"
let createChatButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(createChat))
navigationItem.rightBarButtonItem = createChatButton
}
@IBAction func createChat(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "showChatCreation", sender: self)
}
func fetchChats() {
// Firestoreからチャットリストを取得
let db = Firestore.firestore()
db.collection("chats").getDocuments { snapshot, error in
if let error = error {
print("Error getting documents: \(error)")
} else {
self.chats = snapshot?.documents.compactMap { document -> Chat? in
try? document.data(as: Chat.self)
} ?? []
self.tableView.reloadData()
}
}
}
// UITableViewデリゲートおよびデータソースメソッド
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return chats.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath)
let chat = chats[indexPath.row]
cell.textLabel?.text = chat.name
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let chat = chats[indexPath.row]
performSegue(withIdentifier: "showChat", sender: chat)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showChat" {
if let chatViewController = segue.destination as? ChatViewController, let chat = sender as? Chat {
chatViewController.chat = chat
}
} else if segue.identifier == "showChatCreation" {
if let chatCreationViewController = segue.destination as? ChatCreationViewController {
chatCreationViewController.delegate = self
}
}
}
}
extension ChatListViewController: ChatCreationDelegate {
func didCreateChat(chat: Chat) {
// 新しいチャットを作成し、チャット画面に遷移する
self.chats.append(chat)
self.tableView.reloadData()
self.performSegue(withIdentifier: "showChat", sender: chat)
}
}
インポート
import UIKit
import FirebaseFirestore
- import UIKit: UIKitフレームワークをインポートして、UIコンポーネントを使用できるようにします。
- import FirebaseFirestore: Firestoreをインポートして、Firebaseのクラウドデータベース機能を使用できるようにします。
ChatListViewControllerクラス
class ChatListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
- ChatListViewController: チャット一覧を表示するためのビューコントローラークラスです。
- UITableViewDelegate: テーブルビューの行選択やスクロールなどのイベントを処理するためのデリゲートプロトコルです。
- UITableViewDataSource: テーブルビューに表示するデータを提供するためのデータソースプロトコルです。
プロパティ
@IBOutlet weak var tableView: UITableView!
var chats: [Chat] = []
- @IBOutlet weak var tableView: UITableView!: Interface Builderで接続されたテーブルビューのアウトレットです。
- var chats: [Chat] = []: チャットデータを格納する配列です。
viewDidLoadメソッド
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
fetchChats()
navigationItem.title = "チャット一覧"
let createChatButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(createChat))
navigationItem.rightBarButtonItem = createChatButton
}
- override func viewDidLoad(): ビューがロードされたときに呼び出されるメソッドです。
- tableView.delegate = self: テーブルビューのデリゲートをこのビューコントローラーに設定します。
- tableView.dataSource = self: テーブルビューのデータソースをこのビューコントローラーに設定します。
- fetchChats(): チャットデータをFirestoreから取得するメソッドを呼び出します。
- navigationItem.title = "チャット一覧": ナビゲーションバーのタイトルを「チャット一覧」に設定します。
- navigationItem.rightBarButtonItem = createChatButton: 右上にチャット作成ボタンを追加します。(※他記事で説明)
createChatアクション(※他記事で説明)
@IBAction func createChat(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "showChatCreation", sender: self)
}
- @IBAction func createChat(_ sender: UIBarButtonItem): チャット作成ボタンがタップされたときに呼び出されるアクションメソッドです。
- performSegue(withIdentifier: "showChatCreation", sender: self): "showChatCreation"セグエを実行してチャット作成画面に遷移します。
fetchChatsメソッド
func fetchChats() {
let db = Firestore.firestore()
db.collection("chats").getDocuments { snapshot, error in
if let error = error {
print("Error getting documents: \(error)")
} else {
self.chats = snapshot?.documents.compactMap { document -> Chat? in
try? document.data(as: Chat.self)
} ?? []
self.tableView.reloadData()
}
}
}
- func fetchChats(): Firestoreからチャットデータを取得してchats配列に格納し、テーブルビューを更新するメソッドです。
- let db = Firestore.firestore(): Firestoreのインスタンスを取得します。
- db.collection("chats").getDocuments { ... }: "chats"コレクションからドキュメントを取得します。
- self.chats = snapshot?.documents.compactMap { document -> Chat? in try? document.data(as: Chat.self) } ?? []: 取得したドキュメントをChatオブジェクトに変換してchats配列に格納します。
- self.tableView.reloadData(): テーブルビューをリロードしてデータを表示します。
UITableViewDataSourceメソッド
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return chats.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath)
let chat = chats[indexPath.row]
cell.textLabel?.text = chat.name
return cell
}
- func numberOfSections(in tableView: UITableView) -> Int: テーブルビューのセクション数を返します。この場合、セクションは1つです。
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int: 各セクションの行数を返します。この場合、chats配列の数です。
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell: 各行のセルを設定して返します。チャット名をセルに設定します。
UITableViewDelegateメソッド
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let chat = chats[indexPath.row]
performSegue(withIdentifier: "showChat", sender: chat)
}
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath): 行が選択されたときに呼び出されます。選択されたチャットをsenderとして"showChat"セグエを実行します。
prepareメソッド (※他記事で説明)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showChat" {
if let chatViewController = segue.destination as? ChatViewController, let chat = sender as? Chat {
chatViewController.chat = chat
}
} else if segue.identifier == "showChatCreation" {
if let chatCreationViewController = segue.destination as? ChatCreationViewController {
chatCreationViewController.delegate = self
}
}
}
- override func prepare(for segue: UIStoryboardSegue, sender: Any?): セグエが実行される前に呼び出され、データを次のビューコントローラーに渡します。
- if segue.identifier == "showChat": "showChat"セグエの場合、ChatViewControllerにチャットデータを渡します。
- if segue.identifier == "showChatCreation": "showChatCreation"セグエの場合、ChatCreationViewControllerのデリゲートを設定します。
ChatCreationDelegateメソッド(※他記事で説明)
extension ChatListViewController: ChatCreationDelegate {
func didCreateChat(chat: Chat) {
self.chats.append(chat)
self.tableView.reloadData()
self.performSegue(withIdentifier: "showChat", sender: chat)
}
}
- extension ChatListViewController: ChatCreationDelegate: ChatCreationDelegateプロトコルを実装するための拡張です。
- func didCreateChat(chat: Chat): 新しいチャットが作成されたときに呼び出されます。新しいチャットをchats配列に追加し、テーブルビューをリロードして、"showChat"セグエを実行します。