带有 URLSession 的 PromiseKit
PromiseKit w/ URLSession
如果我的远程服务 returns a 401
.
,我正在尝试添加针对响应状态代码的检查
我正在尝试使用 PromiseKit URLSession
扩展。
假设我有一些基本的东西,比如
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=].data)
}
我想做的是添加一个针对响应状态代码的检查,所以我可能会抛出一个错误并执行一些进一步的步骤。
类似
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=11=])
}.catch { error in
// check the error thrown here and do something
}
这有一个例外
Cannot convert return expression of type 'PMKFinalizer' to return type
'Promise'
是否可以引入类似 retryWhen
的东西,这将使我能够捕获错误并进行检查?
因为 .catch
没有 return 任何东西,但你想要 return 一个 Promise<T>
所以你必须在这里删除 .catch
作为,
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=])
}
.catch
将由被调用者执行。
或者,您可能看起来像,
func test() -> Promise<Any> {
return firstly(execute: { () -> Promise<String> in
return .value("bhai")
}).map({ string -> Promise<Double?> in
return .value(0.1)
}).compactMap({ double -> NSError in
return NSError(domain: "", code: 0, userInfo: nil)
})
}
我试图实现与您所做的完全相同的事情,我认为您正在寻找的 retrywhen
功能称为 recover
,您可以在 GitHub PromiseKit Document
- 请注意以下代码没有经过编辑器,可能无法编译,我只是用这个来演示流程。
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=])
}
// above is a copy of your code
.recover { error in // instead of .catch, use .recover here
guard let err = error as? TokenProviderError,
err == .unauthorized
else { throw error } // we only care 401 error here, other error will be handled in caller's .catch
// in my case, the reason for 401 error is due to an expired access token, so I will try to use refresh token to get a valid access token and make the same request again
return firstly {
loginWithRefreshToken(token: myRefreshToken)
}.then { loginRes -> Promise<(data: Data, response: URLResponse)> in
// loginRes contains new access token, set it to request "Authorization" header, and make the same request again
request.setValue(loginRes.accessToken, forHTTPHeaderField: "Authorization")
return URLSession.shared.dataTask(.promise, with: request)
}.map { session -> Data in
return session.data
}.compactMap { data -> Promise<T> in
try JSONDecoder().decode(T.self, from: data)
}
}
也许回答的有点晚了,但我希望它能帮助一些像我一样刚接触 PromiseKit 的编码人员。
如果我的远程服务 returns a 401
.
我正在尝试使用 PromiseKit URLSession
扩展。
假设我有一些基本的东西,比如
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=].data)
}
我想做的是添加一个针对响应状态代码的检查,所以我可能会抛出一个错误并执行一些进一步的步骤。
类似
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=11=])
}.catch { error in
// check the error thrown here and do something
}
这有一个例外
Cannot convert return expression of type 'PMKFinalizer' to return type 'Promise'
是否可以引入类似 retryWhen
的东西,这将使我能够捕获错误并进行检查?
因为 .catch
没有 return 任何东西,但你想要 return 一个 Promise<T>
所以你必须在这里删除 .catch
作为,
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=])
}
.catch
将由被调用者执行。
或者,您可能看起来像,
func test() -> Promise<Any> {
return firstly(execute: { () -> Promise<String> in
return .value("bhai")
}).map({ string -> Promise<Double?> in
return .value(0.1)
}).compactMap({ double -> NSError in
return NSError(domain: "", code: 0, userInfo: nil)
})
}
我试图实现与您所做的完全相同的事情,我认为您正在寻找的 retrywhen
功能称为 recover
,您可以在 GitHub PromiseKit Document
- 请注意以下代码没有经过编辑器,可能无法编译,我只是用这个来演示流程。
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: [=10=])
}
// above is a copy of your code
.recover { error in // instead of .catch, use .recover here
guard let err = error as? TokenProviderError,
err == .unauthorized
else { throw error } // we only care 401 error here, other error will be handled in caller's .catch
// in my case, the reason for 401 error is due to an expired access token, so I will try to use refresh token to get a valid access token and make the same request again
return firstly {
loginWithRefreshToken(token: myRefreshToken)
}.then { loginRes -> Promise<(data: Data, response: URLResponse)> in
// loginRes contains new access token, set it to request "Authorization" header, and make the same request again
request.setValue(loginRes.accessToken, forHTTPHeaderField: "Authorization")
return URLSession.shared.dataTask(.promise, with: request)
}.map { session -> Data in
return session.data
}.compactMap { data -> Promise<T> in
try JSONDecoder().decode(T.self, from: data)
}
}
也许回答的有点晚了,但我希望它能帮助一些像我一样刚接触 PromiseKit 的编码人员。