Swift 如何取消Alamofire.upload

Swift 如何取消Alamofire.upload,swift,alamofire,Swift,Alamofire,我正在通过Alamofire将图像上传到服务器上。将图像作为多部分数据上传。与Alamofire.request不同,它不返回request对象,我通常使用它来取消请求 但是能够取消像上传这样的消耗性请求是非常合理的。Alamofire中有哪些选项?恐怕您不能,根据Alamofire源代码,upload函数在其所有重载中返回一个请求类型,但在支持多部件数据的重载中除外请参见以下代码: // MARK: MultipartFormData /** Creates an upload reques

我正在通过Alamofire将图像上传到服务器上。将图像作为多部分数据上传。与
Alamofire.request
不同,它不返回
request
对象,我通常使用它来取消请求


但是能够取消像上传这样的消耗性请求是非常合理的。Alamofire中有哪些选项?

恐怕您不能,根据Alamofire源代码,
upload
函数在其所有重载中返回一个
请求
类型,但在支持多部件数据的重载中除外请参见以下代码:

// MARK: MultipartFormData

/**
Creates an upload request using the shared manager instance for the specified method and URL string.

- parameter method:                  The HTTP method.
- parameter URLString:               The URL string.
- parameter headers: The HTTP headers. `nil` by default.
- parameter multipartFormData:       The closure used to append body parts to the `MultipartFormData`.
- parameter encodingMemoryThreshold: The encoding memory threshold in bytes. `MultipartFormDataEncodingMemoryThreshold` 
                                by default.
- parameter encodingCompletion:      The closure called when the `MultipartFormData` encoding is complete.
*/
public func upload(
  method: Method,
  URLString: URLStringConvertible,
  headers: [String: String]? = nil,
  multipartFormData: MultipartFormData -> Void,
  encodingMemoryThreshold: UInt64 = Manager.MultipartFormDataEncodingMemoryThreshold,
  encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?)
{
   return Manager.sharedInstance.upload(
      method,
      URLString,
      headers: headers,
      multipartFormData: multipartFormData,
      encodingMemoryThreshold: encodingMemoryThreshold,
      encodingCompletion: encodingCompletion
   )
}

/**
Creates an upload request using the shared manager instance for the specified method and URL string.

- parameter URLRequest:              The URL request.
- parameter multipartFormData:       The closure used to append body parts to the `MultipartFormData`.
- parameter encodingMemoryThreshold: The encoding memory threshold in bytes. `MultipartFormDataEncodingMemoryThreshold`
                                by default.
- parameter encodingCompletion:      The closure called when the `MultipartFormData` encoding is complete.
*/
public func upload(
  URLRequest: URLRequestConvertible,
  multipartFormData: MultipartFormData -> Void,
  encodingMemoryThreshold: UInt64 =    Manager.MultipartFormDataEncodingMemoryThreshold,
  encodingCompletion: (Manager.MultipartFormDataEncodingResult -> Void)?)
{
   return Manager.sharedInstance.upload(
      URLRequest,
      multipartFormData: multipartFormData,
      encodingMemoryThreshold: encodingMemoryThreshold,
      encodingCompletion: encodingCompletion
   )
}
在编写客户端代码时,建议在表单包含任何
元素时使用
多部分/表单数据

因此,如果您只想将图像上载到服务器,您可以使用另一个
upload
函数重载,该函数返回
请求
对象,您可以像文档中建议的那样取消它:

let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
ler request =Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
// request.cancel()
我希望这对您有所帮助。

使用Alamofire自述文件中的示例:

Alamofire.upload(
    .POST,
    "https://httpbin.org/post",
    multipartFormData: { multipartFormData in
        multipartFormData.appendBodyPart(fileURL: unicornImageURL, name: "unicorn")
        multipartFormData.appendBodyPart(fileURL: rainbowImageURL, name: "rainbow")
    },
    encodingCompletion: { encodingResult in
        switch encodingResult {
        case .Success(let upload, _, _):
            upload.responseJSON { response in
                debugPrint(response)
            }
        case .Failure(let encodingError):
            print(encodingError)
        }
    }
)
这里,
upload.responseJSON
返回一个
请求
,该请求应允许您将其分配给以后取消的对象。例如:

let request = upload.responseJSON {  ...

...

request.cancel()

可以准备一个闭包,并将请求从“encodingCompletion”中转移出去

在我的例子中,我在API类中创建了“sessionManager”实例,并将配置分配给Alamofire的会话管理器

    var sessionManager: SessionManager!

    // Setup request manager
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForResource = TimeInterval(15.0)
    configuration.timeoutIntervalForRequest = TimeInterval(15.0)
    sessionManager = Alamofire.SessionManager(configuration: configuration)


    sessionManager.upload(multipartFormData: { multipartFormData in

        // AppendMultipart parts
        multipartFormData.append(metadataBodyPart, withName: PartName.Metadata, mimeType: MimeType.MultiPart)
        multipartFormData.append(imageDataBodyPart, withName: PartName.Photo, mimeType: MimeType.ImageJPG)

    } // ... rest of the code
然后我可以创建一个方法来取消任何当前的请求类型。注意这里“(u,uploadTasks,u)”您还可以有“dataTasks”和“downloadTasks”,如果您愿意,也可以取消这些任务(dataTasks,uploadTasks,downloadTasks)

您也可以使用如下smth:

func cancel(request: CancelRequestType) {
    sessionManager.session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in
        switch request {
            case .DataTask:
                dataTasks.forEach { $0.cancel() }
                print("- - - Data task was canceled!")
            case .UploadTask:
                uploadTasks.forEach { $0.cancel() }
                print("- - - Upload task was canceled!")
            case .DownloadTask:
                downloadTasks.forEach { $0.cancel() }
                print("- - - Download task was canceled!")
            case .ZeroTask:
                print("- - - Zero tasks was found!")
        }
    }
}
其中“CancelRequestType”是枚举。因此,您可以调用类似于
API.cancel(请求:.UploadTask)


如何在上传中添加参数(Swift 3)?我的应用程序总是在请求时崩溃。cancel(),您是如何成功的?这里有两个问题:1。上传总是挂断在2.03M,然后请求超时;2.无法获取服务器响应数据;
func cancelUploadRequest() {
    sessionManager.session.getTasksWithCompletionHandler { (_, uploadTasks, _) in
        uploadTasks.forEach { $0.cancel() }
    }
}
func cancel(request: CancelRequestType) {
    sessionManager.session.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in
        switch request {
            case .DataTask:
                dataTasks.forEach { $0.cancel() }
                print("- - - Data task was canceled!")
            case .UploadTask:
                uploadTasks.forEach { $0.cancel() }
                print("- - - Upload task was canceled!")
            case .DownloadTask:
                downloadTasks.forEach { $0.cancel() }
                print("- - - Download task was canceled!")
            case .ZeroTask:
                print("- - - Zero tasks was found!")
        }
    }
}
enum CancelRequestType: String {
    case DownloadTask = "DownloadTask"
    case DataTask = "DataTask"
    case UploadTask = "UploadTask"
    case ZeroTask = "Zero"
}