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 toCodableand their property names exactly match the JSON keys (case-sensitive, which matches your JSON). - If you need to handle date formatting for the
zeitGeplant/zeitAktuellstrings (like converting "1804221603" to aDate), you can add a customJSONDecoderwith a date formatter and pass it to Alamofire'sresponseDecodable:
Just update your struct properties to belet 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 }Dateinstead ofStringif you do this.
内容的提问来源于stack exchange,提问作者user5331311
相关产品推荐
相关产品推荐

