iOS向带SSL证书服务器发起HTTPS请求遇连接失败问题求助
解决HTTPS请求出现TIC TCP Conn Failed (-65554)和HTTP load failed (-1003)的问题
嘿,我刚帮好几个开发者搞定过一模一样的问题,咱们一步步拆解排查:
先搞懂错误背后的原因
-65554:核心是SSL/TLS握手失败,要么是服务器证书不被系统信任,要么是ATS(App Transport Security)的安全规则拦截了连接-1003:基本是伴随SSL错误出现的,意思是系统没法建立符合安全要求的HTTPS连接
最常见的解决方案:配置ATS(iOS 9+默认强制启用)
iOS从9.0开始默认开启ATS,要求所有HTTPS连接必须满足严格安全标准(比如TLS 1.2+、证书由可信CA颁发等)。如果你的服务器不符合这些标准,得在Info.plist里添加例外配置:
方案1:允许特定域名的非标准HTTPS连接(推荐,App Store审核更容易通过)
在Info.plist中插入以下配置,把你的服务器域名替换成实际域名:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>你的服务器域名(比如example.com)</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.0</string> <!-- 若服务器仅支持老版本TLS,按需修改 --> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <false/> <!-- 仅当服务器证书完全不可信时临时设为true,上线前务必改回 --> </dict> </dict> </dict>
方案2:全局允许所有HTTP/HTTPS连接(仅测试环境用,不推荐上线)
如果只是临时测试,可以用这个配置,但上线前一定要换成方案1,否则App Store审核大概率被拒:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
如果是自签名/私有CA证书的问题
如果你的服务器用的是自签名证书,哪怕配置了ATS,系统还是会拒绝信任,这时候需要在代码里添加自定义信任逻辑:
- 让你的类遵守
URLSessionDelegate协议 - 实现以下代理方法(注意:上线前一定要补充证书合法性验证,避免中间人攻击!):
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { guard let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } // 测试环境直接信任,上线前要替换成验证证书公钥/指纹的逻辑 let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) }
最后检查你的URL是否合法
确保Constants.baseUrl + self.url拼接后是标准的HTTPS格式,比如https://api.example.com/user,没有拼写错误(比如少打了s、域名写错等)。
结合你的代码,修正后的请求示例大概是这样:
func doTask(completion: @escaping (_ dictionary: NSDictionary) -> Void) { self.start() guard let url = URL(string: Constants.baseUrl + self.url) else { // 处理URL无效的情况 completion(NSDictionary()) return } var request = URLRequest(url: url) // 按需添加请求头,比如Content-Type request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 注意要设置delegate来处理证书信任(如果需要的话) let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) let task = session.dataTask(with: request) { data, response, error in if let error = error { print("请求错误:\(error)") completion(NSDictionary()) return } // 解析数据并返回结果 if let data = data, let dict = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary { completion(dict) } else { completion(NSDictionary()) } } task.resume() }
内容的提问来源于stack exchange,提问作者D.Pacheco




