Tutorial/เริ่มต้นใช้งาน Swift

ดึงอัตราแลกเปลี่ยนใน Swift ด้วย URLSession

ใช้ URLSession, Codable และ URLComponents พร้อมเก็บข้อมูลเวลาที่อัปเดต.

ERexchangerate.dev·Sep 8, 2026·อ่าน 6 นาที

ให้ URLSession จัดการเครือข่ายและ Codable จัดการ JSON คีย์จริงควรอยู่ที่ server ไม่ใช่ในแอป iOS, macOS หรือ watchOS.

Key points
กำหนด response model: เก็บ rates, source, market_session และ data_updated_at ใน model และใช้ Decimal กับจำนวนเงิน.
เก็บคีย์ไว้ที่ server: แอปมือถือเรียก backend ของคุณ แล้ว backend เติม Authorization ส่วน Swift ฝั่ง server อ่านคีย์จาก environment ได้.
จัดการสถานะและ freshness: ตรวจสอบ HTTP status ก่อน decode แยก 401 กับ 429 และแสดงเวลาและ source ให้ผู้ใช้เห็น.

กำหนด response model

เก็บ rates, source, market_session และ data_updated_at ใน model และใช้ Decimal กับจำนวนเงิน.

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

เก็บคีย์ไว้ที่ server

แอปมือถือเรียก backend ของคุณ แล้ว backend เติม Authorization ส่วน Swift ฝั่ง server อ่านคีย์จาก environment ได้.

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)

จัดการสถานะและ freshness

ตรวจสอบ HTTP status ก่อน decode แยก 401 กับ 429 และแสดงเวลาและ source ให้ผู้ใช้เห็น.

เก็บบริบทของอัตราไว้ด้วย
รายงานรายวันใช้วันละครั้ง ส่วน dashboard อาจใช้ทุกชั่วโมง เมื่อเจอ 429 ให้ลดความถี่ ไม่ใช่สร้าง retry ทันที.
  • เก็บอัตราพร้อม source และเวลา.
  • ใช้กับ automation และการวิเคราะห์.
  • อย่าใช้เป็นราคาที่ execute ได้.
ER
exchangerate.dev
คู่มือการเชื่อมต่อสำหรับนักพัฒนา

อ่านต่อ

Referenceเริ่มต้นใช้งาน FX APIอ่าน TutorialJavaScript / Node.jsอ่าน Guideเก็บบริบทของอัตราไว้ด้วยอ่าน
เปรียบเทียบเพิ่มเติมFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
เรียนรู้Reading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
อัตราสดEUR/USDGBP/USDUSD/JPY