首页 > 解决方案 > 使用 URLSession 和 AlamoFire 的 HTTP 状态 NIL。错误代码=303 和 NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask

问题描述

预期:

发生了什么:

应用版本:

测试:

网络调用代码:

func makeNetworkCall(url: String, method: HTTPMethod = .get, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, timeout: Double, completion: @escaping (DefaultURLRequestReturnModel) -> Void ) {
        
        logger.debug("makingCall with: url= _\(url)_ method= _\(method)_, param= _\(parameters)_, headers= _\(headers)_")
        
        var urlRequest: URLRequest?
        var hasReturned: Bool = false
        
        DispatchQueue.main.asyncAfter(deadline: .now() + timeout, execute: {
            if !hasReturned {
                completion(DefaultURLRequestReturnModel(isSuccess: false, statusCode: ErrorCodes.timeoutError.rawValue, action: .failure, dataResponse: nil))
            }
        })
        
        do {
            urlRequest = try URLRequest(url: url, method: method, headers: headers)
            
            if let parameters = parameters {
                urlRequest?.httpBody = try JSONSerialization.data(withJSONObject: parameters)
            }
        } catch {
            completion(DefaultURLRequestReturnModel(isSuccess: false, statusCode: ErrorCodes.encodeError.rawValue, action: .failure, dataResponse: nil))
            return
        }
        
        // Unwrap the optional urlRequest to confirm its != nil
        guard var safeURLRequest = urlRequest else {
            
            completion(DefaultURLRequestReturnModel(isSuccess: false, statusCode: ErrorCodes.encodeError.rawValue, action: .failure, dataResponse: nil))
            return
        }
        
        if safeURLRequest.httpBody != nil {
            safeURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
        }
        
        let session = URLSession.shared

        logger.debug("before session.dataTask for url \(safeURLRequest.url)")
        let task = session.dataTask(with: safeURLRequest, completionHandler: { data, response, error in
            
            logger.debug("url session completion for safeURLRequest.url _\(safeURLRequest.url)_, response= _\(response)_, error= _\(error.debugDescription)_, data= _\(data)_")
            
            if let httpResponse = response as? HTTPURLResponse {
                
                logger.debug("url session completion for URL \(safeURLRequest.url): status \(httpResponse.statusCode)")
                
                switch httpResponse.statusCode {
                    case 200, 204:
                        let defaultDataResponse = DefaultDataResponse(request: safeURLRequest, response: httpResponse, data: data, error: error)
                        completion(DefaultURLRequestReturnModel(isSuccess: true, statusCode: httpResponse.statusCode, action: httpResponse.statusCode == 200 ? .success : .successEmpty, dataResponse: defaultDataResponse))
                    default:
                        logger.debug("ON ERROR")
                        completion(DefaultURLRequestReturnModel(isSuccess: false, statusCode: httpResponse.statusCode, action: httpResponse.statusCode == 401 ? .authError : .failure, dataResponse: nil))
                }
            } else {
                // This is Trigged in the error logs
                logger.debug("url session completion for URL \(safeURLRequest.url): response = \(response) __ can't be cast to HTTPURLResponse")
                if NetworkManager.isConnectedToInternet() { logger.networkNilEvent() }
                completion(DefaultURLRequestReturnModel(isSuccess: false, statusCode: ErrorCodes.noResponseError.rawValue, action: .failure, dataResponse: nil))
            }
            
            hasReturned = true
            
        })

        task.resume()
        
    }

来自问题设备的控制台日志:

调试:safeURLRequest.url可选的 url 会话完成 ( https://cpht.auth0.com/oauth/ro,响应 = nil,错误 = _Optional(错误域 = kCFErrorDomainCFNetwork 代码 = 303 “(空)” UserInfo = {_NSURLErrorFailingURLSessionTaskErrorKey =LocalDataTask .<9>, _kCFStreamErrorDomainKey=4, NSErrorPeerAddressKey=<CFData 0x28375a080 [0x1f9151860]>{length = 16, capacity = 16, bytes = 0x100201bb6810b8f80000000000000000}, _kCFStreamErrorCodeKey=-2205, NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<9>" ) }), data= nil调试:URL 可选的 url 会话完成(https://cpht.auth0.com/oauth/ro):response = nil __ 不能转换为 HTTPURLResponse

来自问题设备的 Firebase Analytics 日志:

2021-08-12 16:59:51.615734-0500 MyAppName[4586:1910198] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 未能找到流 1090aae88 2021-08-12 16:59:51.615848-050101988:1 ] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 1090aae88 2021-08-12 16:59:51.624933-0500 MyAppName[4586:1910198] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 1820 找不到流1aae -08-12 16:59:51.625051-0500 MyAppName[4586:1910198] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 1090aae88 2021-08-12 16:59:51.625570-05101986: [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 1090aae88 2021-08-12 16:59:51.625716-0500 MyAppName[4586:1910198] [connection] nw_endpoint_handler_set_adaptive_read_handler [C14 IP:443 就绪通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 注销 read_timeout 通知失败 2021-08-12 16:59:51.625773-0500 MyAppName[4586:1910198] [连接] nw_endpoint_handler_set_adaptive_write_handler [C14 IP:443 就绪通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 注销 write_timeout 通知失败 2021-08-12 16:59:51.625828-0500 MyAppName[4586: 1910198] [connection] nw_endpoint_handler_set_keepalive_handler [C14 IP:443 就绪通道流(已满足(路径已满足),可行,接口:en0,ipv4,dns)] 注销 keepalive 通知失败 2021-08-12 16:59:51.626028- 0500 MyAppName[4586:1910198] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 1090aae88 2021-08-12 16:59:51.626859-0500 MyAppName[4586:1910198] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 10909f7c8 2021-08-12 16:59:51.627061-0500 MyAppName[4586:1910198] [connection] nw_endpoint_handler_set_adaptive_read_handler [C13.2.2.2.1.11.627061-0500] (满足(路径满足),可行,接口:en0,ipv4,dns)] 取消注册 read_timeout 通知失败 2021-08-12 16:59:51.627118-0500 MyAppName[4586:1910198] [connection] nw_endpoint_handler_set_adaptive_write_handler [C13.2.1 IP:443 就绪通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 注销 write_timeout 通知失败 2021-08-12 16:59:51.627257-0500 MyAppName[4586:1910198] [连接] nw_endpoint_handler_set_keepalive_handler [C13.2.1 IP:443 就绪通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 注销keepalive 通知失败 2021-08-12 16:59:51.641425-0500 MyAppName[4586:1909925] [] nw_protocol_instance_access_flow_state [C13.2.1:2] 找不到流 1090aae88 2021-08-12 16:59: 51.647736-0500 MyAppName[4586:1909925] 任务。<9> HTTP 加载失败,529/0 字节(错误代码:303 [4:-2205])2021-08-12 16:59:51.648181-0500 MyAppName[4586: 1909923] 任务 .<9> 以错误结束 [303] 错误域 = kCFErrorDomainCFNetwork 代码 = 303 "(null)" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<9>, _kCFStreamErrorDomainKey=4, NSErrorPeerAddressKey=<CFData 0x28375a080 [0x1f9151860]>{长度 = 16,容量 = 16,字节 = 0x100201bb6810b8f80000000000000000},_kCFStreamErrorCodeKey=-2205,_NSURLErrorRelatedURLSessionTaskErrorKey=(“LocalDataTask .<9>”)} 2021-08-12 16:59:51。648326-0500 MyAppName[4586:1909925] [connection] nw_endpoint_handler_unregister_context [C13.2.1 IP:443 失败的通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 释放流表后无法取消注册2021-08-12 16:59:51.648393-0500 MyAppName[4586:1909925] [h3connection] 0x1099d1a18 13 因对等错误 258 关闭 2021-08-12 16:59:51.648500-0500 MyAppName[4586:1909925] [C13.2.1 IP:443 failed channel-flow (satisfied (Path is compatible), 可行, interface: en0, ipv4, dns)] 流表释放后无法发送 2021-08-12 16:59:51.648625-0500 MyAppName [4586:1909925] [连接] nw_write_request_report [C13] 发送失败,出现错误“套接字未连接”443 失败的通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 释放流表后无法取消注册 2021-08-12 16:59:51.648393-0500 MyAppName[4586:1909925] [ h3connection] 0x1099d1a18 13 因对等错误 258 关闭 2021-08-12 16:59:51.648500-0500 MyAppName[4586:1909925] [connection] nw_endpoint_handler_add_write_request [C13.2.1 IP:443 通道流失败(满足(满足路径),可行,接口:en0,ipv4,dns)] 流表释放后无法发送 2021-08-12 16:59:51.648625-0500 MyAppName[4586:1909925] [connection] nw_write_request_report [C13] 发送失败,错误为“Socket is未连接”443 失败的通道流(满足(满足路径),可行,接口:en0,ipv4,dns)] 释放流表后无法取消注册 2021-08-12 16:59:51.648393-0500 MyAppName[4586:1909925] [ h3connection] 0x1099d1a18 13 因对等错误 258 关闭 2021-08-12 16:59:51.648500-0500 MyAppName[4586:1909925] [connection] nw_endpoint_handler_add_write_request [C13.2.1 IP:443 通道流失败(满足(满足路径),可行,接口:en0,ipv4,dns)] 流表释放后无法发送 2021-08-12 16:59:51.648625-0500 MyAppName[4586:1909925] [connection] nw_write_request_report [C13] 发送失败,错误为“Socket is未连接”1909925] [h3connection] 0x1099d1a18 13 因对等错误 258 关闭 2021-08-12 16:59:51.648500-0500 MyAppName[4586:1909925] [connection] nw_endpoint_handler_add_write_request [C13.2.1 IP:443 失败的通道流(满足满意),可行,接口:en0,ipv4,dns)]释放流表后无法发送2021-08-12 16:59:51.648625-0500 MyAppName [4586:1909925] [connection] nw_write_request_report [C13]发送失败并出现错误“套接字未连接”1909925] [h3connection] 0x1099d1a18 13 因对等错误 258 关闭 2021-08-12 16:59:51.648500-0500 MyAppName[4586:1909925] [connection] nw_endpoint_handler_add_write_request [C13.2.1 IP:443 失败的通道流(满足满意),可行,接口:en0,ipv4,dns)]释放流表后无法发送2021-08-12 16:59:51.648625-0500 MyAppName [4586:1909925] [connection] nw_write_request_report [C13]发送失败并出现错误“套接字未连接”1909925] [连接] nw_write_request_report [C13] 发送失败,出现错误“套接字未连接”1909925] [连接] nw_write_request_report [C13] 发送失败,出现错误“套接字未连接”

感谢您对解决此问题的任何想法!

标签: swiftauth0urlsessiongeneral-network-error

解决方案


我们遇到了与您描述的相同的问题。在我们的例子中,我们的自定义请求标头之一超出了网络服务器的最大标头大小限制。Nginx 的最大标头大小约为 8kb,如果超出此限制,将向客户端返回 413 错误。无论出于何种原因,ios 应用程序都不会解析此响应并引发 303 错误。在我们将 http2_max_header_size 增加到 32kb 后,它就起作用了。


推荐阅读