티스토리 뷰
이전 글을 읽고 오면 이해가 더 잘 될 것이다.
iOS) Design pattern MVVM(1/2) - MVC, MVVM 알아보기
시작 전
디자인 패턴에 대해서는 무엇이 정답이라는 것이 없다고 한다. 그만큼 맹신하면 안된다고 한다. 무엇이 장점이고 단점인지에 대해서 알고 사용해봤는지가 중요하다고 한다. 또한 현업에서도 같은 프로젝트 내에서 한가지 디자인 패턴만 사용하지 않는다고 한다. 그래서 어떤 상황에 어떤 패턴이 유리한지에 대해서 아는 것이 중요하다고 생각 했다.
다음 소개하는 mvvm 패턴은 기본적인 mvvm 의 구성요소에 충실하게 진행했다. 이것보다 더 구체적인 구조도 있고 같은 역할을 다르게 구현한 코드도 많다. 즉, 같은 mvvm 패턴내에서도 행동패턴을 어떻게 가져가냐에 따라 다양하다. 하나의 포스팅으로 배울 것이 아닌 여러 포스팅을 보고 충분히 이해한 후 진행하면 좋을 것 같다.
🌂 적용할 프로젝트
- 프로필사진 옆의 버튼을 누르면 이미지 변경
- 텍스트필드에 텍스트를 입력 후 버튼을 누르면 라벨의 텍스트 변경
🌂 Data Binding
우선 data binding 에 대해서 알아보자. 가장 쉽고 널리 알려진 Observable 테크닉을 사용할 것이다. Observable 이라는 클래스를 생성해서 바인딩 역할을 수행해주면 된다.
- Observable
이 클래스를 통해서 원하는 값으로 초기화해주고, binding 역할을 해주고, 값을 가져오는 함수를 제공할 것이다.
import Foundation
class Observable<T> {
typealias Listener = (T) -> Void
var listener: Listener?
// ✅ 값이 변할 때마다 클로저 listener 를 호출한다.(View 의 액션에 따라서 자동으로 View Model 의 값이 최신화.)
var value: T {
didSet {
listener?(value)
}
}
init(_ value: T) {
self.value = value
}
func bind(_ closure: @escaping (T) -> Void) {
self.listener = closure
listener?(value)
}
}
🌂 MVVM 패턴 적용
간단하게 인적사항을 다루는 프로젝트에 적용해보겠다.
- Person.swift
Model 역할
import Foundation
import UIKit
struct Person {
var name: String
var age: String
var image: UIImage
}
- ViewController.swift & Main.storyboard
View 역할
import UIKit
class ViewController: UIViewController {
// MARK: - Properties
// ✅ ViewModel 인스턴스화해서 사용
private var personViewModel = ViewModel()
// MARK: - @IBOutlet Properties
@IBOutlet weak var profileImg: UIImageView!
@IBOutlet weak var setProfileButton: UIButton!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var nameTextfield: UITextField!
@IBOutlet weak var ageLabel: UILabel!
@IBOutlet weak var ageTextfield: UITextField!
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
// ✅ View Model 이 업데이트 되면 view 를 바꿀 수 있도록 data binding 을 한다.
personViewModel.image.bind { image in
self.profileImg.image = image
}
personViewModel.name.bind { name in
self.nameLabel.text = name
}
personViewModel.age.bind { age in
self.ageLabel.text = age
}
}
// MARK: - @IBAction Properties
// ✅ @IBAction 으로 View Model을 업데이트한다.
@IBAction func touchSetProfile(_ sender: UIButton) {
personViewModel.setImg(to: "person.fill")
}
@IBAction func touchSetNameButton(_ sender: UIButton) {
if let name = nameTextfield.text {
personViewModel.setName(to: name)
}
}
@IBAction func touchSetAgeButton(_ sender: UIButton) {
if let age = ageTextfield.text {
personViewModel.setAge(to: age)
}
}
}
- View Model 역할
import Foundation
import UIKit
public class ViewModel {
// ✅ 아무 설정 없는 초기의 View 를 보여주기위한 목적의 변수 초기화
let defaultName = "홍길동"
let defaultAge = "25"
let defaultImage = "person"
// ✅ 변수 초기화
let name = Observable("")
let age = Observable("")
// ✅ 변수의 자료형 명시
let image: Observable<UIImage?> = Observable(nil)
init() {
setName(to: defaultName)
setAge(to: defaultAge)
setImg(to: defaultImage)
}
// ✅ value 를 바꾸어서 didSet 이 실행되도록 함.
func setName(to name: String) {
self.name.value = name
}
func setAge(to age: String) {
self.age.value = age
}
func setImg(to image: String) {
if let image = UIImage(systemName: image) {
self.image.value = image
}
}
}
🌂 끝
실습이 끝나고 mvvm 패턴 이미지를 살펴보았다. 아래는 mvvm 을 구글링하면 많이 볼 수 있는 이미지이다. 조금 더 잘 이해할 수 있게 된 것 같다.
출처 : https://lsh424.tistory.com/68
전체 코드:
출처:
'iOS > Design Pattern' 카테고리의 다른 글
iOS) Design pattern MVVM(1/2) - MVC, MVVM 알아보기 (0) | 2021.08.24 |
---|---|
iOS) Coordinator pattern 적용해보자- Advanced (7) | 2021.08.22 |
iOS) Coordinator pattern 적용해보자 - Basic (0) | 2021.08.21 |
- watchOS
- MVVM
- Objective-C
- UserDefaults
- Protocol
- rxswift
- MOYA
- 2022 KAKAO TECH INTERNSHIP
- urlsession
- YPImagePicker
- WidgetKit
- Firebase
- APNS
- WWDC22
- configurable widget
- CloneCoding
- containerBackground
- IOS
- async/await
- Notification
- Swift
- SwiftUI
- projectsetting
- Widget
- github
- OpenSourceLibrary
- 서버통신
- RxCocoa
- Algorithm
- WWDC
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Total
- Today
- Yesterday