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
相关产品推荐
相关产品推荐

