【问题标题】:How to upload multiple images in multipart using Alamofire?如何使用 Alamofire 分段上传多张图片?
【发布时间】:2017-03-08 19:33:53
【问题描述】:

我被困在使用 Alamofire 分段上传多个图像。谁能帮我? 提前致谢!!

有关更多详细信息,我正在使用此代码创建图像数据的主体部分:

func imageArrayToNSData(array: [UIImage],boundary:String) -> NSData {
    let body = NSMutableData()
    var i = 0;
    for image in array{
        let filename = "image\(i).jpg"
        let data = UIImageJPEGRepresentation(image,0.8);
        let mimetype = "image/jpeg"
        let key = "product_images"
        body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(data!)
        body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        i += 1
    }

    body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    return body
}

上传我正在使用:

        Alamofire.upload(.POST, EDIT_PRODUCT_URL, headers: ["Accept": "application/json","Content-Type":"application/json"], multipartFormData: { (formData) in

        if productImages.count>0{
            let boundary = generateBoundaryString()
            let imageData = CommonClass.imageArrayToNSData(productImages,boundary: boundary)
            formData.appendBodyPart(data: imageData, name: "product_images", mimeType: "image/jpeg")
        }

        for (key, value) in params {
            if value is [String]{
                let data = CommonClass.stringArrayToNSData(value as! [String])
                formData.appendBodyPart(data:data , name: key)
            }else if value is String{
                formData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
            }else if let v = value as? Bool{
                var bValue = v
                let d = NSData(bytes: &bValue, length: sizeof(Bool))
                formData.appendBodyPart(data: d, name: key)
            }
        }

    }) { (encodingResult) in
        switch encodingResult {
        case .Success(let upload, _, _):
            KVNProgress.showProgress(CGFloat(0), status:"0% Sent")
            upload.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
                // This closure is NOT called on the main queue for performance
                // reasons. To update your ui, dispatch to the main queue.
                dispatch_async(dispatch_get_main_queue()) {
                    let prg = Int((CGFloat(totalBytesWritten)*100)/CGFloat(totalBytesExpectedToWrite))
                    if prg == 100{
                        KVNProgress.showSuccessWithStatus("Created")
                    }
                    KVNProgress.updateStatus("\(prg)% Sent")
                    KVNProgress.updateProgress(CGFloat(Float(prg)/100.0), animated: true)
                }
            }
            upload.responseJSON { response in
                CommonClass.hideLoader()
                switch response.result {
                case .Success:
                    if let value = response.result.value {
                        let json = JSON(value)
                        print_debug("edit Product JSON is\n\(json)");  
                        completionBlock(json)
                    }else{
                        completionBlock(nil)
                    }
                case .Failure(let error):
                    print_debug(error.description)
                    showErrorWithMessage("Oops! Couldn't connect to server!")
                    completionBlock(nil)
                }
            }

        case .Failure(let encodingError):
            print(encodingError)
        }
    }

谁能让我建议使用 Alamofire 分段上传多个文件的方法?

【问题讨论】:

    标签: ios swift alamofire multipart alamofireimage


    【解决方案1】:

    要上传多张图片,您需要循环调用此代码

    let boundary = generateBoundaryString()
    let imageData = CommonClass.imageArrayToNSData(productImages,boundary: boundary)
    formData.appendBodyPart(data: imageData, name: "product_images", mimeType: "image/jpeg")
    

    【讨论】:

    • 让我检查@Rajat,如果它解决了,我肯定会做其他工作:)
    【解决方案2】:

    希望对你有所帮助:

    使用 Swift 3x:(我在这个 sn-p 中上传了四张照片)

     //MARK: - upload multiple photos
    
        func uploadImagesAndData(params:[String : AnyObject]?,image1: UIImage,image2: UIImage,image3: UIImage,image4: UIImage,headers : [String : String]?, completionHandler:@escaping CompletionHandler) -> Void {
    
            let imageData1 = UIImageJPEGRepresentation(image1, 0.5)!
            let imageData2 = UIImageJPEGRepresentation(image2, 0.5)!
    
            let imageData3 = UIImageJPEGRepresentation(image3, 0.5)!
    
            let imageData4 = UIImageJPEGRepresentation(image4, 0.5)!
    
    
            Alamofire.upload(multipartFormData: { multipartFormData in
    
                    for (key, value) in params! {
                        if let data = value.data(using: String.Encoding.utf8.rawValue) {
                            multipartFormData.append(data, withName: key)
                        }
                    }
    
                    multipartFormData.append(imageData1, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
                    multipartFormData.append(imageData2, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
                    multipartFormData.append(imageData3, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
                    multipartFormData.append(imageData4, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
    
            },
                to: K_BASEURL + K_API_LOGINDATA, encodingCompletion: { encodingResult in
                    switch encodingResult {
                    case .success(let upload, _, _):
                        upload
                            .validate()
                            .responseJSON { response in
                                switch response.result {
                                case .success(let value):
                                    print("responseObject: \(value)")
                                case .failure(let responseError):
                                    print("responseError: \(responseError)")
                                }
                        }
                    case .failure(let encodingError):
                        print("encodingError: \(encodingError)")
                    }
            })
        }
    

    【讨论】:

    • "withName" 参数对于每个新追加都必须不同。否则它们只会被覆盖。
    • 不,“文件名”对此负责!而“withName”是一个“文件”,因为这只是为了指定类型。
    • @AnuragSharma 如果我们必须以单独的数组发送图像,你能告诉我代码吗?
    【解决方案3】:

    1) 在 Swift3 中使用 Alamofire 上传多张图片

    typealias APICompletionHandler = (code:Int, error:NSError?, response:AnyObject?) -> Void
    
    func uploadIMultipart(_ strApiName:String, param : NSDictionary?, data:Array<NSDictionary>, header:[String : String]?, completionHandler:@escaping APICompletionHandler)
        {
            let strURL : String = strApiName
    
            let apiURL = try! URLRequest(url: strURL, method: .post, headers: header)
    
            Alamofire.upload(multipartFormData: { (multipartFormData) in
                // code
                var i : Int = 0
                for dict:NSDictionary in data {
                    let extention = dict["format"] as? String
                    let strMimeType = dict["strMimeType"] as? String
                    let nameofFile:String = (6.randomString as String)+"."+extention!
                    if (dict["data"] as? Data != nil) {
                        multipartFormData.append(Foundation.Data(dict["data"] as! Data), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
                    } else {
                        let strUrl = dict["data"] as! String
                        let fileURL : URL? = URL(string: strUrl)
                        multipartFormData.append(try! Foundation.Data(contentsOf: fileURL!), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
    
                    }
                    i += 1
                }
    
                for (key, value) in param! {
                    multipartFormData.append((value as! NSString).data(using: String.Encoding.utf8.rawValue)!, withName: key as! String)
                }
    
            }, with: apiURL, encodingCompletion: { (result) in
                // code
                switch result {
    
                case .success(let upload,_ ,_ ):
                    upload.responseJSON { response in
    
                        switch response.result {
                        case .success(let data):
                            //Sucess
                        case .failure(let error):
                            print(error.localizedDescription)
    
                        }
                    }
                case .failure(let encodingError):
                    print(encodingError)
                    completionHandler(0, encodingError as NSError?, nil)
                }
            })
        }
    

    2) 调用函数

            let imageData : NSData = UIImagePNGRepresentation(imgUserProfile.image!)! as NSData
            let imageData1 : NSData = UIImagePNGRepresentation(imgUserProfile.image!)! as NSData
    
            let dict1: Dictionary = ["data":imageData,"key":"user_image", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
            let dict2: Dictionary = ["data":imageData1,"key":"image1", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
            let array: Array = [dict1,dict2]; //pass this image array
    
            self.uploadIMultipart(strAPI, param: dictParam as NSDictionary, data: array as Array<NSDictionary>, header: nil) { (code, error, response) in
                AppSingletonObj.stopLoading(inView: self.view)
    
                //API manager sucess or failure
                if code == 1 {
                    let status = response?["success"]
    
                    //API sucess or failure
                    if(status as! Int == 1) {
                        print(response!)
                    }
                    else {
                        let errorMessage = response?["message"]
                        AppSingletonObj.showAlert(msg: errorMessage as! String)
                    }
                }
                else {
                    AppSingletonObj.showAlert(msg: "Some error occured! please try after sometime")
                }
            }
    

    3) 创建文件名的扩展名

    //MARK: CREATE RANDOM STRING of LENGTH
    extension Int{
        var randomString : String {
    
            let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
            let randomString : NSMutableString = NSMutableString(capacity: self)
    
            for _ in 0 ..< self{
                let length = UInt32 (letters.length)
                let rand = arc4random_uniform(length)
                randomString.appendFormat("%C", letters.character(at: Int(rand)))
            }
            return randomString as String
        }
    }
    

    【讨论】:

    • 将在 API 中传递的额外参数。
    【解决方案4】:

    Swift 3 及以上版本 只需在 "[]" 后面加上图像键标识符,将其视为图像数组。

    Alamofire.upload(multipartFormData: { multipartFormData in
                // import image to request
                for imageData in imagesData {
                    multipartFormData.append(imageData, withName: "\(imageParamName)[]", fileName: "\(Date().timeIntervalSince1970).jpeg", mimeType: "image/jpeg")
                }
                for (key, value) in parameters {
                    multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
                }
            }, to: urlString,
    
                encodingCompletion: { encodingResult in
                    switch encodingResult {
                    case .success(let upload, _, _):
                        upload.responseJSON { response in
    
                        }
                    case .failure(let error):
                        print(error)
                    }
    
            })
    

    【讨论】:

      【解决方案5】:
      class func uploadImageToServer(uploadTo: String, imageParameters:[[String: Any]], otherParameters:[String: Any],authorization: String, completionHandler:@escaping ((_ responseValue: Any?, _ error: Error?) -> Void)) {
      
              if isNetWorkAvailable() {
      
                  var urlRequest = URLRequest(url: URL.init(string: uploadTo)!)
                  urlRequest.httpMethod = "POST"
                  urlRequest.addValue(authorization, forHTTPHeaderField: "Authorization")
                  DispatchQueue.main.async(execute: {
                      ActivityIndicatorView.showActivity()
                  })
                 print("Request Url: \(uploadTo)\nRequest Params: \(imageParameters)\nRequest Params: \(otherParameters)")
                  Alamofire.upload(multipartFormData: { (multipartFormData) in
      
                      for (key,value) in otherParameters {
                          multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
                      }
      
                      for value  in imageParameters {
                          let image = value["image"] as! UIImage
                          let imgData = UIImageJPEGRepresentation(image, 1)!
                          let imageName = value["imageName"] as! String
                          let fileName = value["fileName"] as! String
      
                          multipartFormData.append(imgData, withName: imageName, fileName: fileName ,mimeType: "image/jpeg")
                      }
                  }, usingThreshold: UInt64.init(), with: urlRequest, encodingCompletion: { (encodingResult) in
                      switch encodingResult {
      
                      case .success(let upload, _, _):
                          upload.uploadProgress(closure: { (progress) in
                              let uploadPercetange = Int(progress.fractionCompleted*100)
                              print("Upload Progress: \(uploadPercetange)%")
                          })
                          upload.responseJSON(completionHandler: { (response) in
                              print(response.result.value ?? "NaN")
                              let result = response.result.value
                              completionHandler(result, nil)
                              DispatchQueue.main.async(execute: {
                                  ActivityIndicatorView.hideActivity()
                              })
                          })
      
                      case .failure(let encodingError):
                          print(encodingError)
                          let error = encodingError
                          completionHandler(nil, error)
                          DispatchQueue.main.async(execute: {
                              ActivityIndicatorView.hideActivity()
                          })
                      }
                  })
              } else {
                  AlertView.showAlert(title: "Error", message: "Network not available")
              }
      
          }
      

      【讨论】:

        【解决方案6】:

        斯威夫特 4.2.
        这里的代码仅用于不带任何参数。
        如果您需要传递额外的参数,只需使用 @Hardik Thakkar 代码。

        typealias APICompletionHandler = (code:Int, error:NSError?, response:AnyObject?) -> Void
        
        @IBOutlet weak var thirdImage: UIImageView!
        var fristImage:UIImage = UIImage()
        var secondimage:UIImage = UIImage()
        
        extension ViewController {
        
          func upload() {
        
            let imgData1 = fristImage.jpegData(compressionQuality: 0.7)
            let imgData2 = secondimage.jpegData(compressionQuality: 0.7)
            let imgData3 = thirdImage.image!.jpegData(compressionQuality: 0.7)
            let headers = [
                "Authorization" : "Bearer " + "Your Token",
                "Content-type": "form-data",
            ]
            let dict1: Dictionary = ["data":imgData1 as Any,"key":"Here Your Body Key1", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
            let dict2: Dictionary = ["data":imgData2 as Any,"key":"Here Your Body Key2", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
            let dict3: Dictionary = ["data":imgData3 as Any,"key":"Here Your Body Key3", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
            let array: Array = [dict1, dict2, dict3]; //pass this image array
        
            self.uploadIMultipart("Here Your URL", data: array as Array<NSDictionary>, header: headers) { (code, error, response) in
        
                  let httpResponse = response as? HTTPURLResponse
                  print("the resopnse code is : \(String(describing: httpResponse?.statusCode.description))")
            }
          }
        
          func uploadIMultipart(_ strApiName:String, data:Array<NSDictionary>, header:[String : String]?, completionHandler:@escaping APICompletionHandler) {
        
            let strURL : String = strApiName
            let apiURL = try! URLRequest(url: strURL, method: .post, headers: header)
            Alamofire.upload(multipartFormData: { (multipartFormData) in
                // code
                var i : Int = 0
                for dict:NSDictionary in data {
                    let extention = dict["format"] as? String
                    let strMimeType = dict["strMimeType"] as? String
                    let nameofFile:String = (6.randomString as String)+"."+extention!
                    if (dict["data"] as? Data != nil) {
                        multipartFormData.append(Foundation.Data(dict["data"] as! Data), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
                    } else {
                        let strUrl = dict["data"] as! String
                        let fileURL : URL? = URL(string: strUrl)
                        multipartFormData.append(try! Foundation.Data(contentsOf: fileURL!), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)    
                    }
                    i += 1
                }
            }, with: apiURL, encodingCompletion: { (result) in
                // code
                switch result {
        
                case .success(let upload,_ ,_ ):
        
                    upload.responseJSON { response in
                        switch response.result {
                        case .success(let response):
                            //Sucess
                            print("response :-", response)
                        case .failure(let error):
                            //Failure
                            print(error.localizedDescription)
                        }
                    }
                case .failure(let encodingError):
                    print(encodingError)
                    completionHandler(0, encodingError as NSError?, nil)
                }
            })
            }
        }
        
        extension Int{
        
            var randomString : String {
        
                let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
                let randomString : NSMutableString = NSMutableString(capacity: self)
        
                for _ in 0 ..< self{
                    let length = UInt32 (letters.length)
                    let rand = arc4random_uniform(length)
                    randomString.appendFormat("%C", letters.character(at: Int(rand)))
                }
                return randomString as String
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2019-11-24
          • 2017-05-20
          • 2018-05-31
          • 2017-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-16
          相关资源
          最近更新 更多