Moya: How to upload image array as a multipart parameters ?

Created on 31 Jul 2019  路  6Comments  路  Source: Moya/Moya

i have tried for several time to upload image array as a multipart parameters but nothing work

my service code :

enum UserService {
case order(
        Name : String, price : String, images: [UIImage]
}
var task: Task {

        switch self {

case .order(let Name, let price)
return .requestParameters(parameters: [ "name": Name, "price":price]), encoding:URLEncoding.queryString)
}
    var multipartBody: [MultipartFormData]? {

        switch self {
        case .order(_, _,  let Images):
            return [MultipartFormData(provider: .data(Images), name: "image", fileName: " 
            photo.jpg", mimeType:"image/jpeg")]

        default:
            return []
        }


    }

the problem i cant assign array of image to data

Cannot convert value of type '[UIImage]' to expected argument type 'Data'

i try to convert the [UIImage] to Data the error is gone but i cant but my images array to the request . so any one can give how i can do it ?

question

Most helpful comment

Hey @Ghazzway, you need to update your task type from requestParameters to uploadMultipart.

All 6 comments

@sunshinejr

Hey @Ghazzway, I think it depends on how your backend accepts the data, but you could try one the following:

  1. Add multiple images to the form:
for i in 0..<images.count {
    var form = [MultipartFormData]()
    if let data = UIImageJPEGRepresentation(photos[i], 0.5) {        
        form.append(MultipartFormData(provider: .data(data), name: "image", fileName: "photo\(i).jpg", mimeType:"image/jpeg"))
    }
    return form
}
  1. Convert your images to an array of data & convert it to one single data stream that you can send:
let dataImages = images.compactMap { $0.pngData() }
let data = try? JSONEncoder().encode(images)
return [MultipartFormData(provider: .data(data), name: "image", fileName: "photo.jpg", mimeType:"image/jpeg")]

Let me know if it helped!

so what im doing now like this :

enum UserService {
case order(Name : String, price : String, images: [UIImage])
}
var task: Task {

        switch self {

           case .order(let Name, let price)
          return .requestParameters(parameters: [ "name": Name, "price":price]), encoding:URLEncoding.queryString)
}
 var multipartBody: [MultipartFormData]? {

        switch self {
        case .order(_, _,  let Images):
            for i in 0..<images.count {
    var form = [MultipartFormData]()
    if let data = Images[i].jpegData(compressionQuality: 1.0) {        
        form.append(MultipartFormData(provider: .data(data), name: "image", fileName: "photo\(i).jpg", mimeType:"image/jpeg"))
          }

     }
          return form

        default:
            return []
        }


    }

i but breakpoint inside multipartBody but its never calling and the image go withe api like parameter https://domain.com/api/upload?name=book&price=23&images%5B%5D%20size%20%7B1200%2C%20900%7D%20orientation%20

so mr @sunshinejr plz help me

Hey @Ghazzway, you need to update your task type from requestParameters to uploadMultipart.

so im back with another solution like this :

enum UserService {
case order(Name : String, price : String, images: [UIImage])
}
var multipartBody: [MultipartFormData]? {

        switch self {
        case .order(_let Name, let price, let Images):
         //to handle upload the pram

         let NameS = MultipartFormData(provider: .data(Name.data(using: .utf8)!), name: 
         "Name")
            let priceS = MultipartFormData(provider: .data(price.data(using: .utf8)!), 
             name: "price")

        //to handle upload image array 
         var form = [MultipartFormData]()
            for i in 0..<images.count {
          if let data = Images[i].jpegData(compressionQuality: 1.0) {        
         form.append(MultipartFormData(provider: .data(data), name: "image", fileName: "photo\ . 
        (i).jpg", mimeType:"image/jpeg"))
          }

     }
     return  [ NameS,priceS] + form

        default:
            return []
        }


    }
var task: Task {

        switch self {

           case .order:
           return .uploadMultipart(multipartBody!)
}

this working so good with me , thanks a lot @sunshinejr

Awesome to hear @Ghazzway 馃帀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JianweiWangs picture JianweiWangs  路  3Comments

hamada147 picture hamada147  路  3Comments

syq7970 picture syq7970  路  3Comments

dimpiax picture dimpiax  路  3Comments

JoeFerrucci picture JoeFerrucci  路  3Comments