vadymmarkov / Malibu

:surfer: Malibu is a networking library built on promises

Home Page:https://vadymmarkov.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Re: Multipartform upload file using RequestConvertible

quangdng opened this issue · comments

Hi there,

Thanks for the great library. However, I could not seem to figure out how to upload multipart form data (with files attached) using Malibu and RequestConvertible enum.

Could you please give me an example of how to do it?

Many thanks.

Hi @quangdng ! Have you tried upload request, like: Request.upload(data: data, to: "url") or Request.upload( multipartParameters: ["key": "value"], to: "http:/api.loc/posts" )

Hi @vadymmarkov ,

Thanks for your timely response. I've tried with Request.upload( multipartParameters: ["key": "value"], to: "http:/api.loc/posts" ) but has no luck as I have little idea on how to encode my files as String.

Request.upload(data: data, to: "url") does not really suits me as I need to send some more parameters.

I've also tried Request.post with multipart-form content type but also no luck.

If you can give me a hint on how to encode files for Request.upload( multipartParameters: ["key": "value"], to: "http:/api.loc/posts" ) that would be really helpful.

Thanks in advance.

You can custom parameterEncoders like this:

Malibu.parameterEncoders[.multipartFormData] = UEMultipartFormEncoder()

class UEMultipartFormEncoder: ParameterEncoding {
  func encode(parameters: [String: Any]) throws -> Data? {
    let data = CustomMultipartBuilder().buildMultipartData(from: parameters)
    return data
  }
}

class CustomMultipartBuilder {
  public init() {}

  public func buildMultipartString(from parameters: [String: Any]) -> String {
    var string = ""
    let components = parameters

    for (key, value) in components {
      string += "--\(boundary)\r\n"
      string += "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n"
      string += "\(value)\r\n"
    }

    string += "--\(boundary)--\r\n"

    return string
  }

  public func buildMultipartData(from parameters: [String: Any]) -> Data {
    var string = ""
    let components = parameters

    var result: Data = Data()

    for (key, value) in components {
      result.append("--\(boundary)\r\n".data(using: .utf8)!)
      if let d = value as? Data {
        result.append("Content-Disposition: form-data; name=\"\(key)\";filename=\"img.png\"\r\n".data(using: .utf8)!)
        result.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
        result.append(d)
        result.append("\r\n".data(using: .utf8)!)
      }
      else {
        result.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!)
        result.append("\(value)\r\n".data(using: .utf8)!)
      }
    }

    result.append("--\(boundary)--\r\n".data(using: .utf8)!)
    return result
  }
}

I use this code in my project for upload image.