이전에 MVVM에 대해 알아봤었다.
MVVM 패턴은 모델(Model), 뷰(View), 뷰모델(ViewModel)로 구성되어 있다.
Apple Developer Documentation - Identifiable
A class of types whose instances hold the value of an entity with stable identity.
Model 폴더에 Message 파일을 생성한다. Message는 id값을 가지므로 Identifiable 프로토콜을 사용한다.
import Foundation
struct Message: Identifiable {
let id: String
}
Message 모델은 id, text, timestamp값을 가진다.
import Foundation
struct Message: Identifiable {
let id = NSUUID().uuidString
let isFromCurrentUser: Bool
let text: String
}
Chat뷰모델은 Chat뷰와 연결될 뷰모델이다. 우선 목업 데이터로 messages에 할당한다. 내가 좋아하는 백예린의 square🟩 가사를 넣었다.
import Foundation
class ChatViewModel: ObservableObject {
@Published var messages = [Message]()
init() {
messages = mockMessages
}
var mockMessages: [Message] {
[
.init(isFromCurrentUser: true, text: "All the colors and personalities"),
.init(isFromCurrentUser: false, text: "You can’t see right through what I truly am"),
.init(isFromCurrentUser: true, text: "You’re hurting me without noticing"),
.init(isFromCurrentUser: false, text: "I’m so, so broke like someone just robbed me"),
.init(isFromCurrentUser: true, text: "I’m no invincible"),
.init(isFromCurrentUser: false, text: "I have much memories of getting more weaker"),
.init(isFromCurrentUser: true, text: "I know I’m not loveable"),
.init(isFromCurrentUser: false, text: "But you know what you’d have to say")
]
}
}
뷰에서는 뷰모델에서 messages 정보를 가져와 ForEach로 각각 접근하여 ChatCell을 만든다.
struct ChatView: View {
@ObservedObject var viewModel = ChatViewModel()
@State private var text = ""
var body: some View {
VStack {
ScrollView {
VStack(spacing: 16) {
ForEach(viewModel.messages) { message in
ChatCell(message: message)
}
}
}
}
}
text를 받아서 메세지를 생성해 messages 배열에 추가하는 sendMessage 메소드를 추가하였다.
import Foundation
class ChatViewModel: ObservableObject {
@Published var messages = [Message]()
...
func sendMessage(_ text: String) {
let message = Message(isFromCurrentUser: true, text: text)
messages.append(message)
}
}
text는 텍스트필드와 연결되어 있는 변수이다. 텍스트필드에서 메세지를 작성하고 보내면 text 변수를 빈 문자열로 초기화한다. 뷰모델의 메소드를 뷰에서 사용하려면, viewModel.메소드이름으로 접근하면 된다.
struct ChatsView: View {
@ObservedObject var viewModel = ChatViewModel()
...
func sendMessage() {
viewModel.sendMessage(text)
text = ""
}
}