ios - 结合不同格式的返回请求响应
问题描述
嘿,我有一个带有 viewModel 的 SwiftUI。当用户点击登录按钮时,我运行该viewModel.registerAccount
功能。
func registerAccount() {
authService.registerAccount(params: params)
.sink { (dataResponse) in
if let error = dataResponse.error {
//
} else {
//
}
}.store(in: &cancellableSet)
}
在这个函数中,我调用了AuthService
我想要保存一些值并更改响应的位置。
class AuthService {
private let apiClient: APIClient = APIClient()
private var guid: String?
func registerAccount(params: [String: Any]) -> AnyPublisher<DataResponse<RegisterAccountResponse, Error>, Never> {
let registerRequest = RegisterAccountRequest(params: params) // (url + method + params + ...)
let apiRequest = apiClient.request(request: registerRequest)
// i would like to read response, save guid
// change response type and return only Error?
return apiRequest
}
}
还有APIClient
定义。
class APIClient {
private let session: Session = Session(configuration: URLSessionConfiguration.default)
func request<T: APIRequest>(request: T) -> AnyPublisher<DataResponse<T.Response, Error>, Never> {
request
.dataRequest(session: session)
.publishDecodable(type: T.Response.self)
.map { response in
response.mapError { error in
return error
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
但这并不能解决我的需求。我想知道是否有办法读取响应AuthService
并返回类型的响应Error?
。
有一次我想到了这一点,也列出了,AuthService
但我想更改响应并只发送一个对象 format Error?
。
func registerAccount(params: [String: Any]) ->
AnyPublisher<DataResponse<RegisterAccountResponse, Error>, Never> {
let registerRequest = RegisterAccountRequest(params: params)
let apiRequest = apiClient.request(request: registerRequest)
apiRequest.sink { dataResponse in
if let guid = dataResponse.value?.guidFlow {
self.guid = guid
}
}.store(in: &cancellableSet)
return apiRequest
}
我也想过这个,但我正在寻找一种更结合/SwiftUI 的方法。
func registerAccount(params: [String: Any], completion: @escaping (Error?) -> Void) {
let registerRequest = RegisterAccountRequest(params: params)
let apiRequest = apiClient.request(request: registerRequest)
apiRequest.sink { dataResponse in
if let value = dataResponse.value {
// save guid and return nill or backend error (format Error)
} else {
completion(dataResponse.error)
}
}.store(in: &cancellableSet)
}
解决方案
我发现奇怪的第一件事是您APIClient.request
似乎正在返回一个AnyPublisher<DataResponse<RegisterAccountResponse, Error>, Never>
. 我希望它返回一个AnyPublisher<RegisterAccountResponse, Error>
-- 一个报告响应或错误的流。
如果你有能力改变APIClient
我会改变的。如果您无法控制该代码,我们可以使用tryMap
.
看起来您确实希望返回一个发布单个 GUID 或错误的发布者registerAccount
。AuthService
这可能看起来像这样:
class AuthService {
private let apiClient = APIClient()
func registerAccount(params: [String: Any]) -> AnyPublisher<UUID?, Error> {
let registerRequest = RegisterAccountRequest(params: params)
return apiClient.request(request: registerRequest)
.tryMap { (response: DataResponse<RegisterAccountResponse, Error>) throws -> UUID? in
switch response {
case .success(let registerAccountResponse) :
return registerAccountResponse.value?.guidFlow
case .failure(let error) :
throw error
}
}.eraseToAnyPublisher()
}
}
推荐阅读
- java - 文档中的嵌套表格为 pdf
- reactjs - 使用 create-react-app 和 Typescript 时如何在构建时加载 .md 文件?
- docker - 使用匿名卷防止 Docker 容器在本地创建文件夹不起作用
- python - 如何在我的操作系统中正确安装 Python
- javascript - 在段落中创建按钮
- android - 以编程方式更改 Seekbar 颜色
- javascript - SWR 未从 fetcher 填充数据,卡在加载中
- javascript - 第二行内容第一个字符的位置可编辑
- c - 如何在代码块中将数学库链接到我的编译器?
- c# - 接口c#中的具体方法