从天气API转换数组时如何选Double/String/Int?获取最低温及图标失败
Hey there! I totally get how frustrating it is when half your data comes through perfectly (high temps and dates!) but the other half goes MIA. Let’s break down the most likely issues and fix this step by step.
Common Causes & Fixes
1. You’re Targeting the Wrong API Field Paths
First, double-check the exact structure of the API response—this is the #1 culprit for missing data:
- Low temperatures might live under a different key than high temps (e.g.,
main.temp_mininstead ofmain.temp_max). - Weather icons are almost always nested inside a sub-array (like
weather[0].icon), since many APIs return multiple weather conditions per timestamp. If you’re trying to accessicondirectly without drilling into theweatherarray, you’ll get nothing.
2. Data Type Mismatches Are Blocking Parsing
Even if you pick the right field, a type mismatch will silently fail (or throw an error you might not be catching):
- If the API returns low temp as a string (e.g.,
"15.2"instead of15.2), trying to decode it directly into aDoublewill fail. You’ll need to either adjust your model to useStringfirst then convert, or check if the API has a numeric format option. - Weather icons are always strings (like
"01d"for a sunny day), so trying to store them in anIntarray will never work. Stick to[String]for youriconArray.
3. Your Array Initialization/Assignment Logic Has Gaps
Make sure you’re actually populating minTempArray and iconArray in the same loop where you handle high temps and dates. It’s easy to forget to add those lines when copying code!
Example Working Code (Swift)
Here’s a cleaned-up version of your code that properly fetches all 4 datasets, using Codable for reliable parsing:
// Define models that match your API's response structure exactly struct WeatherResponse: Codable { let list: [DailyWeather] } struct DailyWeather: Codable { let main: TemperatureData let weather: [WeatherCondition] let dt: TimeInterval // Timestamp (usually in seconds since 1970) } struct TemperatureData: Codable { let temp_max: Double // Match API key exactly—watch for underscores vs camelCase! let temp_min: Double } struct WeatherCondition: Codable { let icon: String // Icon ID like "01d" or "10n" } // Your data arrays var highTempArray: [Double] = [] var lowTempArray: [Double] = [] var dateArray: [String] = [] var iconArray: [String] = [] // Parse the API response func parseWeatherData(from data: Data) { do { let decodedResponse = try JSONDecoder().decode(WeatherResponse.self, from: data) // Group 3-hourly data into daily chunks (most 5-day APIs return 3-hour intervals) let dailyGroups = Dictionary(grouping: decodedResponse.list) { day in let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" return dateFormatter.string(from: Date(timeIntervalSince1970: day.dt)) } // Extract one entry per day (adjust if you need daily averages instead) for (_, dailyEntries) in dailyGroups { guard let firstEntry = dailyEntries.first else { continue } // Populate arrays highTempArray.append(firstEntry.main.temp_max) lowTempArray.append(firstEntry.main.temp_min) iconArray.append(firstEntry.weather.first?.icon ?? "default-icon") // Fallback if icon is missing // Convert timestamp to weekday name let dateFormatter = DateFormatter() dateFormatter.dateFormat = "EEEE" // e.g., "Monday", "Tuesday" let date = Date(timeIntervalSince1970: firstEntry.dt) dateArray.append(dateFormatter.string(from: date)) } } catch { print("Parsing error: \(error.localizedDescription)") // Don't ignore errors! } }
Pro Tips to Avoid Headaches
- Print the raw API response to confirm field names and types (use
String(data: data, encoding: .utf8)to see what you’re working with). - Handle optional values (like
weather.first?.icon) with a fallback—don’t force-unwrap, or your app might crash if the API returns unexpected data. - Check timestamp units: Some APIs use milliseconds instead of seconds for
dt—if your dates are way off, divide the timestamp by 1000.
内容的提问来源于stack exchange,提问作者Rich J

