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

Swift 5调用Express后端API时Data始终为nil,但API经测试可用的问题排查求助

解决iOS App与Express后端通信时Data为nil的问题

看起来你刚接触iOS网络请求,很容易忽略一些细节,咱们一步步来排查和解决这个问题:

1. 先别忽略error参数,它会告诉你问题根源

你当前的代码只检查了data是否存在,完全没处理error。如果请求过程中出了问题(比如被系统拦截、网络错误、URL无效),error会给出明确提示,这是排查问题的第一步。修改你的请求回调代码:

let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
    // 优先处理错误
    if let error = error {
        print("请求出错:\(error.localizedDescription)")
        return
    }
    
    // 再验证HTTP响应状态码,确认请求是否到达服务器
    guard let httpResponse = response as? HTTPURLResponse else {
        print("无效的HTTP响应")
        return
    }
    print("服务器响应状态码:\(httpResponse.statusCode)") // 比如200是成功,4xx/5xx是错误
    
    do {
        if let data = data {
            // 注意:你的API返回的是数组,不是Dictionary,这里转成Array更准确
            let json = try JSONSerialization.jsonObject(with: data) as! [[String: Any]]
            print(json)
        } else {
            print("服务器未返回任何数据")
        }
    } catch {
        print("JSON解析失败:\(error.localizedDescription)")
    }
})
task.resume()

2. 最可能的原因:iOS ATS(App Transport Security)限制

iOS默认只允许HTTPS请求,你的API用的是http://开头的地址,会被系统拦截,导致请求失败、data为nil。你需要在Info.plist里配置ATS例外:

打开项目的Info.plist,添加以下配置(针对ngrok域名做例外,比全局允许HTTP更安全):

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>ngrok.io</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

3. 优化URL构建方式,避免字符串拼接错误

虽然你说硬编码URL也不行,但字符串拼接URL容易出现格式问题(比如坐标转String时的多余小数、特殊字符未转义),建议用URLComponents来构建:

guard let currentLoc = locationManager.location else {
    print("还未获取到有效位置信息")
    return
}
let latitude = currentLoc.coordinate.latitude
let longitude = currentLoc.coordinate.longitude

// 用URLComponents构建安全的URL
guard let baseURL = URL(string: "http://a542cd3116ed.ngrok.io/api/v1/public/location") else {
    print("基础URL无效")
    return
}
var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: true)!
components.path += "/\(latitude)/\(longitude)/100"
guard let finalURL = components.url else {
    print("URL构建失败")
    return
}

var request = URLRequest(url: finalURL)
request.httpMethod = "GET"

4. 额外检查:位置信息是否有效

你直接取locationManager.location,有可能这个值是nil(比如位置权限未授权、位置管理器还未完成初始化),所以一定要先做非空判断,避免后续URL构建出错。

按照上面的步骤修改后,你应该能看到具体的错误提示或者正常的服务器响应了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:48:13