Swift Alamofire请求已取消(-999)

Swift Alamofire请求已取消(-999),swift,upload,request,alamofire,Swift,Upload,Request,Alamofire,我想利用RequestAdapter和RequestRetrier协议,所以我创建了自己的AuthenticationHandler类,它实现了这两个协议。我这样做是因为刷新令牌可能会过期,所以这种机制很方便。 确实调用了RequestAdapter协议方法adapt,但是应该RequestRetrier协议方法没有调用。我有一个单独的类来处理实际的请求: class TestRequest { var authHandler: AuthenticationHandler? func exe

我想利用RequestAdapter和RequestRetrier协议,所以我创建了自己的AuthenticationHandler类,它实现了这两个协议。我这样做是因为刷新令牌可能会过期,所以这种机制很方便。 确实调用了RequestAdapter协议方法adapt,但是应该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)
    }       
}
我遵循了文档中的示例

我以前读过几篇文章,说这与保留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…处理响应…