我具有以下功能来执行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()
}
}
具有以下两个功能,我现在可以从对应的 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()
调用2个嵌套函数:getBurbles()
和emptyAction()
burbleAction(offset: Int)
performRequest<T>(_ request: T)
变量,并将其显示在 SwiftUI 层上答案 0 :(得分:1)
这里至少有2个问题。
首先,当for row in range(row_start, row_end+1):
for column in range(column_start, column_end+1):
print(lst[row,column])
错误时,它将不再产生元素。这是一个问题,因为即使内部Publisher
失败,您也想在这里回收发布者并多次调用它。您需要处理Publisher
内部的错误,并确保该错误不会传播到封闭的flatMap
。 (即,您可以返回Publisher
或其他一些Result
或元组,指示您应该显示错误状态。)
第二,enum
几乎肯定不是您想要的,因为它将合并所有api调用并以任意顺序返回它们。如果要取消任何现有请求并仅显示最新结果,则应使用flatMap
,然后使用switchToLatest。