PanduanTutorial

Mengambil kurs valas di Swift dengan URLSession

Gunakan URLSession, Codable, dan URLComponents sambil menyimpan informasi waktu pembaruan untuk menampilkan kurs di aplikasi Swift iOS dan macOS.

8 Sep 2026 · 6 menit membaca

Gunakan URLSession untuk jaringan dan Codable untuk JSON. Simpan kunci di server, bukan di aplikasi iOS, macOS, atau watchOS.

  • Tentukan model respons: Simpan rates, source, market_session, dan data_updated_at; gunakan Decimal untuk perhitungan nilai uang.
  • Simpan kunci di server: Aplikasi mobile memanggil backend Anda, lalu backend menambahkan Authorization. Swift di server dapat membaca kunci dari environment.
  • Tangani status dan kesegaran: Periksa status HTTP sebelum decode dan bedakan 401 dari 429. Tampilkan waktu dan sumber pengamatan.

Tentukan model respons

Simpan rates, source, market_session, dan data_updated_at; gunakan Decimal untuk perhitungan nilai uang.

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

Simpan kunci di server

Aplikasi mobile memanggil backend Anda, lalu backend menambahkan Authorization. Swift di server dapat membaca kunci dari environment.

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)

Tangani status dan kesegaran

Periksa status HTTP sebelum decode dan bedakan 401 dari 429. Tampilkan waktu dan sumber pengamatan.

Simpan konteks kurs

Laporan harian cukup sekali sehari, sedangkan dashboard operasional bisa tiap jam. Saat menerima 429, kurangi jadwal dan jangan membuat loop retry.

  • Simpan kurs bersama sumber dan waktu.
  • Gunakan untuk otomasi dan analisis.
  • Jangan perlakukan sebagai kuotasi eksekusi.

Pertanyaan

Bolehkah kunci ada di iOS?

Tidak, kunci dari app bundle dapat diekstrak; gunakan server.

Bisa tanpa kunci?

Bisa, dalam batas evaluasi anonim.

Mengapa Decimal?

Untuk menghindari error floating point saat menghitung nominal.

Apa yang dilakukan setelah 429?

Kurangi jadwal, jangan langsung retry, dan patuhi batas paket.

Baca selanjutnya

Mulai dengan kunci API gratis

5.000 permintaan per bulan dengan paket gratis. Tanpa kartu kredit.

Dapatkan kunci gratis