Tutorial/Swift hızlı başlangıç

Swift URLSession ile döviz kurlarını alma

URLSession, Codable ve URLComponents ile güncelleme bilgisini koruyan bir Swift istemcisi oluşturun.

ERexchangerate.dev·Sep 8, 2026·6 dk okuma

Ağı URLSession, JSON sözleşmesini Codable yönetir. Anahtarı sunucuda tutun; iOS, macOS veya watchOS paketine gömmeyin.

Key points
Yanıt modelini tanımlayın: Modelde rates, source, market_session ve data_updated_at alanlarını koruyun. Tutar hesaplarında Decimal kullanın.
Anahtarı sunucuda tutun: Mobil uygulama kendi backendinizi çağırmalı, Authorization başlığını backend eklemelidir. Sunucu Swift ortamdan anahtarı okuyabilir.
Durum ve güncelliği yönetin: JSON çözümlemeden önce HTTP durumunu kontrol edin; 401 ve 429 durumlarını ayırın.

Yanıt modelini tanımlayın

Modelde rates, source, market_session ve data_updated_at alanlarını koruyun. Tutar hesaplarında Decimal kullanın.

swift · ExchangeRateClient.swiftcopy
import Foundation

final 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)
    }
}

Anahtarı sunucuda tutun

Mobil uygulama kendi backendinizi çağırmalı, Authorization başlığını backend eklemelidir. Sunucu Swift ortamdan anahtarı okuyabilir.

swift · server setupcopy
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)

Durum ve güncelliği yönetin

JSON çözümlemeden önce HTTP durumunu kontrol edin; 401 ve 429 durumlarını ayırın.

Kur bağlamını koruyun
Günlük rapor için günde bir, operasyon paneli için saatte bir çağrı yeterli olabilir. 429 sonrası hemen yeniden denemek yerine sıklığı azaltın.
  • Kuru kaynak ve zamanla birlikte saklayın.
  • Otomasyon ve analiz için kullanın.
  • Uygulanabilir fiyat gibi görmeyin.
ER
exchangerate.dev
Geliştiriciler için entegrasyon rehberleri.

Okumaya devam edin

ReferenceKur API hızlı başlangıçOku TutorialJavaScript / Node.jsOku GuideKur bağlamını koruyunOku
Daha Fazla KarşılaştırmaFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
ÖğrenReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Canlı KurlarEUR/USDGBP/USDUSD/JPY