BIBI BLOG

Swift에서 자주 사용하는 모델 프로토콜 🎯 본문

iOS/Swift

Swift에서 자주 사용하는 모델 프로토콜 🎯

BIBI⭐️ 2025. 3. 11. 18:49
728x90

Swift에서 자주 사용하는 모델 프로토콜 🎯

Swift에서 Equatable, Hashable 같은 프로토콜(Protocol)특정 기능을 반드시 구현하도록 강제하는 설계도 같은 역할을 해요.
특히 모델(데이터를 담는 구조체나 클래스) 에 많이 쓰이는 프로토콜들을 모아서 정리해 보았어요!


🔷 1. Equatable (같은지 비교할 수 있도록 해줌)

Equatable을 적용하면 두 개의 값이 같은지(==) 비교할 수 있어요.
자동으로 == 연산자가 생성되기 때문에, 코드가 짧아지고 편리해요!

📌 예제

struct Person: Equatable {
    let name: String
    let age: Int
}

let person1 = Person(name: "Alice", age: 20)
let person2 = Person(name: "Alice", age: 20)

print(person1 == person2) // true (같은 데이터라서 true)

🛠 언제 사용하면 좋을까?

  • 유저 정보, 상품 정보 같은 데이터를 비교할 때

🔷 2. Hashable (고유한 값으로 변환)

Hashable을 적용하면 Set, Dictionary 같은 곳에서 값을 빠르게 찾을 수 있음
(컴퓨터가 데이터를 "숫자"로 변환해서 관리하기 때문에 빠름!)

📌 예제

struct Product: Hashable {
    let id: Int
    let name: String
}

let product1 = Product(id: 101, name: "iPhone")
let product2 = Product(id: 102, name: "MacBook")

var productSet: Set<Product> = [product1, product2]
print(productSet.contains(product1)) // true (빠르게 검색 가능!)​

🛠 언제 사용하면 좋을까?

  • 중복 없는 데이터 저장 (예: 회원 ID, 상품 ID)
  • Set, Dictionary에서 빠르게 검색할 때

🔷 3. Codable (JSON으로 변환할 수 있도록)

Codable을 적용하면 데이터를 JSON으로 변환하거나 JSON에서 데이터를 가져올 수 있음
(JSON은 서버와 데이터를 주고받을 때 많이 사용되는 형식!)

📌 예제

import Foundation

struct User: Codable {
    let name: String
    let age: Int
}

// JSON 데이터로 변환
let user = User(name: "Bob", age: 25)
let jsonData = try? JSONEncoder().encode(user)
print(String(data: jsonData!, encoding: .utf8)!) // {"name":"Bob","age":25}

// JSON에서 객체로 변환
let jsonString = "{\"name\":\"Charlie\",\"age\":30}"
let jsonData2 = jsonString.data(using: .utf8)!
let decodedUser = try? JSONDecoder().decode(User.self, from: jsonData2)
print(decodedUser!) // User(name: "Charlie", age: 30)

🛠 언제 사용하면 좋을까?

  • 서버에서 데이터를 가져오거나 보낼 때 (예: 로그인, 게시글, 채팅)

🔷 4. Identifiable (각 항목을 고유하게 식별)

SwiftUI에서 리스트(List)처럼 여러 개의 데이터를 관리할 때 필수!
Identifiable을 적용하면 id 값으로 각각을 구별할 수 있어요.

📌 예제

import SwiftUI

struct Animal: Identifiable {
    let id = UUID() // 자동으로 고유한 값 생성
    let name: String
}

let animals = [Animal(name: "Dog"), Animal(name: "Cat"), Animal(name: "Rabbit")]

ForEach(animals) { animal in
    Text(animal.name)
}

🛠 언제 사용하면 좋을까?

  • SwiftUI의 List, ForEach 에서 데이터 표시할 때

🔷 5. Comparable (값을 크기 비교 가능)

Comparable을 적용하면 값의 크기를 비교할 수 있음
(<, >, <=, >= 연산자 사용 가능)

📌 예제

struct Student: Comparable {
    let name: String
    let score: Int

    static func < (lhs: Student, rhs: Student) -> Bool {
        return lhs.score < rhs.score
    }
}

let s1 = Student(name: "Alice", score: 90)
let s2 = Student(name: "Bob", score: 80)

print(s1 > s2) // true (Alice 점수가 더 높음)

🛠 언제 사용하면 좋을까?

  • 점수, 가격, 거리 등 숫자 비교할 때

🔷 6. CaseIterable (모든 값을 배열로 가져올 수 있음)

enum에서 사용하면 모든 케이스를 배열처럼 가져올 수 있음

📌 예제

enum Fruit: CaseIterable {
    case apple, banana, orange
}

for fruit in Fruit.allCases {
    print(fruit)
}
// apple
// banana
// orange

🛠 언제 사용하면 좋을까?

  • 모든 옵션을 반복문으로 돌려야 할 때 (예: 설정 옵션, 게임 캐릭터 목록)

🔷 7. CustomStringConvertible (출력할 때 보기 좋게)

객체를 출력할 때 커스텀된 문자열을 출력할 수 있음

📌 예제

struct Car: CustomStringConvertible {
    let model: String
    let year: Int
    
    var description: String {
        return "\(year)년식 \(model)"
    }
}

let car = Car(model: "Tesla Model 3", year: 2022)
print(car) // 2022년식 Tesla Model 3

🛠 언제 사용하면 좋을까?

  • print() 했을 때 예쁜 문자열로 표시하고 싶을 때

🔷 8. RawRepresentable (특정 타입으로 변환 가능)

enum의 값을 숫자나 문자열 같은 특정 타입으로 변환 가능

📌 예제

enum Direction: String {
    case north = "북쪽"
    case south = "남쪽"
    case east = "동쪽"
    case west = "서쪽"
}

let d = Direction.north
print(d.rawValue) // "북쪽"

🛠 언제 사용하면 좋을까?

  • 데이터를 저장하거나, 변환할 때

🔷 9. Error (커스텀 에러 정의)

사용자 정의 에러 타입을 만들 때 사용

📌 예제

enum LoginError: Error {
    case invalidUsername
    case wrongPassword
}

func login(username: String, password: String) throws {
    if username != "admin" { throw LoginError.invalidUsername }
    if password != "1234" { throw LoginError.wrongPassword }
}

do {
    try login(username: "user", password: "1234")
} catch {
    print(error) // invalidUsername
}
728x90
Comments