가이드튜토리얼

Swift URLSession으로 환율 가져오기

URLSession, Codable, URLComponents를 사용하고 업데이트 정보를 보존하는 Swift 클라이언트를 만듭니다.

2026년 9월 8일 · 6분 읽기

네트워크는 URLSession, JSON은 Codable로 처리하세요. 실제 키는 서버에 두고 iOS, macOS, watchOS 앱에 넣지 마세요.

  • 응답 모델 정의하기: rates, source, market_session, data_updated_at을 모델에 보존하고 금액 계산에는 Decimal을 사용하세요.
  • 키를 서버에 두기: 모바일 앱은 자체 backend를 호출하고 backend가 Authorization을 추가해야 합니다. 서버 Swift는 환경 변수에서 키를 읽을 수 있습니다.
  • 상태와 최신성 처리하기: 디코드 전에 HTTP 상태를 확인하고 401과 429를 구분해 처리하세요.

응답 모델 정의하기

rates, source, market_session, data_updated_at을 모델에 보존하고 금액 계산에는 Decimal을 사용하세요.

swift · ExchangeRateClient.swift
import Foundationfinal class NoRedirects: NSObject, URLSessionTaskDelegate {    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {        completionHandler(nil)    }}struct Latest: Decodable {    let base: String    let source: String    let marketSession: String    let dataUpdatedAt: String    let rates: [String: Decimal]}struct ExchangeRateClient {    let session: URLSession    let apiKey: String?    func latest(base: String) async throws -> Latest {        let normalizedBase = base.uppercased()        guard normalizedBase.count == 3, normalizedBase.allSatisfy({ $0.isASCII && $0.isLetter }) else {            throw URLError(.badURL)        }        guard var components = URLComponents(string: "https://api.exchangerate.dev/v1/latest/\(normalizedBase)") else {            throw URLError(.badURL)        }        components.queryItems = [URLQueryItem(name: "symbols", value: "EUR,GBP,JPY")]        guard let url = components.url else { throw URLError(.badURL) }        var request = URLRequest(url: url)        request.timeoutInterval = 10        if let apiKey { request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization") }        let (data, response) = try await session.data(for: request)        guard let http = response as? HTTPURLResponse, (200..<300).contains(http.statusCode) else {            throw URLError(.badServerResponse)        }        let decoder = JSONDecoder()        decoder.keyDecodingStrategy = .convertFromSnakeCase        return try decoder.decode(Latest.self, from: data)    }}

키를 서버에 두기

모바일 앱은 자체 backend를 호출하고 backend가 Authorization을 추가해야 합니다. 서버 Swift는 환경 변수에서 키를 읽을 수 있습니다.

swift · server setup
let key = ProcessInfo.processInfo.environment["EXCHANGERATE_API_KEY"]let session = URLSession(configuration: .ephemeral, delegate: NoRedirects(), delegateQueue: nil)let client = ExchangeRateClient(    session: session,    apiKey: key)let latest = try await client.latest(base: "USD")print(latest.rates["EUR"] as Any, latest.source, latest.dataUpdatedAt)

상태와 최신성 처리하기

디코드 전에 HTTP 상태를 확인하고 401과 429를 구분해 처리하세요.

환율의 맥락을 함께 저장하세요

일일 보고서는 하루 한 번, 운영 대시보드는 한 시간마다 호출하면 됩니다. 429가 오면 즉시 재시도하지 말고 주기를 줄이세요.

  • 출처와 시간과 함께 환율을 저장합니다.
  • 자동화와 분석에 사용합니다.
  • 실행 가능한 가격으로 취급하지 않습니다.

자주 묻는 질문

iOS에 키를 넣어도 되나요?

안 됩니다. 앱 번들에서 추출할 수 있으므로 서버에 두세요.

키 없이 동작하나요?

네, 익명 평가 한도 안에서 동작합니다.

왜 Decimal을 쓰나요?

금액 계산에서 부동소수점 오차를 줄이기 위해서입니다.

429 이후에는 어떻게 하나요?

주기를 줄이고 즉시 재시도하지 않으며 요금제 한도를 지키세요.

계속 읽기

무료 API 키로 시작하세요

무료 플랜으로 월 5,000건 요청 가능. 신용카드는 필요하지 않습니다.

무료 키 받기