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

Swift命令行应用中使用URLSession发送POST请求失败排查

Swift命令行应用中URLSession uploadTask POST JSON请求到iTranslate API失败排查

我正在Swift命令行应用中尝试使用POST方法发送HTTP请求,请求体采用JSON格式。我用URLSession的uploadTask发送请求,请求体由字典序列化得到JSON数据。但请求无法正常工作,尽管我把请求内容打印到控制台后发现格式完全符合iTranslate API的要求。

以下是我的代码:

//creating new session
let session = URLSession.shared
let url = URL(string: "https://api.itranslate.com/translate/v1")!
//setting httpMethod to POST
var request = URLRequest(url: url)
request.httpMethod = "POST"
//setting header
request.setValue("application/json", forHTTPHeaderField: "content-type")
//dictionary with json
let json = ["key": "...", "source": ["dialect":"en", "text": "How are you?"], "target": ["dialect": "es"]] as [String : Any]
//serialization from json to jsonData
let jsonData = try! JSONSerialization.data(withJSONObject: json, options: [])
let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
    if let data = data, let dataString = String(data: data, encoding: .utf8) {
        print(dataString)
    }
}
task.resume()

请帮忙排查问题原因。


你的代码框架看起来没问题,但命令行场景下用URLSession有几个容易踩的坑,再结合API调用的细节,我帮你梳理排查方向:

1. 命令行应用的异步任务生命周期问题

这是最常见的命令行网络请求失败原因:Swift命令行应用默认在主函数执行完毕后就会立即退出,根本等不到URLSession的异步请求完成。

你需要在task.resume()后让程序保持运行,直到请求结束。推荐用信号量实现,修改后代码如下:

// 添加信号量阻塞主线程
let semaphore = DispatchSemaphore(value: 0)

let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
    // 请求完成后发送信号,解除阻塞
    defer { semaphore.signal() }
    
    // 先排查错误和响应状态码
    if let error = error {
        print("请求出错: \(error.localizedDescription)")
        return
    }
    
    if let httpResponse = response as? HTTPURLResponse {
        print("响应状态码: \(httpResponse.statusCode)") // 状态码能快速定位问题(比如401=权限错,400=参数错)
    }
    
    if let data = data, let dataString = String(data: data, encoding: .utf8) {
        print(dataString)
    }
}
task.resume()

// 阻塞主线程,等待请求完成
semaphore.wait()

2. 确认API Key的有效性

你代码里的"key": "..."是占位符,一定要替换成iTranslate官方提供的有效API Key。无效的Key会直接导致请求被拒绝,这时候看响应状态码(比如401 Unauthorized)就能立刻发现问题。

3. 完善JSON序列化的错误处理

你用try!强制解包,如果JSON序列化失败会直接崩溃,建议换成do-catch捕获错误,避免隐性崩溃:

do {
    let jsonData = try JSONSerialization.data(withJSONObject: json, options: [])
    // 后续任务代码
} catch {
    print("JSON序列化失败: \(error.localizedDescription)")
}

另外可以把序列化后的JSON转成字符串打印,确认没有格式问题:

if let jsonString = String(data: jsonData, encoding: .utf8) {
    print("序列化后的JSON内容: \(jsonString)")
}

4. 优先查看响应的错误详情

在回调里先打印error和HTTP响应状态码,这是快速定位问题的关键:

  • 状态码400:参数格式或内容不符合API要求
  • 状态码401:API Key无效或未授权
  • 状态码500:服务器端问题,可稍后重试

先试试这些调整,应该能找到问题所在!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:40:00