Brand new to Swift and iOS development (started learning this weekend).
I am trying to make a generic HTTP Client wrapper for signing and sending requests to API Gateway (AWS) using SotoSignerV4
and AsyncHTTPClient
. I have followed an excellent guide to get some boiler plate ideas on how to achieve this, but when I go to test this approach in a unit test (XCTestCase
), it does not work at all as expected. It seems as if the request isn't even executed (in fact I know it isn't, because I can check the logs on my Lambda application - the request isn't reaching lambda).
Here's the bulk of my code:
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!;
}
The failure is on the entity
assignment line, stating,
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file MyFramework/AWSSignedClient.swift, line 158
The optional it can't unwrap is the response string, meaning that the code in the .success
case was never hit. I have tried testing the error case as well by capturing a string representing the error, and not even that works. It's as if the callback associated with whenComplete
is completely skipped, the request never being made. I have also tried using URLSession.shared.dataTask
, with the same results - no request is ever made.
Please help! What am I doing wrong with the HTTPClient
?