MVC 패턴의 개요

Model - View - Controller 구조로 이루어진 디자인 패턴을 의미한다.

 

Model : 앱의 데이터 또는 비즈니스 로직을 소유 ( 데이터의 변수 및 상수 , 데이터 값의 계산 등을 수행 )

View : 사용자에게 데이터 또는 UI 를 보여주는 역할을 수행 ( Storyboard 가 View 에 포함 )

Controller : Model  View 의 중간에서 View로부터 사용자의 이벤트를 감지하고, 해당 이벤트 처리를 Model에게 지시하며, Model의 계산된 데이터를 받아 View에게 전달하는 역할을 수행 ( TableViewController , ViewController, 등등.. )

 

Model - View - Controller 는 각각 어떻게 소통을 하나?

음식점을 예로 들어보자

1. 손님은 음식을 주문하기 위해 음식점의 홀에 있는 종업원에게 음식을 주문한다.
2. 음식 주문을 받은 종업원은 주방장에게 주문 내역을 보여준다.
3. 주방장은 주문내역을 보며 음식을 조리하여 조리가 완료되면 종업원을 다시 부른다.
4. 종업원은 해당 음식을 손님에게 제공한다.
5. 만약, 음식의 맛이 이상하거나 추가적인 조리를 원한다면 손님은 종업원을 호출한다.
6. 종업원은 손님의 요구사항을 적어 주방장에게 전달한다.
7. 주방장은 손님의 요구사항대로 음식을 재 조리하여 종업원을 부른다.
8. 종업원은 손님에게 재 조리된 음식을 제공한다.

자! 이제 종업원을 Controller로, 손님을 View로, 주방장을 Model 로 생각해보자

손님(View)은 요구사항을 전달하기 위해 종업원(Controller)에게 요구사항을 알려준다.

종업원(Controller)는 해당 요구사항을 주방장(Model)에게 전달한다.

주방장(Model)은 요구사항대로 조리가 되면 종업원(Controller)에게 음식을 전달한다.

종업원(Controller)주방장(Model)로부터 받은 음식을 손님(View)에게 전달한다.

즉, View  Model 은 직접적으로 소통할수 없고, Controller를 통해서만 소통을 할수 있다.

 

아주 간단한 MVC 패턴 적용 예시

TableView 를 사용해 이름들을 나열하는 화면을 그려보자!

 

일단 나 같은 경우, 공부를 해가는 과정이지만 Udemy - 안젤라유님의 강의를 듣고 최대한 습관화 하려고 노력하고있다.

이렇게 Model - View - Controller 를 구분하여 그룹으로 묶어두면 MVC패턴에 익숙해지는데 도움이 될거같아서...


Model

Name 구조체 먼저 선언해주고


View

View는 Storyboard 파일도 포함되지만, 이렇게 일부 Cell을 떼어내어 View로 구성할수 도 있다!


Controller

해당 부분을 보면 알겠지만, Model에 선언된 구조체를 Controller가 그 내용을 담고있으며,
View의 변화 ( TableView의 DataSource ) 에 따라 해당 값을 Controller가 전달한다.

 

이를 실행해보면

이와 같이 TableView 로 각 이름 값 들을 표시하는걸 볼 수 있다!

물론 해당 예시가 완벽한 MVC 패턴을 그리고 있진 않지만 대략적으로 이렇게 사용된다고 이해하면 될 것 같다!

 

 

MVC 패턴의 장점

  • 다른 패턴들에 비해 비교적 적은 코드량을 갖고있다
  • Apple 에서 SwiftUI가 나오기 전, 기본적으로 채택하고 있던 패턴요소이다! ( 하지만,, 현재는 MVVM 패턴을 강조하고 있다... MVVM 패턴은 아직까진 숙지가 되지 않아 이해하게 되면 블로그에 올릴 생각! )

 

MVC 패턴의 단점

  • 모든 일을 Controller가 맡아서 하고있다, 즉 Cotroller가 너무 많은 업무를 담당하게 된다
  • Controller의 코드가 너무 길어질 수 밖에 없는 구조! → Controller의 내부 구조가 복잡해지기 쉽다
  • 프로젝트의 규모가 커질수록 유지보수 하기에 어려움이 있다! ( 사실 아직까지 큰 프로젝트를 한적이 없어서 이 말이 잘 이해가 가지 않는다... 나중에 하게 된다면 몸소 느껴봐야겠다! )

iOS의 ViewControlle의 생명주기는 개발함에 있어 굉장히 중요하다.

해당 View에 컨텐츠가 언제 나타나야 하는지, 컨텐츠의 내용은 무엇인지, 해당 컨텐츠의 내용이 뷰가 사라지면 어떻게 되야하는지 등등 개발함에 있어 반드시 알아야 하는 중요한 사항들이있다.

ViewController의 생명주기에 대해 알아보자!

1. ViewDidLoad()

공식문서에 의하면 뷰 컨트롤러가 메모리에 로드된후 호출되는 메소드이다.

다시말해 뷰가 메모리에 로딩이 완료되면 시스템에 의해 자동으로 호출되는 메소드로, 화면이 처음 생성될때 딱 한번 실행된다.

2. ViewWillAppear()

공식문서에 의하면 뷰가 뷰 계층에 추가될 것임을 뷰 컨트롤러 알려주는 메소드이다.

다시말해 뷰가 화면에 나타나기 직전! 해당 메서드가 호출된다!

그럼, ViewDidLoad 도 화면에 나타나기전, 수행되는데 이 둘의 차이는 무엇일까?

직접 구현해보면 차이를 파악알수 있다.

처음 View를 표시할때 ViewDidLoad() 가 호출되고, 그다음에 ViewWillApear() 가 호출된다,

그리고 다른 뷰로 넘어갈때, 마찬가지로 둘다 호출이 되지만 다시 이전화면으로 돌아갈때

ViewWillAppear() 메소드만 호출됨을 알수있다.

즉, ViewDidLoad() 는 메모리가 해제되기 전까지는 무조건 1번만 호출되며, ViewWillAppear() 메소드는 메모리와 관계없이 해당 뷰를 표시할때 무조건 호출되는 차이가 있다!

3. ViewDidAppear()

공식문서에 의하면 뷰가 뷰 계층에 추가되었음을 뷰 컨트롤러에 알려주는 메소드이다.

다시 말해 ViewWillAppear() 는 뷰가 표시되기 직전 호출되는 메소드라면,

ViewDidAppear() 는 뷰가 표시된 직후!!! 호출되는 메소드이다!

4. ViewWillDisappear()

공식문서에 의하면 뷰가 뷰 계층에서 제거될 것임을 뷰 컨트롤러에 알려주는 메소드이다.

다시말해 뷰가 사라지기 직전 호출되는 메소드 이다!

5. ViewDidDisappear()

공식문서에 의하면 뷰가 뷰 계층에서 제거되었음을 뷰 컨트롤러에 알려주는 메소드이다.

마찬가지로 ViewWillDisappear() 가 사라지기 직전 호출되는 메소드라면, ViewDidDisappear()는 사라진 직후 호출되는 메소드이다.

이와 같이 ViewController의 생명주기는 메소드의 이름만으로도 충분히 어떤일을 수행하는 메소드인지 짐작할수 있다!

이를 직접 구현하여 실제로 어떤 순서로 호출되는지 파악해 보자!

확실히 호출되는 순서를 보면 더욱더 이해하기 쉽다!

이 생명주기를 잘 기억하여 

View 에 표시되는 데이터나 저장해야하는 시점 등등을 적절한 메소드에 적절하게 사용하면 된다!

아주 기본적이면서 아주 중요한 내용이다!

저번 글에서는 xcode 에서 프로젝트를 생성하는 법을 알아보았다!

프로젝트 생성후 각종 설정을 해야하는데 중요한 부분을 위주로 포스팅 해야겠다!

 

/*

프로젝트 생성 방법에 대한 포스팅은

ai-hong.tistory.com/70

 

1. Xcode 프로젝트 생성

xcode 를 실행하고, 프로젝트를 만드는 방법까지 설명한다. xcode를 실행하면 위의 이미지를 볼수 있을것이다! ( 본인의 버전은 xcode 12.3 버전 ! ) 버전에 따라 다소 다를수도 있지만 가능하면 최신으

ai-hong.tistory.com

*/

 

 

먼저 왼쪽창에서 제일 위에 있는 프로젝트 명을 클릭하면 각종 설정 화면이 뜰것이다!

 

 

그중 제일 위에 위치해있는  Identity 를 살펴보자!

Display Name APP 의 이름을 작성하는곳! 앱의 이름이 설정과 같이 표시된다
Bundle Identifier 앱 스토어가 앱을 식별하는 고유 코드
Version 앱의 버전을 의미
Build 릴리즈 를 의미

 

다음을 Deployment Info 를 보자!

제일 위 칸의 iOS 버전은 해당 앱이 구동될 기기의 최하 IOS 버전을 의미한다!

사진과 같이 13.0 이라면 최소 IOS 13.0 버전 이상에서만 해당 앱을 실행할수 있다!

iPhone 과 iPad 지원을 선택할수도 있다!

 

Main Interface 는 앱이 처음 실행될때 기본 인터페이스 파일을 무엇으로 할 것인지 설정하는 항목!

우리는 기초를 배우는 것이기 때문에 Main.storyboard 를 사용하기 위해 Main 그대로 둔다!

 

Device Orientation 은 모바일 기기의 가로,세로 회전 여부를 결정하는 항목이다! 각각의 내용은 다음과 같다

Portrait 디바이스의 기본 방향
Upside Down 상 하 반전! ( 디바이스 기본 방향의 180도 회전 )
Landscape Left 디바이스를 왼쪽으로 90도 회전
Landscape Right 디바이스를 오른쪽으로 90도 회전

 

다음으로 App Icons and Launch Images 탭을 살펴보자

해당 탭에서 Launch Screen File 은 앱이 수행된후 처음 보여질 화면을 의미한다

즉, 실제 앱이 수행된후 기능을 수행하기 전에 잠깐 보여질 화면을 구성하는것이다..

가령.. 카카오톡을 실행할때 잠깐동안 나오는 이미지 같은것들이다

이러한 것을 Splach(스플래시) 라고 부른다!

 

이에대한 설정은 추후 공부하면서 구성해 봐야지!

 

다음은 Frameworks, Libraries, and Embedded Content 탭이다!

지금 당장은 기초를 공부하는 것이기 때문에 해당탭에서 설정할것은 없지만

추후 앱을 개발하다 보면 반드시 외부 라이브러리 나 프레임워크를 사용하게 될것이다

그러한 경우 이곳에서 추가시켜주면 된다!

 

이제부터 정말 간단한 앱을 구현해보자!

xcode 를 실행하고, 프로젝트를 만드는 방법까지 설명한다.

xcode 실행시 화면

xcode를 실행하면 위의 이미지를 볼수 있을것이다! ( 본인의 버전은 xcode 12.3 버전 ! )

버전에 따라 다소 다를수도 있지만 가능하면 최신으로 update 를 하는게 좋음!

 

새로운 프로젝트를 생성하기 위해서는 create a new Xcode project 를 클릭한다!

 

그럼 위와 같은 창이 뜨게 되는데 우리의 목적은 APP 개발이기 때문에 App 탭을 클릭한 후 next 클릭!

( 이 창에서 macOS, iOS, watchOS, tvOS 등 다양한 OS 개발에 맞게 설정할수 있다, 추후 나도 watch용 OS 개발을 해봐야지 )

 

 

그럼 위와 같은 창이 뜨게 되는데 

그 안의 기능은 다음과 같다!

내용 설명 내가 한것
Product Name 프로젝트의 이름을 기입 Hello World
Team 개발자 팀의 계정 아직 개발자 계정이 없기때문에 Apple 계정을 입력했다 ( 이런 경우 Personal Team 이라고 표시됨! )
Organization Identifier 소속된 조직명 소속된 조직이 없기때문에 이름 이니셜로 기입
Bundle Identifier 앱의 고유 식별코드 ( 임의 수정 불가 ) Organization Identifier + Product Name 으로 자동으로 기입된다 ( 수정불가 )
Interface Storuboard 와 SwiftUI 선택 본인은 StoryBoard로 개발할것이기에 스토리보드 선택
Language Swift 와 Objective-C 선택 Swift 로 개발!
Use Core Data 앱 내에서 데이터 저장을 위한 객체인 코어데이터의 사용 여부 사용하지 않음!
Include Tests APP 에 대한 테스트를 진행하고 결과를 검사해볼수 있는 기능을 제공한다! ( XCTestCase를 상속받을 클래스가 추가됨 ) 사용하지 않음!

 

이후 Next 를 클릭하면

어디에 저장할 것인지 디렉터리를 선택할수 있는 창이 나온다 원하는 위치에 저장하고 Create 를 클릭!

프로젝트가 생성되었다!

 

자세한 내용은 다음에 설명한다!

1) 구조체 선언

struct BasicInformation {
    let name: String
    var age: Int
}

Swift 에서 변수와 상수의 선언은 let 과 var 로 구성한다.

var 는 나중에 바뀔수도 있는 값!

let 은 나중에 바꿀수 없는 값!

 

예를들어..

let a: Int = 5
var b: Int = 5

a = 6		// 상수(let)기 때문에 오류가 발생한다

b = 6		// 변수(var) 이기 때문에 b 의 값은 6이 된다!

위와 같이 된다

 

앞서 선언한 BasicInformation 구조체를 사용해보자!

var hongInfo: BasicInformation = BasicInformation(name: "hong", age: 27)

// print 는 단순 데이터의 값만 출력!
print(hongInfo)
/*
BasicInformation(name: "hong", age: 27)
*/

// dump 는 데이터의 자세한 정보까지 출력해준다!
dump(hongInfo)
/*
▿ BasicInformation
  - name: "hong"
  - age: 27
*/

 

2) Class (클래스) 선언

class Person {
    var height: Float = 0.0 // 키 의 정보
    var weight: Float = 0.0 // 몸무게 의 정보
}

Person 이라는 클래스는 키 와 몸무게의 정보를 가지고 있다

 

Person 클래스를 사용해보자

let hong: Person = Person()
hong.height = 175.1
hong.weight = 95.3

print("hong : \(hong)")
/*
hong : Person
*/

dump(hong)
/*
▿ Person #0
  - height: 175.1
  - weight: 95.3
*/

 

기본적인 Swift 의 방향만 파악했다.

앞으로 공부하면서 더욱 자세히 알아보자!

+ Recent posts