💻 프로그래밍

Swift

Swift

Apple이 개발한 iOS/macOS 개발 언어. 안전성과 성능에 중점.

📖 상세 설명

Swift는 Apple이 2014년 WWDC에서 발표한 범용 프로그래밍 언어로, iOS, macOS, watchOS, tvOS 애플리케이션 개발을 위해 설계되었습니다. 현대적이고 안전한 언어 설계 철학을 바탕으로, 개발자가 더 빠르고 안정적인 코드를 작성할 수 있도록 지원합니다.

Swift는 기존 Apple 생태계의 주력 언어였던 Objective-C를 대체하기 위해 개발되었습니다. Objective-C의 30년 역사와 C 언어 호환성에서 오는 복잡성을 해소하고, LLVM 컴파일러 최적화를 통해 Objective-C보다 최대 2.6배 빠른 성능을 제공합니다. 2015년 오픈소스화되어 Linux, Windows에서도 사용 가능합니다.

Swift의 핵심 특징은 안전성(Safety), 성능(Performance), 표현력(Expressiveness)입니다. Optional 타입으로 nil 참조 에러를 컴파일 타임에 방지하고, ARC(Automatic Reference Counting)로 메모리를 자동 관리합니다. 또한 프로토콜 지향 프로그래밍(Protocol-Oriented Programming)을 통해 상속보다 유연한 코드 재사용을 권장합니다.

실무에서 Swift는 iOS/macOS 앱 개발의 표준 언어이며, SwiftUI와 결합하여 선언적 UI 개발을 지원합니다. 최근에는 Vapor, Kitura 등 프레임워크를 통한 서버사이드 개발, Swift for TensorFlow를 통한 머신러닝 분야로도 영역을 확장하고 있습니다.

💻 코드 예제

// Swift 기본 문법 예제

// 1. 변수와 상수
var mutableVariable = "변경 가능"  // var: 변수
let immutableConstant = "변경 불가"  // let: 상수 (권장)

// 2. 타입 추론과 명시적 타입
let inferredInt = 42  // 타입 추론: Int
let explicitDouble: Double = 3.14  // 명시적 타입 선언

// 3. 문자열 보간
let name = "Swift"
let version = 5.9
print("Hello, \(name) \(version)!")  // "Hello, Swift 5.9!"

// 4. 컬렉션
let fruits = ["Apple", "Banana", "Cherry"]  // 배열
let scores = ["Alice": 95, "Bob": 87]  // 딕셔너리

// 5. 조건문과 반복문
for fruit in fruits {
    print(fruit)
}

if let score = scores["Alice"] {
    print("Alice's score: \(score)")
}

// 6. 함수
func greet(person name: String, from city: String = "Seoul") -> String {
    return "Hello \(name) from \(city)!"
}

let greeting = greet(person: "Kim", from: "Busan")  // 외부 파라미터명 사용

// 7. 클로저
let numbers = [3, 1, 4, 1, 5, 9]
let sorted = numbers.sorted { $0 < $1 }  // 축약 문법
let doubled = numbers.map { $0 * 2 }
// Swift Optional - nil 안전성의 핵심

// Optional 선언: 값이 있을 수도, nil일 수도 있음
var nickname: String? = nil
var age: Int? = 25

// 1. Optional Binding (if let) - 가장 안전한 방법
if let unwrappedAge = age {
    print("나이: \(unwrappedAge)살")  // 안전하게 언래핑
} else {
    print("나이 정보 없음")
}

// 2. Guard let - 조기 반환 패턴 (함수 내에서 권장)
func processUser(name: String?) {
    guard let validName = name else {
        print("이름이 필요합니다")
        return  // 조기 반환
    }
    // 여기서 validName은 non-optional
    print("처리 중: \(validName)")
}

// 3. Nil Coalescing Operator (??) - 기본값 제공
let displayName = nickname ?? "Guest"  // nil이면 "Guest"

// 4. Optional Chaining - 연쇄적 접근
struct User {
    var address: Address?
}
struct Address {
    var city: String?
}

let user: User? = User(address: Address(city: "Seoul"))
let city = user?.address?.city  // 중간에 nil이면 전체가 nil

// 5. 강제 언래핑 (!) - 위험! 피해야 함
// let forcedAge = age!  // age가 nil이면 크래시!

// 6. Implicitly Unwrapped Optional - IBOutlet 등에서 사용
var button: UIButton!  // 초기화 후에는 항상 값이 있다고 가정

// 7. Optional Map/FlatMap
let stringNumber: String? = "42"
let parsedNumber = stringNumber.flatMap { Int($0) }  // Int?
// Swift Protocol - 프로토콜 지향 프로그래밍

// 1. 프로토콜 정의
protocol Drawable {
    var color: String { get set }
    func draw()
}

protocol Resizable {
    func resize(scale: Double)
}

// 2. 프로토콜 채택 (클래스, 구조체, 열거형 모두 가능)
struct Circle: Drawable, Resizable {
    var color: String
    var radius: Double

    func draw() {
        print("\(color) 원을 그립니다 (반지름: \(radius))")
    }

    func resize(scale: Double) {
        // 구조체는 mutating 키워드 필요 없이 새 인스턴스 반환
    }
}

// 3. 프로토콜 확장 - 기본 구현 제공
extension Drawable {
    func printDescription() {
        print("색상: \(color)")
    }
}

// 4. 프로토콜 상속
protocol Shape: Drawable, Resizable {
    var area: Double { get }
}

// 5. 제네릭과 프로토콜 제약
func drawAll(_ items: [T]) {
    for item in items {
        item.draw()
    }
}

// 6. 프로토콜 타입으로 사용 (existential type)
var shapes: [any Drawable] = [Circle(color: "Red", radius: 5)]

// 7. Codable - 가장 많이 사용되는 프로토콜
struct User: Codable {
    let id: Int
    let name: String
    let email: String
}

// JSON 인코딩/디코딩
let user = User(id: 1, name: "Kim", email: "kim@example.com")
let jsonData = try? JSONEncoder().encode(user)
let decoded = try? JSONDecoder().decode(User.self, from: jsonData!)

🗣️ 실무 대화 예시

모바일 앱 기술 스택 회의에서 (Swift vs Flutter)

"iOS 전용 앱이고 Apple 생태계 기능을 깊이 활용해야 하니까 Swift가 맞습니다. Flutter는 크로스플랫폼이라 빠르게 양쪽 앱을 만들 때 좋지만, Core ML, HealthKit, Apple Watch 연동은 Swift 네이티브가 훨씬 안정적이에요. SwiftUI로 하면 선언적 UI라 Flutter처럼 빠르게 개발할 수 있고요."

코드 리뷰 중 Optional 처리 피드백

"여기 강제 언래핑(!) 쓰신 부분, guard let으로 바꿔주세요. 서버 응답이 nil일 수 있어서 크래시 날 수 있어요. API 응답은 항상 Optional이라고 가정하고, if let이나 guard let으로 안전하게 처리하는 게 Swift 관례입니다."

기술 면접에서 Optional 설명 질문

"Swift의 Optional은 값이 없을 수 있음을 타입 시스템에서 명시적으로 표현하는 방법입니다. 내부적으로는 enum으로 구현되어 있어서 .some(value)와 .none 두 케이스를 가집니다. 컴파일 타임에 nil 체크를 강제하기 때문에 런타임 null pointer exception을 원천 차단하죠. Objective-C에서는 nil 메시지가 무시됐는데, Swift는 이를 컴파일 에러로 잡아줍니다."

⚠️ 주의사항

1
강제 언래핑(!) 사용 금지

force unwrap(!)은 nil일 때 앱이 크래시됩니다. if let, guard let, nil coalescing(??)를 사용하세요. IBOutlet 외에는 !를 쓰면 코드 리뷰에서 반려됩니다. Optional binding이 Swift의 안전성 핵심입니다.

2
ARC와 순환 참조

Swift는 ARC로 메모리를 관리하지만, 클로저와 delegate에서 순환 참조(retain cycle)가 발생할 수 있습니다. 클로저에서 [weak self] 또는 [unowned self]를 사용하고, delegate는 weak로 선언하세요.

3
버전 마이그레이션 비용

Swift는 빠르게 발전하며 메이저 버전 간 breaking change가 있습니다. Swift 4에서 5로 마이그레이션 시 String 처리 변경 등 수정이 필요했습니다. 새 프로젝트는 최신 버전으로, 기존 프로젝트는 Xcode 마이그레이션 도구를 활용하세요.

🔗 관련 용어

📚 더 배우기