본문 바로가기
iOS 프로그래밍 실무

iOS 프로그래밍 실무 4주차

by 노아입니다 2025. 3. 27.

UIKit과 ViewController의 역할, 그리고 Scene 관리 개념 정리

iOS 앱을 개발할 때 UIKit과 ViewController의 역할을 이해하는 것은 필수적입니다. 또한, iOS 13부터 도입된 Scene 관리 개념을 파악하면 다중 윈도우 환경에서도 유연하게 앱을 설계할 수 있습니다. 이번 글에서는 UIKit, ViewController, 그리고 Scene 관리 개념을 정리해보겠습니다.

UIKit이란?

UIKit은 iOS 애플리케이션의 UI를 구성하는 프레임워크로, 버튼, 레이블, 이미지 등 다양한 UI 요소를 만들고 관리하는 기능을 제공합니다.

import UIKit

UIKit을 가져오면 UI 관련 기능을 사용할 수 있습니다.

ViewController의 역할

ViewController는 iOS에서 화면을 관리하는 기본 단위입니다. UIViewController 클래스를 상속받아 새로운 화면을 만들고, 사용자와 상호작용하는 기능을 추가할 수 있습니다.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 초기 설정 및 데이터 로드
    }
}

viewDidLoad()의 역할

  • viewDidLoad()는 화면이 메모리에 로드된 후 한 번 호출됩니다.
  • 주로 초기 설정을 하거나 데이터를 불러오는 역할을 합니다.
  • super.viewDidLoad()를 호출하여 부모 클래스의 초기화 작업을 실행해야 합니다.

Scene 관리 개념

iOS 13부터 SceneDelegate가 도입되면서 앱의 UI를 Scene 단위로 관리할 수 있게 되었습니다. 다중 윈도우 환경에서도 각 Scene을 독립적으로 관리할 수 있습니다.

application(_:configurationForConnecting:options:)

새로운 Scene이 생성될 때 호출되는 메서드입니다.

func application(
    _ application: UIApplication,
    configurationForConnecting connectingSceneSession: UISceneSession,
    options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

매개변수 설명

  • application: 현재 앱의 인스턴스를 나타냅니다.
  • connectingSceneSession: 새로 연결될 Scene의 세션 정보를 담고 있습니다.
  • options: Scene을 연결할 때의 옵션을 포함하는 객체입니다. (예: 특정 URL을 통해 앱이 열렸을 때 해당 URL 정보 포함)

반환 값

  • UISceneConfiguration 객체를 반환하며, 새로운 Scene을 설정하는 데 필요한 정보를 담고 있습니다. 기본적으로 "Default Configuration"을 사용합니다.

configurationForConnecting vs connectingSceneSession

항목 설명
configurationForConnecting 새로운 Scene을 설정하기 위한 구성을 반환하는 메서드
connectingSceneSession 현재 연결하려는 Scene의 세션 정보

Swift 오류 메시지: Missing argument labels

Swift에서는 매개변수 레이블이 요구됩니다. 이를 생략하면 오류가 발생할 수 있습니다.

let point = CGPoint(10, 20) // 오류 발생

올바른 방식:

let point = CGPoint(x: 10, y: 20)

Swift의 #function에 대한 이해

Swift에서는 #function이라는 특별한 매크로를 제공하여 현재 실행 중인 함수의 이름을 문자열로 반환할 수 있습니다. 이 기능은 주로 디버깅이나 로깅 목적으로 매우 유용하게 사용됩니다.

사용 예시

func myFunction() {
    print("현재 실행 중인 함수: \(#function)")
}

myFunction()

Swift UITableView numberOfRowsInSection 완벽 정리

numberOfRowsInSection이란?

numberOfRowsInSectionUITableView에서 특정 섹션(section)에 몇 개의 행(row)이 들어갈지를 결정하는 메서드입니다. 이 메서드는 UITableViewDataSource 프로토콜의 필수 구현 항목으로, 테이블 뷰가 올바르게 작동하려면 반드시 구현해야 합니다.

기본 문법

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 데이터배열.count
}

사용 예제

1️⃣ 기본적인 배열을 이용한 구현

class MyTableViewController: UITableViewController {
    let items = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count // 배열의 개수만큼 행을 생성
    }
}

items.count == 5 이므로, 테이블 뷰에 5개의 행이 표시됩니다.

2️⃣ 여러 개의 섹션이 있는 경우

class MyTableViewController: UITableViewController {
    let sections = [
        ["Apple", "Banana", "Cherry"],
        ["Dog", "Elephant", "Fox", "Giraffe"]
    ]

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].count // 각 섹션별 데이터 개수 반환
    }
}

✅ 첫 번째 섹션은 3개, 두 번째 섹션은 4개의 행을 가집니다.

🔥 정리

✔️ numberOfRowsInSection은 테이블 뷰의 각 섹션에 포함될 행(row)의 개수를 반환하는 필수 메서드입니다.
✔️ 보통 배열의 개수를 반환하는 경우가 많습니다.
✔️ 섹션이 여러 개라면 section 인덱스를 활용해 다르게 설정할 수도 있습니다.

테이블 뷰 구현 시 필수적인 부분이니 꼭 기억해 두세요! 😊


1. 상속(Inheritance)과 프로토콜(Protocol)이란?

상속(Inheritance)이란?

  • 부모 클래스의 속성과 메서드를 자식 클래스에서 재사용하는 개념입니다.
  • 코드 중복을 줄이고, 유지보수를 쉽게 만들 수 있습니다.
  • class에서만 사용 가능하며, structenum에서는 지원되지 않습니다.

프로토콜(Protocol)이란?

  • 특정 기능을 정의만 해두고, 실제 구현은 각 타입에서 하도록 강제하는 개념입니다.
  • class, struct, enum 모두에서 채택할 수 있습니다.
  • 다중 채택이 가능하여, 유연한 코드 설계가 가능합니다.

2. 상속과 프로토콜을 활용한 예제 (🐶 개와 🐱 고양이)

📌 상황

  • 모든 동물은 이름을 가지며, speak() 메서드를 사용할 수 있습니다.
  • 일부 동물(예: 개, 고양이)은 달릴 수 있는 능력을 가집니다.
  • Animal 클래스를 만들고, DogCat이 이를 상속받도록 합니다.
  • Runnable 프로토콜을 만들어 run() 메서드를 강제합니다.

코드 구현

// ✅ 1. 프로토콜 정의
protocol Runnable {
    func run()
}

// ✅ 2. 부모 클래스: Animal (모든 동물의 기본 속성)
class Animal {
    var name: String
    init(name: String) { self.name = name }
    func speak() { print("\(name)이(가) 소리를 낸다!") }
}

// ✅ 3. 개(Dog) 클래스 (Animal 상속 + Runnable 구현)
class Dog: Animal, Runnable {
    func run() { print("\(name)이(가) 달린다! 🐕💨") }
}

// ✅ 4. 고양이(Cat) 클래스 (Animal 상속 + Runnable 구현)
class Cat: Animal, Runnable {
    func run() { print("\(name)이(가) 살금살금 달린다! 🐈💨") }
}

// ✅ 5. 여러 객체를 저장하는 배열 (다형성 활용)
let animals: [Runnable] = [Dog(name: "멍멍이"), Cat(name: "야옹이")]

for animal in animals {
    animal.run()
}

💡 실행 결과

멍멍이이(가) 달린다! 🐕💨
야옹이이(가) 살금살금 달린다! 🐈💨

3. 핵심 정리 ✨

개념 설명
상속(Inheritance) DogCatAnimal의 기능을 물려받음.
프로토콜(Protocol) DogCatRunnable을 구현하여 run() 메서드 제공.
다형성(Polymorphism) animals 배열에 DogCat을 넣고 같은 방식(run())으로 호출 가능.

상속은 코드 재사용성을 높여주고, 프로토콜은 유연성을 제공한다! 🚀


4. 마무리 🎯

Swift에서 상속을 사용하면 기존 클래스를 확장하여 새로운 클래스를 쉽게 만들 수 있고, 프로토콜을 사용하면 공통 기능을 정의하여 다양한 객체에서 활용할 수 있습니다. 특히, 프로토콜을 활용하면 다중 채택이 가능해 더욱 유연한 설계가 가능합니다.

👉 상속과 프로토콜을 적절히 활용하여 유지보수하기 좋은 코드를 작성해보세요! 😊

📌 추가 팁

  • iOS 개발을 처음 접하는 분이라면, Apple 공식 문서를 참고해보세요! Apple Developer Documentation
  • SceneDelegate는 iPadOS에서도 중요한 역할을 합니다. 여러 개의 윈도우를 동시에 띄울 수 있는 앱을 개발하고 싶다면 반드시 익혀두세요!