1

As the title suggests, I'm having troubles with my form submission to my server with an API. There are a lot of other posts and tutorials about uploading images to servers in Swift 5, so I currently have the following;

func request5(authToken: String, contextID: String, parameters: [String:Any], image: UIImage) {
        func getBase64Image(image: UIImage, complete: @escaping (String?) -> ()) {
            DispatchQueue.main.async {
                let imageData = image.pngData()
                let base64Image = imageData?.base64EncodedString(options: .lineLength64Characters)
                complete(base64Image)
            }
        }
        getBase64Image(image: image) { base64Image in
            let boundary = "Boundary-\(UUID().uuidString)"

            guard let url = URL(string: self.baseURL + contextID) else { return }

            let jsonData = try? JSONSerialization.data(withJSONObject: parameters)

            var body = ""
            body += "--\(boundary)\r\n"
            body += "Content-Disposition:form-data; name=\"post_picture_link\""
            body += "\r\n\r\n\(base64Image ?? "")\r\n"
            body += "--\(boundary)--\r\n"
            let postData = body.data(using: .utf8)

            var urlRequest = URLRequest(url: url)
            urlRequest.httpMethod = "POST"
            urlRequest.httpBody = jsonData

            let APIauthToken = "Bearer " + authToken
            urlRequest.addValue(APIauthToken, forHTTPHeaderField: "Authorization")
            urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
            urlRequest.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

            URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in

                do {
                    if let d = data {
                        let result = try JSONDecoder().decode(ProperResponseGen.self, from: d)
                        DispatchQueue.main.async {
                            self.response = result
                            self.hasFinished = true
                        }
                    } else {
                        print("No Data")
                    }
                } catch {
                    print(error)
                }

            }.resume()
        }
    }

For the most part (as far as I know), all of this is good as it is for having the image and the body parameters in a setup to be submitted. The problem is, as you can probably tell, when I have it written as it is above, I have the two variables of data, postData, and jsonData, both of which contain separate parts of the full form data submission I need.

Just for simplicity, let's say the API endpoint wants two body keys; "post_picture_link" and "post_caption", post caption being encapsulated in the parameters variables passed onto the function.

How do I combine both of them into just a single httpBody?

methodical
  • 126
  • 10
  • Why are you base64 encoding an image that you’re going to upload as `multipart/form-data`? The whole reason to do `multipart/form-data` is so you don’t have to base64 encode. You only need to base64 encode if you’re uploading in `application/x-www-form-urlencoded` or in JSON. FWIW, see https://stackoverflow.com/a/26163136/1271826 for example of how to do `multipart/form-data` request. That shows you how to not only include image, but also your parameters. – Rob May 18 '20 at 04:45
  • That post is from 6 years ago, since which Swift has obviously changed a lot. I've followed that post as close as possible, but if you look at the post, it has a line where it says `let path1 = Bundle.main.path(forResource: "image1", ofType: "png")!` How do I change this line to use my own image that I pass to the request5 function? – methodical May 18 '20 at 12:47
  • Yep, that question is old, but the answer is up to date. To pass an image, you’d change it to take a `UIImage` and a filename, rather than file paths/urls. See https://gist.github.com/robertmryan/4606ca698bea7ddc5eac5af512b449d5. – Rob May 18 '20 at 14:11

0 Answers0