Swift解析JSON并在TableView展示时报错:无法转成[String:Any]
Hey there! Let's break down this error and fix it step by step.
What's Causing the Error?
The error Cast from '(key: String, value: AnyObject)' to unrelated type '[String : Any]' always fails means you're trying to convert a key-value tuple (the type you get when iterating over a dictionary's entries) directly into a [String: Any] dictionary. These two types are completely unrelated, so the compiler immediately flags this as impossible.
Looking at the TFL API you're using (https://api.tfl.gov.uk/journey/journeyresults/1000266/to/1000013), the response structure has a top-level dictionary that contains a journeys array—this array is where your actual journey data lives. You're probably making a mistake in how you're traversing this structure: instead of targeting the journeys array, you're accidentally iterating over the top-level dictionary's key-value pairs.
Example of the Mistake (What You Might Have Written)
This is the kind of code that would trigger your error:
// ❌ Wrong approach: iterating over the top-level dictionary's key-value pairs if let response = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { for journeyEntry in response { // journeyEntry is a (key: String, value: Any) tuple let journeyDict = journeyEntry as! [String: Any] // This line causes the error! // Attempt to process journeyDict... } }
Fixed Code for Parsing the TFL API
Here's how to correctly parse the response and get data ready for your TableView:
// ✅ Correct approach: target the "journeys" array in the top-level dictionary do { guard let topLevelDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let journeys = topLevelDict["journeys"] as? [[String: Any]] else { print("Failed to parse JSON or locate the journeys array") return } // Iterate over the actual journey dictionaries in the array for journey in journeys { // Extract fields you need for your TableView cells if let duration = journey["duration"] as? Int, let startDateTime = journey["startDateTime"] as? String { print("Journey takes \(duration) mins, starts at \(startDateTime)") } // If you need to process journey legs, dig deeper into the structure if let legs = journey["legs"] as? [[String: Any]] { for leg in legs { if let mode = leg["mode"] as? String { print("Leg uses transport mode: \(mode)") } } } } // Assign parsed data to your TableView's data source and refresh self.journeyDataSource = journeys DispatchQueue.main.async { self.tableView.reloadData() } } catch { print("JSON parsing error: \(error.localizedDescription)") }
Key Takeaway
The core issue was mixing up dictionary iteration (which gives you key-value tuples) and array iteration (which gives you the dictionary objects you need). The TFL API's useful data lives inside the journeys array of the top-level response—focus on accessing and iterating over that array, not the top-level dictionary's entries.
内容的提问来源于stack exchange,提问作者User 5000

