У меня есть следующая функция для выполнения запроса URL:
final class ServiceManagerImpl: ServiceManager, ObservableObject {
private let session = URLSession.shared
func performRequest<T>(_ request: T) -> AnyPublisher<String?, APIError> where T : Request {
session.dataTaskPublisher(for: self.urlRequest(request))
.tryMap { data, response in
try self.validateResponse(response)
return String(data: data, encoding: .utf8)
}
.mapError { error in
return self.transformError(error)
}
.eraseToAnyPublisher()
}
}
Имея эти 2 следующие функции, теперь я могу вызывать нужные запросы из соответствующих ViewModel :
final class AuditServiceImpl: AuditService {
private let serviceManager: ServiceManager = ServiceManagerImpl()
func emptyAction() -> AnyPublisher<String?, APIError> {
let request = AuditRequest(act: "", nonce: String.randomNumberGenerator)
return serviceManager.performRequest(request)
}
func burbleAction(offset: Int) -> AnyPublisher<String?, APIError> {
let request = AuditRequest(act: "burble", nonce: String.randomNumberGenerator, offset: offset)
return serviceManager.performRequest(request)
}
}
final class AuditViewModel: ObservableObject {
@Published var auditLog: String = ""
private let auditService: AuditService = AuditServiceImpl()
init() {
let timer = Timer(timeInterval: 5, repeats: true) { _ in
self.getBurbles()
}
RunLoop.main.add(timer, forMode: .common)
}
func getBurbles() {
auditService.emptyAction()
.flatMap { [unowned self] offset -> AnyPublisher<String?, APIError> in
let currentOffset = Int(offset?.unwrapped ?? "") ?? 0
return self.auditService.burbleAction(offset: currentOffset)
}
.receive(on: RunLoop.main)
.sink(receiveCompletion: { [unowned self] completion in
print(completion)
}, receiveValue: { [weak self] burbles in
self?.auditLog = burbles!
})
.store(in: &cancellableSet)
}
}
Все хорошо, когда я впервые использую self.getBurbles()
. Тем не менее, для следующих вызовов print(completion)
показывает finished
, а код не выполняет self?.auditLog = burbles!
Я не знаю, как я могу перебрать функцию getBurbles()
и получить ответс разными интервалами.
Редактировать
Весь процесс в двух словах:
- Я вызываю
getBurbles()
из инициализатора класса getBurbles()
вызывает 2 вложенные функции: emptyAction()
и burbleAction(offset: Int)
- Эти две функции генерируют разные запросы и вызывают
performRequest<T>(_ request: T)
- Наконец, я устанавливаю ответ в
auditLog
переменная и показать его на SwiftUI слое