Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re: Multipartform upload file using RequestConvertible #82

Open
quangdng opened this issue Oct 14, 2017 · 3 comments
Open

Re: Multipartform upload file using RequestConvertible #82

quangdng opened this issue Oct 14, 2017 · 3 comments

Comments

@quangdng
Copy link

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.

@vadymmarkov
Copy link
Owner

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

@quangdng
Copy link
Author

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.

@shiweifu
Copy link

shiweifu commented Feb 2, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants