

import Foundation
enum RideType: Int, CaseIterable, Identifiable {
    case uberX
    case black
    case uberXL
    
    var id: Int { return rawValue }
    
    var description: String {
        switch self {
        case .uberX:
            return "UberX"
        case .black:
            return "UberBlack"
        case .uberXL:
            return "UberXL"
        }
    }
    
    var imageName: String {
        switch self {
        case .uberX:
            return "uber_x"
        case .black:
            return "uber_black"
        case .uberXL:
            return "uber_xl"
        }
    }
    
    var fair: Double {
        switch self {
        case .uberX: return 10
        case .black: return 20
        case .uberXL: return 15
        }
    }
    
    func computedPrice(for distanceInMeters: Double) -> Double {
        let distanceInMiles = distanceInMeters / 1600
        switch self {
        case .uberX:
            return distanceInMiles * 1.5 + fair
        case .black:
            return distanceInMiles * 2.0 + fair
        case .uberXL:
            return distanceInMiles * 1.75 + fair
        }
    }
}
Identificable νλ‘ν μ½μ λ°λ₯΄κΈ° μν΄ id κ°μ μλ³μλ‘ λ¦¬ν΄ (μ°μ° νλ‘νΌν°)    @State private var selectedRideType: RideType = .uberX
...
                    ForEach(RideType.allCases) { ride in
                        VStack(alignment: .leading) {
                            Image(ride.imageName)
                                .resizable()
                                .scaledToFit()
                            
                            VStack(alignment: .leading,  spacing: 4) {
                                Text(ride.description)
                                    .font(.system(size: 14, weight: .semibold))
                                Text(viewModel.computeRidePrice(for: ride).asCurrency)
                                    .font(.system(size: 14, weight: .semibold))
                            }
                            .padding(8)
                        }
                        .frame(width: 112, height: 140)
                        .foregroundColor(ride == selectedRideType ? .white : .black)
                        .background(Color(ride == selectedRideType ? .systemBlue : .systemGroupedBackground))
                        .scaleEffect(ride == selectedRideType ? 1.1 : 1)
                        .cornerRadius(10)
                        .onTapGesture {
                            withAnimation(.spring()) {
                                selectedRideType = ride
                            }
                        }
                    }
@State νλ‘νΌν°λ₯Ό ν΅ν΄ νΉμ  μΉ΄λ μ νμ 체ν¬, μ ν μ¬λΆμ λ°λΌμ λ€λ₯Έ μΉ΄λμ λ€λ₯Έ ν¨κ³Ό(μκΉ, μ€μΌμΌ μ¬λΆ λ±) μ£ΌκΈ°.onReceive(LocationManager.shared.$userLocation) { location in
            if let location = location {
                viewModel.userLocation = location
            }
        }
func computeRidePrice(for ride: RideType) -> Double {
        guard
            let destinationCoordinate = selectedLocation,
            let startCoordinate = userLocation else { return 0.0 }
        let start = CLLocation(latitude: startCoordinate.latitude, longitude: startCoordinate.longitude)
        let dest = CLLocation(latitude: destinationCoordinate.latitude, longitude: destinationCoordinate.longitude)
        let distanceInMeters = start.distance(from: dest)
        return ride.computedPrice(for: distanceInMeters)
    }

μ 체μ μΌλ‘ μ κ°μλ νκ²½ λ³μλ₯Ό λ§€μ° μ μ©νκ² μ κ·Όνλ κ² κ°μλ°, κ·ΈλΌμλ λΆκ΅¬νκ³ λ©λͺ¨λ¦¬ λμμ κ°μ μΌμ κ±±μ νμ§ μμ μ μλ€. DIλ₯Ό ν΅ν΄ ν΄κ²°ν μ μκ² μ§λ§, μμ κ°μ μ½λ©μ μ©μ΄μ±μ λ§€λ ₯μ μ΄λ€. λ¬Όλ‘ μ°λ²μ κ°μ΄ μμΉ μ 보λ₯Ό μ§μμ μΌλ‘ μ κ·Όνλ κ²μ΄ νμ λΆκ°κ²°ν κ²½μ°μλ νκ²½ λ³μκ° ν΄λ΅μΌ μ§λ.