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

Swift调用日出日落API时JSONDecoder解码失败该如何解决?

问题排查及修复方案

你将getData函数移出ViewController的操作不影响代码逻辑,不会导致解码失败,无需回退该修改。本次解码失败的核心原因如下:

1. 请求URL参数错误

你当前的请求URL结尾为不完整的&form,属于无效参数,会导致接口返回结构异常。正确的参数应为formatted,该参数控制返回值格式:

  • 若传formatted=0:day_length返回秒级数值(对应你模型里的Int类型,符合你的需求)
  • 若传formatted=1(默认值):day_length返回HH:MM:SS格式字符串,会和你定义的Int类型冲突,直接触发解码失败
    修正后的合法URL为:
    https://api.sunrise-sunset.org/json?date=2020-01-01&lat=-74.060&lng=40.7128&formatted=0

2. Swift Playground异步执行配置缺失

Playground默认执行完同步代码后会直接终止进程,不会等待URLSession的异步回调返回,所以哪怕代码逻辑正确也可能看不到返回结果,需要在Playground开头添加配置允许无限期执行:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

3. 可选优化点(避免崩溃)

你当前对URL做了强制解包,若URL构造失败会直接触发崩溃,建议替换为可选绑定判断:

guard let requestUrl = URL(string: url) else {
    print("URL构造失败")
    return
}
let task = URLSession.shared.dataTask(with: requestUrl, completionHandler: { ... })

另外解码报错时建议打印完整的error对象而不是localizedDescription,可以直接看到字段不匹配等具体错误原因,方便排查:

catch {
    print("解码失败: \(error)")
}

完整可运行代码示例

import UIKit
import PlaygroundSupport

// 允许Playground等待异步任务执行
PlaygroundPage.current.needsIndefiniteExecution = true

// 模型定义
struct Response: Codable {
    let results: MyResult
    let status: String
}

struct MyResult: Codable {
    let sunrise: String
    let sunset: String
    let solar_noon: String
    let day_length: Int
    let civil_twilight_begin: String
    let nautical_twilight_begin: String
    let nautical_twilight_end: String
    let astronomical_twilight_begin: String
    let astronomical_twilight_end: String
}

// 请求逻辑
let url = "https://api.sunrise-sunset.org/json?date=2020-01-01&lat=-74.060&lng=40.7128&formatted=0"
getData(from: url)

private func getData(from url: String) {
    guard let requestUrl = URL(string: url) else {
        print("URL构造错误")
        return
    }
    let task = URLSession.shared.dataTask(with: requestUrl, completionHandler: { data, response, error in
        guard let data = data, error == nil else {
            print("请求出错: \(error?.localizedDescription ?? "未知错误")")
            return
        }
        do {
            let result = try JSONDecoder().decode(Response.self, from: data)
            print("状态: \(result.status)")
            print("日出时间: \(result.results.sunrise)")
            print("昼长: \(result.results.day_length)秒")
        } catch {
            print("解码失败, 详细错误: \(error)")
        }
    })
    task.resume()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:15:07