티스토리 뷰
iOS 개발할 때 사용되고 있는 MVC , MVP , MVVM 패턴에 대해 알아보고자 한다.
MVC
Model - 데이터에 관한 로직 담당
View - 사용자에게 보여지는 화면 담당
Controller - Model 과 View 연결
View 와 Controller 가 강하게 연결되어 있기 때문에 View, Controller 를 ViewController 에서 수행하게 된다.
Model 만 따로 만들어 주면 된다.
struct Bookmark: Codable {
let sourceLange: Language
let translatedLanguage: Language
let sourceText: String
let translatedText : String
}
Model
final class BookmarkListViewController: UIViewController {
private var bookmark: [Bookmark] = []
private lazy var collectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
let inset: CGFloat = 16.0
layout.estimatedItemSize = CGSize(width: view.frame.width - (inset * 2), height: 100.0)
layout.sectionInset = UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset)
layout.minimumLineSpacing = 16.0
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = .secondarySystemBackground
collectionView.register(BookmarkCollectionViewCell.self, forCellWithReuseIdentifier: BookmarkCollectionViewCell.identifier)
collectionView.dataSource = self
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupLayout()
navigationItem.title = "즐겨찾기"
navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bookmark = UserDefaults.standard.bookmarks
collectionView.reloadData()
}
}
ViewController
장점
- 설계가 단순하며 쉽고 빠르게 개발이 가능하다.
단점
- ViewController 의 역할이 커지게 된다.
- View 와 Model 이 서로 의존적
MVP
Presenter 를 이용해 View 와 Model 의 의존성을 제거한다.
final class ReviewListController: UIViewController {
private lazy var presenter = ReviewListPresenter(viewController: self)
private lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.dataSource = presenter
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
presenter.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
presenter.viewWillAppear()
}
}
ViewController
protocol ReviewListProtocol {
func setupNavigationBar()
func setupViews()
func presentToReviewWriteViewController()
func reloadTableView()
}
final class ReviewListPresenter: NSObject{
private let viewController: ReviewListProtocol
private let userDefaultManager: UserDefaultManagerProtocol
private var review: [BookReview] = []
init(viewController: ReviewListProtocol
,userDefaultManager : UserDefaultManagerProtocol = UserDefaultManager()
) {
self.viewController = viewController
self.userDefaultManager = userDefaultManager
}
func viewDidLoad() {
viewController.setupNavigationBar()
viewController.setupViews()
}
func viewWillAppear() {
review = userDefaultManager.getReviews()
viewController.reloadTableView()
}
func didTapRightBarButtonItem() {
viewController.presentToReviewWriteViewController()
}
}
Presenter
장점
- 독립적으로 테스트에 용이하다
- View 는 출력만 하는 역할을 수행한다.
단점
- View 와 Presenter 1:1 관계
MVVM
ViewModel 는 Model 를 View 에 맞게 가공 및 처리 ( 데이터 비즈니스 로직 담당)
class MyInfoViewController: UIViewController {
let myInfoViewModel = MyInfoViewModel()
func getUser() {
myInfoViewModel.getUser(idtoken: UserManager.idtoken!) { user, APIStatus in
switch APIStatus {
case .success :
guard let user = user else {
return
}
self.userData = user
self.collectionView.dataSource = self
self.collectionView.delegate = self
case .unregisterdUser :
return
case .expiredToken :
AuthNetwork.getIdToken { error in
switch error {
case .success :
self.getUser()
case .failed :
self.view.makeToast(APIErrorMessage.failed.rawValue)
default :
self.view.makeToast(APIErrorMessage.failed.rawValue)
}
}
default:
self.view.makeToast("에러가 발생했습니다. 잠시 후 다시 시도해주세요.")
}
}
}
Viewcontroller
User 를 API를 통해 viewModel 에서 가져온 후 ViewController 에서 데이터 바인딩 해준다.
class MyInfoViewModel {
let imageArray = ["notice", "faq", "qna", "setting_alarm", "permit"]
let textArray = ["공지사항", "자주 묻는 질문", "1:1 문의", "알람 설정", "이용 약관" ]
/// 내 유저 정보가져오기
/// - Parameters:
/// - idtoken: 파이어베이스 id 토큰
/// - completion: user, apistatus 리턴
func getUser(idtoken: String, completion: @escaping(User?, APIStatus?) -> Void ) {
let userNetwork = UserNetwork(idtoken: idtoken)
userNetwork.getUser { user, APIStatus in
switch APIStatus {
case .success:
completion(user, .success)
//...
}
}
}
ViewModel
장점
- View 와 ViewModel 관계는 N: 1 이다.
- View 와 Model 이 서로 독립성을 유지하게 된다.
단점
- ViewModel 의 역할이 커질 수 있다.
- ViewModel의 설계가 어렵다.
Reference
'IOS' 카테고리의 다른 글
만보기 iOS 앱 개발기 (0) | 2023.10.09 |
---|
- Total
- Today
- Yesterday
- BigData
- SWIFT
- python
- 엘라스틱서치
- MYSQL
- 리눅스
- 네트워크
- WEB
- nginx
- docker
- pytest
- ElasticSearch
- logstash
- network
- 도커
- flask
- linux
- ios
- 로그
- spark
- SQL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |