使用Swift和Combine wait从webservice调用获取结果以进行下一次调用
为了进行一些其他呼叫,需要一个访问令牌,因此我们的想法是获取访问令牌,一旦接收到,然后使用它进行下一次呼叫 这是实际调用,但生成请求被忽略:使用Swift和Combine wait从webservice调用获取结果以进行下一次调用,swift,networking,combine,swift5.1,Swift,Networking,Combine,Swift5.1,为了进行一些其他呼叫,需要一个访问令牌,因此我们的想法是获取访问令牌,一旦接收到,然后使用它进行下一次呼叫 这是实际调用,但生成请求被忽略: @available(iOS 13.0, *) func postToken(session: URLSession = URLSession.shared) throws -> URLSession.DataTaskPublisher { let request = try buildTokenRequest() return se
@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()
}
我的问题是,当我运行应用程序时,我没有收到任何错误,它只是在运行结束时不打印任何结果。我基本上需要能够暂停并等待请求完成,然后再尝试进行断言,所以假设它是同步的
这是我跑步的结果:
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' started.
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' passed (0.004 seconds).
如果等待令牌生成,则应该花费大约1秒的时间
**更新**
我将测试更改为如下所示,因此我认为解决方案可能是使用PassThroughSubject
。它可能需要计时,所以我在应用程序启动时调用它,然后它应该在调用第一个Web服务之前返回,或者我等待直到我得到它已被设置的事实
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)
检查
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' started.
Test Case '-[AccessTokenServiceTests.AccessTokenServiceTests testRetrieveToken]' passed (0.004 seconds).
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)