如何使用 Combine in Swift 读取 JSON 错误对象的 属性 值?
How do I read the property values of a JSON error object using Combine in Swift?
我的所有 API 端点 return 在 Postman 中看起来像这样的响应:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing authentication"
}
我想做的是发出请求,并访问 Swift 中的这些属性。在某些情况下,我会在应用程序的前面使用错误消息 属性 的值。这将由 statusCode returned.
决定
我现在有的是:
private var cancellable: AnyCancellable?
let url = URL(string: "http://abc336699.com/create")
self.cancellable = URLSession.shared.dataTaskPublisher(for: url!)
.map { [=14=].data }
在此之前,我尝试了 tryMap,但它 returned 的错误类型并没有给我想要的灵活性。然后我继续尝试 Almofire,但它似乎对我想做的事来说太过分了。
我想检查 return 收到的响应中的内容,但出现以下错误:
Cannot assign value of type 'Publishers.Map<URLSession.DataTaskPublisher, Data>' to type 'AnyCancellable'
我想简单地访问我的响应错误,这样我就可以使用 combine 在整个应用程序中集成 API。
我不确定您将从哪里获取数据,因为在 JSON 响应中没有数据密钥。在编写下面的代码之前,我的理解是您想从提到的 JSON 响应中检查 error
和 statusCode
,然后继续您的业务逻辑。下面的代码是为了让您对我们如何做到这一点有一个模糊的了解。
enum CustomError: Error {
case custom(_ error: String)
case unknownStatusCode
case errorOccurred
}
let url = URL(string: "http://abc336699.com/create")
func load() -> AnyPublisher<Data,CustomError> {
URLSession.shared.dataTaskPublisher(for: url!)
.map(\.data)
.tryMap { (data) -> Data in
let genericModel = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject]
if let statusCode = genericModel?["statusCode"] as? String {
switch statusCode {
case "200":
guard let data = genericModel?["message"] as? Data else {
throw CustomError.custom("Parsing error")
}
return data
default:
if let error = genericModel?["error"] as? String {
throw CustomError.custom(error)
} else {
throw CustomError.unknownError
}
}
}
throw CustomError.errorOccurred
}
.decode(type: YourCustomDecodableModel.self, decoder: JSONDecoder())
.mapError({ [=10=] as? CustomError ?? CustomError.errorOccurred })
.eraseToAnyPublisher()
}
我的所有 API 端点 return 在 Postman 中看起来像这样的响应:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing authentication"
}
我想做的是发出请求,并访问 Swift 中的这些属性。在某些情况下,我会在应用程序的前面使用错误消息 属性 的值。这将由 statusCode returned.
决定我现在有的是:
private var cancellable: AnyCancellable?
let url = URL(string: "http://abc336699.com/create")
self.cancellable = URLSession.shared.dataTaskPublisher(for: url!)
.map { [=14=].data }
在此之前,我尝试了 tryMap,但它 returned 的错误类型并没有给我想要的灵活性。然后我继续尝试 Almofire,但它似乎对我想做的事来说太过分了。
我想检查 return 收到的响应中的内容,但出现以下错误:
Cannot assign value of type 'Publishers.Map<URLSession.DataTaskPublisher, Data>' to type 'AnyCancellable'
我想简单地访问我的响应错误,这样我就可以使用 combine 在整个应用程序中集成 API。
我不确定您将从哪里获取数据,因为在 JSON 响应中没有数据密钥。在编写下面的代码之前,我的理解是您想从提到的 JSON 响应中检查 error
和 statusCode
,然后继续您的业务逻辑。下面的代码是为了让您对我们如何做到这一点有一个模糊的了解。
enum CustomError: Error {
case custom(_ error: String)
case unknownStatusCode
case errorOccurred
}
let url = URL(string: "http://abc336699.com/create")
func load() -> AnyPublisher<Data,CustomError> {
URLSession.shared.dataTaskPublisher(for: url!)
.map(\.data)
.tryMap { (data) -> Data in
let genericModel = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject]
if let statusCode = genericModel?["statusCode"] as? String {
switch statusCode {
case "200":
guard let data = genericModel?["message"] as? Data else {
throw CustomError.custom("Parsing error")
}
return data
default:
if let error = genericModel?["error"] as? String {
throw CustomError.custom(error)
} else {
throw CustomError.unknownError
}
}
}
throw CustomError.errorOccurred
}
.decode(type: YourCustomDecodableModel.self, decoder: JSONDecoder())
.mapError({ [=10=] as? CustomError ?? CustomError.errorOccurred })
.eraseToAnyPublisher()
}