스위프트로 SwiftUI 방식, 아이폰 앱 개발, 뷰 컨트롤러 기반 프로그램 만들기

최근 몇 년 동안 애플의 SwiftUI는 아이폰 앱 개발의 패러다임을 변화시켰습니다. SwiftUI는 선언형 프로그래밍 방식으로, UI를 구성하는 방식이 이전의 UIKit의 imperative 방식과는 다릅니다. 이 글에서는 SwiftUI의 활용 방법과 뷰 컨트롤러 기반의 앱 개발 방법을 비교하며, 실제 앱을 만드는 경험을 공유하고자 합니다.

1. SwiftUI란?

SwiftUI는 2019년 WWDC에서 처음 발표된 최신 UI 프레임워크입니다. 이 프레임워크는 다음과 같은 특징을 가지고 있습니다:

  • 선언형 프로그래밍: UI를 선언적으로 작성하여 코드가 더 간단하고 직관적입니다.
  • 상태 관리: 데이터와 UI 간의 관계를 쉽게 관리할 수 있도록 도와줍니다.
  • 크로스 플랫폼: iOS, macOS, watchOS, tvOS에서 사용할 수 있습니다.

2. UIKit과 SwiftUI의 차이점

기존에는 UIKit 프레임워크를 통해 뷰 컨트롤러 기반으로 앱을 개발했습니다. UIKit은 다음과 같은 방식으로 앱을 구성합니다:


class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let label = UILabel()
        label.text = "Hello, UIKit!"
        label.frame = CGRect(x: 100, y: 100, width: 200, height: 50)
        view.addSubview(label)
    }
}

반면에 SwiftUI에서는 UI를 구성하는 방식이 매우 다릅니다. SwiftUI는 다음과 같이 간단합니다:


struct ContentView: View {
    var body: some View {
        Text("Hello, SwiftUI!")
            .padding()
    }
}

3. SwiftUI를 사용한 간단한 앱 만들기

이제 SwiftUI를 사용하여 간단한 앱을 만들어보겠습니다. 이 앱은 사용자가 버튼을 클릭할 때마다 카운트가 증가하는 기능을 가집니다.

3.1 프로젝트 설정

Xcode를 실행하고 새로운 SwiftUI 프로젝트를 생성합니다. 이때 ‘App’ 템플릿을 선택합니다.

3.2 메인 뷰 작성

ContentView.swift 파일을 열고 다음 코드를 입력합니다:


import SwiftUI

struct ContentView: View {
    @State private var count = 0
    
    var body: some View {
        VStack {
            Text("Button tapped \(count) times")
                .padding()
            Button(action: {
                count += 1
            }) {
                Text("Tap me!")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

이 코드에서는 상태 변수 `count`를 정의하고, 버튼이 눌릴 때마다 카운트를 증가시키는 기능을 구현했습니다.

4. UIKit을 사용한 앱 만들기

이제 UIKit을 사용하여 비슷한 기능의 앱을 만들어보겠습니다.

4.1 프로젝트 설정

Xcode를 열고 새로운 ‘Single View App’ 프로젝트를 생성합니다.

4.2 메인 뷰 작성

ViewController.swift 파일을 열고 다음과 같은 코드를 입력합니다:


import UIKit

class ViewController: UIViewController {
    private var count = 0
    private let countLabel = UILabel()
    private let tapButton = UIButton(type: .system)

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        countLabel.text = "Button tapped \(count) times"
        countLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(countLabel)
        
        tapButton.setTitle("Tap me!", for: .normal)
        tapButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        tapButton.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(tapButton)
        
        // Autolayout constraints
        NSLayoutConstraint.activate([
            countLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            countLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            tapButton.topAnchor.constraint(equalTo: countLabel.bottomAnchor, constant: 20),
            tapButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])
    }

    @objc private func buttonTapped() {
        count += 1
        countLabel.text = "Button tapped \(count) times"
    }
}

UIKit에서의 개발은 SwiftUI에 비해 좀 더 boilerplate code(단순한 코드)가 필요하지만, 복잡한 UI를 구성할 때에는 더 많은 제어권을 제공합니다.

5. 뷰 컨트롤러와 SwiftUI의 통합

SwiftUI는 기존의 UIKit와 완벽하게 통합될 수 있습니다. 즉, UIKit에서 만든 앱에 SwiftUI 뷰를 추가하고, SwiftUI 앱에서 UIKit 뷰를 사용할 수 있습니다.


import SwiftUI

struct UIKitView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> ViewController {
        return ViewController()
    }
    
    func updateUIViewController(_ uiViewController: ViewController, context: Context) {}
}

struct ContentView: View {
    var body: some View {
        UIKitView()
    }
}

6. SwiftUI의 장점과 단점

6.1 장점

  • 코드가 간결하고 읽기 쉬움
  • UI와 데이터 상태의 관계를 직접 관리 가능
  • 함께 사용할 수 있는 다양한 뷰 컴포넌트 제공

6.2 단점

  • SwiftUI의 일부 기능은 아직 안정적이지 않음
  • UIKit보다 낮은 성능을 보일 수 있음
  • 구버전 iOS에서의 호환성이 없음

7. 결론

SwiftUI는 애플의 최신 UI 프레임워크로, 기존 UIKit보다 훨씬 더 직관적이고 간단한 UI 개발을 가능하게 합니다. 하지만 UIKit도 여전히 견고하고 많은 개발자에게 익숙한 프레임워크이므로, 두 프레임워크를 적절하게 혼합하여 사용하는 것이 중요합니다. 각 프레임워크의 특성을 잘 이해하면, 더 나은 품질의 앱을 개발할 수 있을 것입니다.