티스토리 뷰
안녕하세요 멍구입니다. ^-^//
오늘은 MVC의 MassiveViewController 문제를 해결할 수 있는 디자인패턴, MVVM패턴의 코드 구현 연습을 Swift언어를 사용해서 해볼까 합니다. 🤩
바로 시작하겠습니다.
MVVM패턴 Swift 코드로 구현 해보기
MVVM은 Model-View-ViewModel의 구성을 갖습니다.
먼저 이중에 Model을 구현해보겠습니다. 보통 Model은 Class, Struct등으로 정의됩니다. 아래에서 바로 코드로 구현해보겠습니다. 먼저 해당 프로젝트는 Playground에서 진행합니다. MVVM의 구현결과는 Playground의 LiveView에서 볼 예정입니다.
구현하기에 앞서 먼저, UIView를 Playground의 LiveView에서 표출하기 위해 두개의 프레임워크를 import 해줍니다.
이제 차례대로 구현해 보도록 할까요? 👍🏼
Model
모델 구성하기
모델로는 class로 Pet을 정의합니다. 코드는 아래와 같습니다.
import PlaygroundSupport
import UIKit
// MARK: Model
// - 예를 들면, pets를 채택하는 앱의 일부로서 Pet View를 만들 수 있습니다. 먼저, 아래와 같은 코드를 작성합니다.
public class Pet {
public enum Rarity {
case common
case uncommon
case rare
case veryRare
}
public let name: String
public let birthday: Date
public let rarity: Rarity
public let image: UIImage
public init(name: String, birthday: Date, rarity: Rarity, image: UIImage) {
self.name = name
self.birthday = birthday
self.rarity = rarity
self.image = image
}
}
Pet은 그 자체의 희소성을 구분하는 Rarity 열거형과 이름, 생일, 희귀성, 이미지의 멤버를 갖습니다.
또한 이러한 값들을 생성자로 받아 초기화 됩니다. Pet class는 모델(Model)입니다.
해당 모델은 독자적으로 View에 표출되어질 수 없습니다. Model은 ViewModel을 거쳐 View에 표출됩니다. MVVM의 ViewModel을 통해 View에 표출될 값으로 변환되어 사용되어집니다.
이어서 ViewModel을 구현하겠습니다.
ViewModel
뷰 모델 구성하기
뷰모델은 Pet Model을 View에 표출할 수 있는 값으로 변환해줍니다. 그 코드는 아래와 같습니다.
// MARK: ViewModel
public class PetViewModel {
// 1) pet : Pet 객체를 생성합니다. 나이 연산을 위해 Calendar도 생성합니다.
private let pet: Pet
private let calendar: Calendar
public init(pet: Pet) {
self.pet = pet
calendar = Calendar(identifier: .gregorian)
}
// 2) name : 펫의 이름을 반환합니다.
public var name: String {
return pet.name
}
// image : 펫의 이미지를 반환합니다.
public var image: UIImage {
return pet.image
}
// 3) ageText : 펫의 나이를 연산하며 반환합니다. 몇살인지를 표출합니다.
public var ageText: String {
let today = calendar.startOfDay(for: Date())
let birthday = calendar.startOfDay(for: pet.birthday)
let components = calendar.dateComponents([.year], from: birthday, to: today)
let age = components.year!
return "\(age) years old"
}
// 4) adoptionFeeText : 해당 펫의 희귀성에 따른 가격을 결정합니다.
public var adoptionFeeText: String {
switch pet.rarity {
case .common:
return "$50.00"
case .uncommon:
return "$75.00"
case .rare:
return "$150.00"
case .veryRare:
return "$500.00"
}
}
}
위의 코드는 Model, Pet이 거치게 되는 뷰모델, PetViewModel을 정의하고 있습니다.
위 주석에 번호 매긴 부분을 하나하나 돌아보도록 하겠습니다.
1) 먼저 pet, calendar를 생성합니다. 이들은 pet의 속성, 나이 등을 변환 및 반환하는데에 사용되어집니다. 생성자로 해당 값들은 초기화됩니다.
2) 그 다음 name, image를 위한 두개의 계산 프로퍼티를 선언합니다. name, image는 pet에 대해 표출되어야 하는 이름, 이미지 값을 반환할 때 사용되어집니다. 이는 Model의 값을 ViewModel에서 변환하는 가장 쉬운 방법의 예가 됩니다. 만약 펫의 이름 접두어를 수정하고 싶다면, ViewModel의 해당 부분에서 이름 구조를 수정하면 끝입니다.
3) 세번째로, 또 다른 계산 프로퍼티, ageText를 선언합니다. ageText 값 변환 시에는 오늘부터 ~ pet의 생일까지의 시간 차이를 계산하기 위해 calendar를 활용하고 있습니다. 여기에 "years old" 문자열이 따라오게 됩니다. 이후 어떠한 String 문자열 포멧 작업 없이 해당 값(ageText)를 뷰에 띄울 수 있습니다.
4) 마지막으로, 계산 프로퍼티로서 adoptionFeeText를 생성할 수 있습니다. adoptionFeeText에서는 rarity에 기반한 pet의 입양비용을 결정할 수 있습니다. 또한 이러한 값을 String 문자열로서 반환할 수 있습니다.
지금까지 MVVM의 Model인 Pet, ViewModel인 PetViewModel이 정의되었습니다.
마지막으로 Model이 ViewModel을 거쳐 표현되어질, 실제로 화면에 표출되어질 View를 정의해야겠죠?
View는 UIView로서 정의됩니다. 그러므로 UIKit을 import 해주어야 합니다.
View
뷰 구성하기
// MARK: View
public class PetView: UIView {
public let imageView: UIImageView
public let nameLabel: UILabel
public let ageLabel: UILabel
public let adoptionFeeLabel: UILabel
public override init(frame: CGRect) {
var childFrame = CGRect(x: 0,
y: 16,
width: frame.width,
height: frame.height / 2)
imageView = UIImageView(frame: childFrame)
imageView.contentMode = .scaleAspectFit
childFrame.origin.y += childFrame.height + 16
childFrame.size.height = 30
nameLabel = UILabel(frame: childFrame)
nameLabel.textAlignment = .center
nameLabel.textAlignment = .center
childFrame.origin.y += childFrame.height
ageLabel = UILabel(frame: childFrame)
ageLabel.textAlignment = .center
childFrame.origin.y += childFrame.height
adoptionFeeLabel = UILabel(frame: childFrame)
adoptionFeeLabel.textAlignment = .center
super.init(frame: frame)
backgroundColor = .white
addSubview(imageView)
addSubview(nameLabel)
addSubview(ageLabel)
addSubview(adoptionFeeLabel)
}
@available(*, unavailable)
public required init?(coder _: NSCoder) {
fatalError("init?(coder:) is not supported")
}
}
위의 코드는 MVVM의 View를 구현한 예시입니다.
해당 코드에서 총 4개의 서브뷰(subView)를 포함한 PetView를 선언하고 있습니다. 해당 뷰에서 pet의 이미지, 이름, 나이, 입양비를 표현하는 세개의 라벨을 중앙정렬하여 띄웁니다. 이 때 각각의 뷰에 대한 위치, 크기를 init(frame:)에서 설정할 수 있습니다. 마지막으로, 해당 뷰가 지원되지 않는다면, init?(coder:)에서 fatalError를 실행하여 런타임 크래시를 일으키도록 하고 있습니다.
자, 이렇게 Swift(스위프트) 언어를 사용한 MVVM의 구성 요소인 Model, ViewModel, View가 준비되었네요! 🤩
이제 해당 코드들을 Playground의 LiveView에 동작시킬 준비가 임박되었습니다. 다음 포스팅에서 LiveView에 뷰를 셋팅하고 표출을 해보는 과정을 정리해보겠습니다. 👨🏻💻
* 출처 : Design Patterns by Tutorials (lay wenderLich)
'iOS 개발' 카테고리의 다른 글
Google Swift 가이드라인, 한 줄에 하나의 선언하기 (0) | 2020.06.28 |
---|---|
iOS Swift 디자인패턴, MVVM 사용 전 생각해볼 사항 (0) | 2020.06.27 |
iOS 디자인패턴, MVC대신 MVVM 패턴을 사용하는 이유 (2) | 2020.06.25 |
iOS MVVM 디자인패턴, Model-View-ViewModel 개요 (0) | 2020.06.24 |
iOS leastNonzeroMagnitude, leastNormalMagnitude 알아보기 (0) | 2020.06.11 |
- Total
- Today
- Yesterday
- 알고리즘
- CoreML
- 프로그래머스
- swift언어
- publisher
- 컬렉션
- 개발자문서
- swift 문자열
- swift
- swift 기초
- 알고리즘문제
- 스위프트
- 프로그래머스swift
- ios
- 백준swift
- Protocol
- uikit
- SwiftUI
- 김프매매
- 프로토콜
- swift알고리즘
- 백준알고리즘
- swift reduce
- 자연어처리
- 부스트코스
- Swift 알고리즘
- Collection
- swift문제
- createML
- swift string
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |