iOS端WebService请求重复发送问题排查求助
这种iOS独有的重复请求问题我之前碰到过好几次,结合你描述的「代码仅调用一次(日志只打一次)、Android端正常、已排除服务端问题」这些信息,大概率是iOS网络层的自动重试机制或者你使用的网络库配置导致的,下面给你一步步拆解排查和解决的方案:
1. 先排查URLSession的默认重试行为
iOS原生的URLSession在遇到特定网络异常(比如请求超时、临时网络波动)时,会自动触发重试逻辑——哪怕你的代码只调用了一次请求,底层也可能悄悄发多次。
你可以通过自定义URLSessionConfiguration来禁用自动重试:
let config = URLSessionConfiguration.default // 禁用系统自动重试的关键配置 config.httpMaximumConnectionsPerHost = 1 config.timeoutIntervalForRequest = 10 // 缩短超时时间,减少触发重试的概率 config.allowsCellularAccess = true // 使用自定义配置创建Session,替代默认的URLSession.shared let customSession = URLSession(configuration: config)
之后用这个customSession来发起你的Post请求,而不是默认的共享Session。
2. 检查网络库的重试插件(如果用了Alamofire等)
如果你是用Alamofire这类第三方网络库,很可能不小心开启了默认重试策略,哪怕代码只调用一次,插件也会自动重试请求。比如这类错误写法:
// 错误示例:默认retry()会自动重试请求 AF.request(baseURL, method: .post, parameters: params) .retry() // 这个方法会导致重复请求 .responseJSON { response in // 处理响应逻辑 }
如果有这类配置,要么直接移除retry(),要么自定义重试条件,只在明确需要的场景(比如服务端返回5xx错误)才触发重试:
// 自定义重试策略:仅在5xx错误时重试1次 let retryPolicy = RetryPolicy(retryLimit: 1, retryStatusCodes: [500, 502, 503]) AF.request(baseURL, method: .post, parameters: params) .retry(retryPolicy) .responseJSON { response in // 处理响应逻辑 }
3. 用断点+抓包确认请求发起源
虽然你说控制台日志只打印一次,但还是建议在SendPostHttpRequest方法开头加个断点,确认代码是否真的只被执行一次。如果断点只触发一次,那肯定是底层网络层的问题。
同时用Charles或Wireshark抓iOS设备的网络包,看重复请求的User-Agent是否来自你的App:
- 如果是,说明是App内部的配置问题;
- 如果不是,可能是系统层面的网络重试(比如VPN、代理的影响)。
4. 排查App生命周期的影响
如果你的请求是在App进入后台/前台的临界状态发起的,iOS的生命周期回调(比如applicationDidEnterBackground)可能会导致网络请求被系统重新调度,出现重复发送的情况。可以在请求发起时打印当前App状态:
print("当前App状态:\(UIApplication.shared.applicationState.rawValue)")
如果是在后台发起的请求,建议用BackgroundTasks框架来处理,避免系统干扰。
内容的提问来源于stack exchange,提问作者ava

