메세지✉️ 모델 만들고 관찰👀하기

sanghee·2021년 8월 9일
1

🚩iOS

목록 보기
6/18
post-thumbnail

MVVM 패턴🏁?

Velog - MVVM

이전에 MVVM에 대해 알아봤었다.

MVVM 패턴은 모델(Model), 뷰(View), 뷰모델(ViewModel)로 구성되어 있다.

  • 뷰: UI에 관련된 코드이다.
  • 뷰 모델: 뷰가 사용할 메서드와 필드를 구현하고 뷰에게 상태 변화를 알린다.
  • 모델: 데이터의 구조를 정의한다.

Identifiable?

Apple Developer Documentation - Identifiable

A class of types whose instances hold the value of an entity with stable identity.

Message 모델 만들기

Model 폴더에 Message 파일을 생성한다. Message는 id값을 가지므로 Identifiable 프로토콜을 사용한다.

import Foundation

struct Message: Identifiable {
    let id: String
}

Message 모델 완성!

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 = ""
    }
}

@ObservableObject, @Published📚 ↔ @ObservedObject👀

  • 뷰모델
    • 뷰모델은 @ObservableObject이다. 관찰이 가능하다.
    • 뷰모델 안의 messages 배열이 @Published되었다. messages 배열이 출판되었다.
    • 뷰에서 뷰모델을 @ObservedObject 관찰하고 있다.
    • @Published된 messages가 변화할 때마다 UI를 업데이트한다.

깃허브 커밋 주소

GitHub - Commit

profile
👩‍💻

0개의 댓글