AsyncHTTPClient 请求不起作用 (Swift iOS)

如何解决AsyncHTTPClient 请求不起作用 (Swift iOS)

全新的 Swift 和 iOS 开发(本周末开始学习)。

我正在尝试使用 sotoSignerV4AsyncHTTPClient 制作一个通用的 HTTP 客户端包装器,用于对 API 网关 (AWS) 进行签名和发送请求。我已经按照 excellent guide 获得了一些关于如何实现这一点的样板想法,但是当我在单元测试 (XCTestCase) 中测试这种方法时,它根本无法按预期工作。似乎请求甚至没有执行(事实上我知道它没有执行,因为我可以检查我的 Lambda 应用程序上的日志 - 请求没有到达 lambda)。

这是我的大部分代码

private func request<TEntity: Codable>(
        type: TEntity.Type,body: Codable? = nil,resource: String,method: HTTPMethod) throws -> TEntity {
    
    // A bunch of AWS Sig4 signing stuff happens here,already tested and working...    
    
    let timeout = HTTPClient.Configuration.Timeout(
        connect: .seconds(30),read: .seconds(30))
    let httpClient: HTTPClient = HTTPClient(
        eventLoopGroupProvider: .createNew,configuration: HTTPClient.Configuration(timeout: timeout))
        
    var entity: TEntity? = nil;
    var responseString: String? = nil;
        
    let request = try! HTTPClient.Request(
        url: processedUrl,method: method,headers: signedHeaders,body: requestPayload)
        
    let future = httpClient.execute(request: request)
           
    future.whenComplete {
          
        result in
        switch result {
        case .success(let response):
            guard let responseBuffer = response.body,response.status == .ok
            else { return }
            let responseBody = Data(buffer: responseBuffer)
            responseString = String(decoding: responseBody,as: UTF8.self)
        case .failure(_):
            return
        }
            
    }
        
    try httpClient.syncShutdown()
        
    entity = try! JSONDecoder().decode(TEntity.self,from: Data(responseString!.utf8));
        
    return entity!;
}

失败在 entity 赋值行,说明,

Fatal error: Unexpectedly found nil while unwrapping an Optional value: file MyFramework/AWSSignedClient.swift,line 158

它无法解包的可选内容是响应字符串,这意味着 .success 案例中的代码从未被命中。我也尝试通过捕获表示错误的字符串来测试错误情况,但即使这样也不起作用。就好像与 whenComplete 关联的回调被完全跳过了,请求永远不会被发出。我也尝试过使用 URLSession.shared.dataTask,结果相同 - 从未提出任何请求。

请帮忙!我在使用 HTTPClient 时做错了什么?

解决方法

您在这里遇到的问题是您希望在调用异步代码时代码同步运行。您调用 future.whenComplete 但之后立即关闭客户端。请求永远没有机会完成。

您可以设置您的函数,使其在请求完成时调用回调(从您的 whenComplete 闭包调用),或者您可以添加一个 future.wait() 等待请求完成后再继续。第一个选项可能更可取,因为第二个选项会在等待响应时停止您正在运行的线程。

或者第三个选项是让函数返回一个 EventLoopFuture<TEntity>

return httpClient.execute(request: request)
    .flatMapThrowing { response in
        guard let responseBuffer = response.body,response.status == .ok
            else { throw Error.requestFailed }
        let responseBody = Data(buffer: responseBuffer)
        return try JSONDecoder().decode(TEntity.self,responseBody)
    }

EventLoopF​​uture https://apple.github.io/swift-nio/docs/current/NIO/Classes/EventLoopFuture.html 的参考文档非常全面,如果您打算与它们进行交互,则值得一读。

如果您选择第一个或第三个选项,您将无法在您的函数中关闭客户端。您需要在确定请求已完成时执行此操作。始终保留一个 HTTPClient 实例可能更容易

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?