기타/iOS 기초

<iOS 디자인패턴> swift MVC - 쉽게 설명

studying develop 2021. 7. 24. 16:38

MVC 

사실 스위프트 MVC로 검색해보면 말이 다 너무 어렵고, 설명만 봐서는 api 호출은 어디서할지, 모델을 여기서 변경해도 될지, notification은 어디다 걸어야 될지 등이 어렵다.

 

여기서의 설명이 꼭 맞지는 않지만 이렇게 해도 되구나 그냥 생각해보면 되겠다.

 

일단 밑에는 https://www.edwith.org/swiftapp/lecture/26620?isDesc=false 여기서 가져온 내용인데, 내가 바라본 입장에서 좀 더 설명해보겠다. 틀린 내용이 있으면 댓글 부탁드립니다.

 

1. Model

앱이 무엇인지에 대해 관심을 가집니다.

 

-> 앱이 가지는 데이터들을 정의한다. 즉 일기 앱이면 앱은 날짜와 메모 사항을 저장하고, 이를 모델에서 정의하는 것이다.

struct Diary {
	var date: Date?
	var memo: String?
}

 

즉 어떤 변수를 가질지에 큰 상관이 있다.

 

하지만 여기서 오해될 만한 사항이, UI를 관리하는 변수는 Model이 갖는 것이 아니다. ViewController에서 갖는다.

 

예를 들면 제목 라벨을 보여줄지 말지에 대해서는 앱의 데이터에 대한 모델이 아니라 뷰에 대한 데이터 이므로

 

MVC에서 뷰의 영역이 뷰컨트롤러에서 소유하고 관리하는 것입니다.

 

(즉 MVVM이면 이경우 viewcontroller나 viewModel이 갖게 됩니다. MVVM은 뷰영역이 뷰컨, 뷰, 뷰모델 세개로 많음)

class myVC: ViewController {
    var titleLabelIsHidden: Bool = false
    @IBOulet titleLabel: UILable!
    
    func viewDidLoad() {
        if (titleLabelIsHidden) {
            titleLabel.isHidden = true
        }
    }

}

 

 

UI 독립되어 있습니다.

 

-> 즉 Diary 구조체에는 뷰의 조절에 대한 변수인 titleLabelIsHidden을 소유하거나, 해당 변수의 값을 set할 일이 없습니다.

 

MVC 구조는 이렇게 어떤 영역이 다른 영역을 관리하거나 소유할수 있고, 값을 변경할 수 있는지에 대한 규칙을 만드는 것입니다.

 

 

2. Controller

어떻게 화면에 표시할 것인지에 대해 관심을 가집니다.

 

-> 주로 model을 여기에서 생성하여, 변수(데이터)를 set 하거나 get합니다.

 

이제 뷰컨에서 버튼을 눌렀을때 api 호출을 하여 생성한 모델에 데이터를 저장하고, 

 

이를 바탕으로 뷰를 그릴 수 있습니다.

 

밑의 예제에서 api를 뷰컨에서 호출하고

 

호출한 데이터를 생성한 모델에 저장하여

 

저장된 데이터를 바탕으로 뷰를 그리는 것입니다.

class myVC: UIViewController {
	
    var carModel = Car()
    @IBOulet titleLable: UILabel!

    func viewDidLoad() {
        callApi()
    }
    
    func callApi() {
    	alamofire.request() { (success, data) in
            if success {
                carModel.wheels = data
              	updateView()
            }
        }
    }
    
    func updateView() {
    	titleLabel.text = carModel.wheels
    }
}

 

 

3. View

UIButton, UIViewController, UILabel와 같은 UI와 관련된 것이고 Controller의 통제를 받게 됩니다.

 

-> 뷰는 일단 간단한 뷰들은 uikit에서 쉽게 제공합니다. 위의 UILabel처럼,

 

하지만 뷰의 구조가 복잡해지면 뷰를 그리는 새로운 클래스를 만들수도 있습니다.

import UIKit

class ViewMaker {
    
    // 파라미터로 받아 이에 맞게 커스터 마이징한 뷰를 생성할 수 있다.
    func makeUILabel(someData: dataForUI) -> UIView {
        //custom한 라벨을 생성할 수 있다. 
        var bodyView = UIView()
        var label = UILabel()
        
        label.title = "타이틀"
        
        bodyView.addSubview(label)
        
        return bodyView
    }


}

위의 예시는 간단하지만 복잡한 뷰를 생성할 수 있다. 

 

뷰의 위치정보, 표시할 데이터들을 받아 생성할 수 있다.


밑의 내용은 위의 사이트에서 가져온것입니다. 제가 풀어 설명한 글과 비교하며 읽어보시기 바랍니다.

 

서로의 관계

 

Model과 Controller

Controller는 모델에 직접적으로 접근할 수 있지만, Model은 Controller에 Notification & KVO 방식을 통해

모델의 변화를 알립니다.

 

Model과 View

Model은 UI에 독립적이며 View와 소통할 수 없으며, View 또한 불가능합니다.

 

View와 Controller

Controller는 View에 대해 outlet을 이용해 View에게 직접적으로 접근할 수 있습니다. =

View는 Controller에게 구조적으로 미리 정해진 방식으로 Controller에게 행위에 대한 요청(delegate)과

데이터에 대한 요청(data source)을 할 수 있습니다. 뿐만 아니라, action(View) - target(controller)의 구조로

사용자의 행위에 따라 필요한 함수를 호출할 수도 있습니다.

 

아래와 같은 MVC 패턴이 여러개 모여 하나의 앱을 만들게 됩니다. 

 

출처. cs193p 강의

 

참고.

https://www.edwith.org/swiftapp/lecture/26620?isDesc=false