iOS ๊ฐ๋ฐ์์๋ ์ฌ๋ฌ ๊ฐ์ง ๋์์ธ ํจํด์ ์ฌ์ฉํ์ฌ ์ฑ์ ๊ด๋ฆฌํ๊ณ ๊ตฌ์กฐํํ๋ค.
๊ทธ ์ค ๊ฐ์ฅ ์ผ๋ฐ์ ์ด๋ฉฐ ๋ํ์ ์ผ๋ก ์ฌ์ฉ๋๋ MVC ํจํด์ ๋ํด ์์๋ณด๋ ค๊ณ ํ๋ค.
MVC (Model - View - Controller)
MVC๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ด๊ณ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋์์ธ ํจํด์ด๋ค. ์ฑ์ ๊ตฌ์ฑ์ ์ธ ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ก ๋๋์ด ์ค๊ณํ๋ค.
Model : ์ฑ์ ๋ฐ์ดํฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ค.
View : ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ํ์ํ๊ณ ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ค.
Controller : ๋ชจ๋ธ๊ณผ ๋ทฐ์ ์ฌ์ด๋ฅผ ์ค์ฌํด์ค๋ค. ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ค.
Model
์ฃผ๋ก struct์ class๋ฅผ ๋ง๋ ๋ค. ์ฑ์ด ๊ฐ์ง๋ ๋ฐ์ดํฐ๋ค์ ๋ด๋นํ๋ค.
์๋ฅผ ๋ค์ด, ์ ํ๋ฒํธ๋ถ์ด๋ฉด ์ด๋ฆ, ์ ํ๋ฒํธ, ์์ ๋ฑ์ ์ ์ฅํ๊ณ ์ด๋ฅผ model์์ ์ ์ํ๊ฒ ๋๋ค.
Todo List๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋ ์์๋ฅผ ๋ค์ด๋ณด๊ฒ ๋ค.
// ToDo List๋ฅผ ๋ํ๋ด๋ Model
struct TodoItem {
var title: String
var isCompleted: Bool
}
View
์ฃผ๋ก UIKit์ ์์ํ๋ค. UIButton, UIViewController, UILabel์ ๊ฐ์ ๊ฒ์ด๊ณ Controller์ ํต์ ๋ฅผ ๋ฐ๊ฒ ๋๋ค.
ํ๋ฉด์ ๊ตฌ์ํ๋ ์ญํ ์ ํ๋ค.
์ฝ์ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋ ์์๋ฅผ ๋ค์ด๋ณด๊ฒ ๋ค.
// ์ฝ์ ๊ธฐ๋ฐ์ View
class ConsoleView {
func displayTodos(_ todos: [TodoItem]) {
for (index, todo) in todos.enumerated() {
print("\(index + 1). [\(todo.isCompleted ? "โ
" : " ")] \(todo.title)")
}
}
func askForNewTodoTitle() -> String? {
print("Enter a new todo title: ", terminator: "")
return readLine()
}
func askForTodoIndexToDelete() -> Int? {
print("Enter the index of the todo to delete: ", terminator: "")
if let input = readLine(), let index = Int(input) {
return index
}
return nil
}
}
displayTodos(_:) ๋ฉ์๋๋ ToDo ํญ๋ชฉ๋ค์ ์ถ๋ ฅํ์ฌ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค๋ค.
askForNewTodoTitle() ๋ฉ์๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์๋ก์ด ToDo ํญ๋ชฉ์ ์ ๋ชฉ์ ์ ๋ ฅ ๋ฐ๋๋ค.
askForTodoIndexToDelete() ๋ฉ์๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์ญ์ ํ ToDo ํญ๋ชฉ์ ์ธ๋ฑ์ค๋ฅผ ์ ๋ ฅ ๋ฐ๋๋ค.
Controller
Model๊ณผ View ๋ ์ฌ์ด๋ฅผ ๊ด๋ฆฌํ๋ค.
Model์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด์ view์ ๋ณด์ฌ์ฃผ๊ธฐ๋ ํ๋ฉฐ, ๋ฐ์ดํฐ๊ฐ ๋ณํ๋ฉด ์ด๋ฅผ view์ ๋ค์ ์ ์ฉํ๊ธฐ๋ ํ๋ค.
view์์ ์ด๋ ํ ์ผ์ด ๋ฐ์ํ๋ฉด ์ด๋ฅผ model์๊ฒ ์ ๋ฌํด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฟ ์๋ ์๋ค.
// Controller
class TodoListController {
private var todos: [TodoItem] = []
private let consoleView = ConsoleView()
func start() {
print("To-Do List App")
while true {
consoleView.displayTodos(todos)
print()
print("1. Add Todo 2. Delete Todo 3. Quit")
if let choice = readLine() {
switch choice {
case "1":
addTodo()
case "2":
deleteTodo()
case "3":
exit(0)
default:
print("Invalid choice. Please try again.")
}
}
print()
}
}
private func addTodo() {
if let title = consoleView.askForNewTodoTitle() {
let newTodo = TodoItem(title: title, isCompleted: false)
todos.append(newTodo)
}
}
private func deleteTodo() {
if let index = consoleView.askForTodoIndexToDelete() {
if index >= 0 && index < todos.count {
todos.remove(at: index)
} else {
print("Invalid index. Please try again.")
}
}
}
}
start() ๋ฉ์๋๋ ์ฑ์ ์์ํ๊ณ , ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ฉฐ, View๋ฅผ ์ ๋ฐ์ดํธํ๋ ์ฃผ์ ๋ก์ง์ ๋ด๊ณ ์๋ค.
addTodo() ๋ฉ์๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์๋ก์ด ToDo ํญ๋ชฉ์ ์ถ๊ฐํ๋ ๋ก์ง์ ์ฒ๋ฆฌํ๋ค.
deleteTodo() ๋ฉ์๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์ญ์ ํ ToDo ํญ๋ชฉ์ ์ธ๋ฑ์ค๋ฅผ ์ ๋ ฅ ๋ฐ๊ณ , ํด๋น ํญ๋ชฉ์ ์ญ์ ํ๋ ๋ก์ง์ ์ฒ๋ฆฌํ๋ค.
๊ฐ๋จ ์ ๋ฆฌ
Model์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ณ๊ฒฝ์ ์ถ์ ํ๋ฉฐ ๋ฐ์ดํฐ์ ๊ด๋ จ๋ ๋ก์ง์ ์ํํ๋ค. View์ Controller์ ์ง์ ์ ์ผ๋ก ์ํธ์์ฉํ์ง ์๋๋ค.
View๋ ํ๋ฉด์ ํ์ํ๋ฉฐ model์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๊ณ Controller์๊ฒ ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ ๋ฌํ๋ค. ์ง์ ์ ์ผ๋ก Model์ ๋ํ ์ ๋ณด๋ ๋ฐ์ง ๋ชปํ๋ฉฐ Controller๋ฅผ ํตํด ๋ฐ๋๋ค.
Controller๋ Model๊ณผ View ์ฌ์ด์์ ์ค๊ฐ์ ์ญํ ์ ํ๊ณ ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ค. ์ฌ์ฉ์์ ์ก์ ์ ๋ฐ์ํ์ฌ View์ Model์ ์ ๋ฐ์ดํธํ๋ค.
MVC ํจํด์ ๊ฐ ๊ตฌ์ฑ ์์ ๊ฐ์ ๊ฐ๋ ฅํ ๊ฒฐํฉ์ ํผํ๊ณ , ์ฑ์ ๋ ์ฝ๊ฒ ๊ด๋ฆฌํ๊ณ ํ์ฅํ ์ ์๊ฒ ํด์ค๋ค. ๋ํ, ๊ฐ ๊ตฌ์ฑ ์์๊ฐ ๋ถ๋ฆฌ๋์ด ์๊ธฐ ๋๋ฌธ์, ํ ๊ตฌ์ฑ ์์๋ฅผ ์์ ํ๋๋ผ๋ ๋ค๋ฅธ ๊ตฌ์ฑ ์์์ ์ํฅ์ ์ฃผ์ง ์๋๋ค. ์ด๋ก ์ธํด ์ ์ง ๋ณด์๊ฐ ์ฉ์ดํ๋ค.
'๐ฑ Mobile > iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS - Swift] extension(ํ์ฅ) ์ ๋ํด (0) | 2023.07.31 |
---|---|
iOS - Delegate Pattern (๋ธ๋ฆฌ๊ฒ์ดํธ ํจํด) (0) | 2023.07.28 |
iOS - 2023๋ ์ต์ iOS ๊ฐ๋ฐ ๋ํฅ๊ณผ ์ ๋ฐ์ดํธ (feat. WWDC 2023) (0) | 2023.07.24 |
iOS - UIKit vs SwiftUI ์ ๋ํด์ (2) (0) | 2023.07.18 |
iOS - UIKit vs SwiftUI ์ ๋ํด์ (1) (0) | 2023.07.16 |