You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift解析复杂JSON求助:基于Alamofire获取数据并通过Struct解析

Parsing Dynamic-Key JSON in Swift with Alamofire

Got it, let's work through parsing this JSON structure where the top-level keys are dynamic random strings (like -8802586561990153106-1804221538-5). Here's a step-by-step solution tailored to your setup:

1. Define Your Codable Structs First

First, make sure your nested structs all conform to Codable (this is required for Alamofire's built-in decoding). I've mapped them directly to your JSON structure:

import Foundation
import Alamofire

struct Zug: Codable {
    let klasse: String
    let nummer: String
}

struct Ankunft: Codable {
    let zeitGeplant: String
    let zeitAktuell: String
    let routeGeplant: [String]
}

struct Abfahrt: Codable {
    let zeitGeplant: String
    let zeitAktuell: String
    let routeGeplant: [String]
}

struct Train: Codable {
    let zug: Zug
    let ankunft: Ankunft
    let abfahrt: Abfahrt
}

2. Decode the Dynamic Top-Level Dictionary

The key trick here is that your entire JSON response is a dictionary with string keys and Train values ([String: Train]). Alamofire's responseDecodable can handle this directly:

// Replace with your actual API endpoint
let trainAPIURL = "https://your-api-url-here.com/train-data"

AF.request(trainAPIURL).responseDecodable(of: [String: Train].self) { response in
    switch response.result {
    case .success(let trainData):
        // Process the data—you can iterate over the key-value pairs
        for (uniqueTrainKey, train) in trainData {
            print("Unique Train Identifier: \(uniqueTrainKey)")
            print("Train Details: Class \(train.zug.klasse), Number \(train.zug.nummer)")
            print("Scheduled Arrival: \(train.ankunft.zeitGeplant) | Actual: \(train.ankunft.zeitAktuell)")
            print("Arrival Route: \(train.ankunft.routeGeplant.joined(separator: " → "))")
            print("Scheduled Departure: \(train.abfahrt.zeitGeplant) | Actual: \(train.abfahrt.zeitAktuell)")
            print("Departure Route: \(train.abfahrt.routeGeplant.joined(separator: " → "))")
            print("---")
        }
        
        // If you only care about the train objects (not the keys), convert to an array:
        let allTrains = Array(trainData.values)
        // Use allTrains as needed
        
    case .failure(let error):
        print("Decoding failed: \(error.localizedDescription)")
        // Optional: Print raw JSON to debug if parsing goes wrong
        if let rawData = response.data, let rawJSONString = String(data: rawData, encoding: .utf8) {
            print("Raw JSON Response: \(rawJSONString)")
        }
    }
}

Key Notes

  • The top-level type [String: Train] is crucial here—since your JSON uses dynamic, unpredictable keys at the root, we can't map them to a fixed struct property. Using a dictionary lets us capture all those key-value pairs.
  • All nested structs (Zug, Ankunft, Abfahrt) automatically decode because they conform to Codable and their property names exactly match the JSON keys (case-sensitive, which matches your JSON).
  • If you need to handle date formatting for the zeitGeplant/zeitAktuell strings (like converting "1804221603" to a Date), you can add a custom JSONDecoder with a date formatter and pass it to Alamofire's responseDecodable:
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "ddMMyyHHmm" // Adjust based on your date string format
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .formatted(dateFormatter)
    
    AF.request(trainAPIURL).responseDecodable(of: [String: Train].self, decoder: decoder) { response in
        // ... same handling as before
    }
    
    Just update your struct properties to be Date instead of String if you do this.

内容的提问来源于stack exchange,提问作者user5331311

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:51:56