Swift Alamofire请求已取消(-999)
我想利用RequestAdapter和RequestRetrier协议,所以我创建了自己的AuthenticationHandler类,它实现了这两个协议。我这样做是因为刷新令牌可能会过期,所以这种机制很方便。 确实调用了RequestAdapter协议方法adapt,但是应该RequestRetrier协议方法没有调用。我有一个单独的类来处理实际的请求:Swift Alamofire请求已取消(-999),swift,upload,request,alamofire,Swift,Upload,Request,Alamofire,我想利用RequestAdapter和RequestRetrier协议,所以我创建了自己的AuthenticationHandler类,它实现了这两个协议。我这样做是因为刷新令牌可能会过期,所以这种机制很方便。 确实调用了RequestAdapter协议方法adapt,但是应该RequestRetrier协议方法没有调用。我有一个单独的类来处理实际的请求: class TestRequest { var authHandler: AuthenticationHandler? func exe
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)
}
}
我遵循了文档中的示例
我以前读过几篇文章,说这与保留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() }
}
}
我的配置如下:
- 阿拉莫菲尔版本:4.7.2
- Xcode版本:9.4.1
- Swift版本:4
非常感谢您的帮助。您的核心问题是您的
会话管理器
实例正在被删除,这将取消任何正在进行的任务。你应该把它放在一个单例或类似的东西中,这将解决另一个问题,即为每个请求使用一个新的会话管理器,这是一个反模式。你的核心问题是你的会话管理器
实例正在被删除,这将取消任何正在进行的任务。你应该把它放在一个单独的或类似的地方,这将解决另一个问题,即为每个请求使用一个新的会话管理器,这是一种反模式。这解决了问题;创建一个单独的类,其中包含一个静态会话管理器,并在TestRequest类中使用它。然后可以删除AuthenticationHandler中的sessionManager实例。但是仍然不会调用should方法。encodingResult的值为success,但响应的状态代码为401。我遗漏了什么?噢,哇,链接validate方法确实会触发回调。因此,如果编码结果成功,我需要执行以下操作:case.success(让我们上传,,u):upload.validate().responseJSON{response in…对response做点什么…
这解决了问题;创建了一个单独的类,其中包含一个静态的SessionManager
,并在TestRequest类中使用它。然后可以删除AuthenticationHandler中的SessionManager实例。但是仍然不会调用should方法。编码结果已更改值为success,但响应的状态代码为401。我在这里缺少什么?哇,链接validate方法会触发回调。因此,如果编码结果成功,我需要执行以下操作:case.success(让我们上载,…):upload.validate().responseJSON{response in…处理响应…