Чтобы сделать некоторые другие вызовы, нужен токен доступа, поэтому идея состоит в том, чтобы получить токен доступа и, как только он будет получен, затем использовать его для следующего вызова.
Вот фактический вызов, но создание запроса игнорируется:
@available(iOS 13.0, *)
func postToken(session: URLSession = URLSession.shared) throws -> URLSession.DataTaskPublisher {
let request = try buildTokenRequest()
return session.dataTaskPublisher(for: request)
}
@available(iOS 13.0, *)
public func fetchToken() -> AnyPublisher<AccessToken, Error> {
return try! postToken()
.tryMap{ try self.validate($0.data, $0.response) }
.decode(type: AccessToken.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
}
Проверка довольно проста, но может быть полезна:
@available(iOS 13.0, *)
func validate(_ data: Data, _ response: URLResponse) throws -> Data {
guard let httpResponse = response as? HTTPURLResponse else {
throw APIError.invalidResponse
}
guard (200..<300).contains(httpResponse.statusCode) else {
throw APIError.statusCode(httpResponse.statusCode)
}
return data
}
В моем тесте я делаю это, и если я могу получить утверждениячтобы работать в моем тесте, тогда я думаю, что в основном скопировать этот код, где я сделаю следующий сервисный вызов.
@available(iOS 13.0, *)
func testRetrieveToken() {
let cancellableLogin = AccessTokenService().fetchToken()
.sink(receiveCompletion: { (completion) in
switch completion {
case .failure(let error):
print(error)
case .finished:
print("BEARER TOKEN")
}
}, receiveValue: { response in
print(response)
XCTAssertNotNil(response)
})
}
Моя проблема в том, что когда я запускаю приложение, я не получаю ошибок, оно простоне выводит никаких результатов, поскольку он заканчивает работу.В основном мне нужно иметь возможность сделать паузу и дождаться завершения запроса, прежде чем я попытаюсь сделать утверждение, поэтому представьте, что оно синхронное.
Это результаты моего выполнения:
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' started.
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' passed (0.004 seconds).
Это должно было занять около 1 секунды, если бы он ожидал генерации токена.
** Обновление **
Я изменил тест следующим образом, так что я думаю, что решение можетбыть может использовать PassThroughSubject
возможно.Это может потребовать времени, поэтому я вызываю его при запуске приложения, затем оно должно вернуться до того, как будет вызван первый веб-сервис, или я жду, пока получу факт, что оно установлено.
let expectation = self.expectation(description: "Scaling")
let cancellableLogin = AccessTokenService().fetchToken()
.sink(receiveCompletion: { (completion) in
switch completion {
case .failure(let error):
print(error)
expectation.fulfill()
XCTFail()
case .finished:
print("BEARER TOKEN")
}
}, receiveValue: { response in
print(response)
XCTAssertNotNil(response)
XCTAssertEqual(response.token_type, "Bearer")
expectation.fulfill()
})
waitForExpectations(timeout: 60, handler: nil)