Firebaseの初期設定自体は終わっている前提で進めます。
Firebaseコンソール画面でRealTime Databaseだけ立ち上げておいてください。
Contents 非表示
実装
Message.swift (メッセージのモデル)
import Foundation
struct Message: Identifiable {
let id: String
let text: String
let sender: String
}
ChatViewModel (メッセージ送信 & 監視)
import FirebaseDatabase
final class ChatViewModel: ObservableObject {
@Published var messages: [Message] = []
private var ref: DatabaseReference = Database.database().reference()
init() {
observeMessages()
}
// メッセージ送信
func sendMessage(text: String, sender: String) {
let message = ["text": text, "sender": sender]
ref.child("messages").childByAutoId().setValue(message)
}
// Database内のメッセージ監視
func observeMessages() {
ref.child("messages").observe(.childAdded) { snapshot in
if let data = snapshot.value as? [String: String],
let text = data["text"],
let sender = data["sender"] {
let message = Message(id: snapshot.key, text: text, sender: sender)
DispatchQueue.main.async {
self.messages.append(message)
}
}
}
}
}
HomeView.swift (メインのView)
import SwiftUI
struct HomeView: View {
@StateObject var chatViewModel = ChatViewModel()
@State private var messageTextMichael: String = ""
@State private var messageTextLincoln: String = ""
@State private var senderNameMichael: String = "Michael"
@State private var senderNameLincoln: String = "Lincoln"
var body: some View {
VStack {
ScrollView {
VStack {
ForEach(chatViewModel.messages) { message in
HStack {
if message.sender == senderNameMichael {
Spacer()
VStack(alignment: .trailing) {
Text("\(message.sender):")
.bold()
.font(.system(size: 12))
Text(message.text)
.padding(10)
.background(Color.blue.opacity(0.3))
.cornerRadius(8)
}
} else if message.sender == senderNameLincoln {
VStack(alignment: .leading) {
Text("\(message.sender):")
.bold()
.font(.system(size: 12))
Text(message.text)
.padding(10)
.background(Color.green.opacity(0.3))
.cornerRadius(8)
}
Spacer()
}
}
.padding([.leading, .trailing], 10)
}
}
}
Divider().padding(.vertical, 10)
HStack {
TextField("Enter message (Michael)", text: $messageTextMichael)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minHeight: 30)
Button {
if !messageTextMichael.isEmpty {
chatViewModel.sendMessage(text: messageTextMichael, sender: senderNameMichael)
messageTextMichael = ""
}
} label: {
Text("Send as Michael")
.bold()
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
.padding()
HStack {
TextField("Enter message (Lincoln)", text: $messageTextLincoln)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minHeight: 30)
Button {
if !messageTextLincoln.isEmpty {
chatViewModel.sendMessage(text: messageTextLincoln, sender: senderNameLincoln)
messageTextLincoln = ""
}
} label: {
Text("Send as Lincoln")
.bold()
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(8)
}
}
.padding()
}
}
}