如何取消Alamofire.upload

时间:2016-01-19 23:19:38

标签: swift alamofire

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

但是能够取消像上传这样的消费请求是非常合理的。在Alamofire有什么选择?

4 个答案:

答案 0 :(得分:13)

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

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会返回Request,这样您就可以将其分配给稍后要取消的内容。例如:

let request = upload.responseJSON {  ...

...

request.cancel()

答案 1 :(得分:1)

我担心你不能,根据Alamofire源代码,upload函数在其所有重载中都会返回Request类型除了之外的那些支持 MultipartFormData 请参阅以下代码:

// 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
   )
}

建议您在编写客户端代码时,在表单包含任何multipart/form-data元素时使用<input type="file">

因此,如果您只想将图像上传到服务器,则可以使用另一个返回upload对象的Request函数重载,您可以像{{{{{ 3}}文档:

let fileURL = NSBundle.mainBundle().URLForResource("Default", withExtension: "png")
ler request =Alamofire.upload(.POST, "https://httpbin.org/post", file: fileURL)
// request.cancel()

我希望这对你有所帮助。

答案 2 :(得分:1)

可以准备一个闭包,并从&#34; encodingCompletion&#34;

转出请求。
class NetworkManager {
    private var closure: ((Request)->())?

    func startUpload() {
        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, _, _):
                    self.closure?(upload)

                    upload.responseJSON { response in
                        debugPrint(response)
                        uploadRequest = nil
                    }
                case .Failure(let encodingError):
                    print(encodingError)
                }
            }
        )
    }
}

答案 3 :(得分:0)

就我而言,我在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

然后,我可以创建一种方法来取消任何当前请求类型。请注意,在这里((_,uploadTasks,_)“您还可以拥有” dataTasks“和” downloadTasks“,如果您想要的是((dataTasks,uploadTasks,downloadTasks)”,也可以将其取消。

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!")
        }
    }
}

其中“ CancelRequestType”是枚举。因此,您可以调用API.cancel(request: .UploadTask)

之类的方法
enum CancelRequestType: String {
    case DownloadTask = "DownloadTask"
    case DataTask = "DataTask"
    case UploadTask = "UploadTask"
    case ZeroTask = "Zero"
}