Rao*_*oul 0 upload request swift alamofire
我想使用 RequestAdapter 和 RequestRetrier 协议,所以我创建了自己的所谓 AuthenticationHandler 类,它实现了这两种协议。我这样做是因为刷新令牌可能已过期,因此此机制派上用场。RequestAdapter 协议方法adapt会被调用,但是should RequestRetrier 协议方法不会被调用。我有一个单独的类来执行实际请求:
class TestRequest {
var authHandler: AuthenticationHandler?
func executeRequest() {
// For testing purposes a false access token is passed
self.authHandler = AuthenticationHandler(accessToken: "some_default_token")
let sessionManager = SessionManager()
sessionManager.adapter = authHandler
sessionManager.retrier = authHandler
var loginModel : LoginMessage = LoginMessage.init()
loginModel.username = "someUserName"
loginModel.password = "WrongPassword"
do {
let binaryData = try loginModel.serializedData()
// Create a file with this binary data in order to use it as part of the multipart formdata
guard let fileURL = createFileFrom(data: binaryData) else {
print("Error creating file")
return
}
// Note: custom headers have been set in the AuthenticationHandler
sessionManager.upload(multipartFormData: { multipartFormData in
multipartFormData.append(fileURL, withName: "content")
},
to: K.endpointLogin) { (encodingResult) in
switch encodingResult{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Encoding result success...")
print("Statuscode: \(response.response?.statusCode)")
print(response)
}
case .failure(let encodingError):
print("Failure: \(encodingError)")
}
}
} catch {
print(error)
}
}
Run Code Online (Sandbox Code Playgroud)
我已按照此处文档中的示例进行操作
我读过几篇以前的帖子,说这与保留 sessionManager 有关。但我认为这也涵盖了。我的身份验证处理程序如下所示:
class AuthenticationHandler: RequestAdapter, RequestRetrier {
private typealias RefreshCompletion = (_ succeeded: Bool, _ accessToken: String?) -> Void
private let sessionManager: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
return SessionManager(configuration: configuration)
}()
private let lock = NSLock()
private var accessToken: String
private var isRefreshing = false
private var requestsToRetry: [RequestRetryCompletion] = []
init(accessToken: String) {
self.accessToken = accessToken
}
// MARK: - RequestAdapter protocol method
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
var urlRequest = urlRequest
if let urlString = urlRequest.url?.absoluteString, urlString.hasPrefix(K.SERVER_URL) {
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
urlRequest.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
}
return urlRequest
}
// MARK: - RequestRetrier protocol method
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
lock.lock() ; defer { lock.unlock() }
}
}
Run Code Online (Sandbox Code Playgroud)
我的配置如下:
我在这里做错了什么?为什么请求被取消并且没有调用should方法?任何帮助是极大的赞赏。
您的核心问题是您的SessionManager实例正在被deinit编辑,这会取消任何正在进行的任务。您应该将它保留在单例或类似的东西中,这将解决另一个问题,即为SessionManager每个请求使用一个 new 的问题,这是一种反模式。
| 归档时间: |
|
| 查看次数: |
1529 次 |
| 最近记录: |