티스토리 뷰

IOS

[Swift] - MVC, MVP, MVVM

내일도이렇게 2022. 4. 1. 16:16

 

iOS 개발할 때 사용되고 있는 MVC , MVP , MVVM 패턴에 대해 알아보고자 한다. 

 

MVC 

 

Model   - 데이터에 관한 로직 담당 

View -  사용자에게 보여지는 화면 담당

Controller -  Model 과 View 연결 

 

애플 MVC 패턴

 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 의 의존성을 제거한다.

 

mvp

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 

https://dev-leeyang.tistory.com/21

https://lsh424.tistory.com/68#recentComments

'IOS' 카테고리의 다른 글

만보기 iOS 앱 개발기  (0) 2023.10.09
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함