2

I know that this question has been asked before a few times, here, here and possibly many more times. I've tried all of those answers, but none of them work for what I am trying to do.

Essentially, I am attempting to connect a UIImage to the Kairos API. I'm making a simple POST request, with a source parameter in the request. The request returns a JSON object with various datapoints that I would like to use in my application. Most of the answers that I have seen about uploading image files use a multipart-form-data request to do it, but I'm not sure about how this would connect to the source parameter the API is asking for in the request. I know how I can add in the authentication section as a header to my URLRequest, I just need help with uploading the image as the source parameter.

This CURL code works:

curl -X POST -H "app_id: XXX" -H "app_key: YYY" -F "source=@/Users/myusername/Desktop/myimage.jpg" "https://api.kairos.com/v2/media"

However, I'm not sure how I can convert such code to Swift.

Preferably, I'd like to use traditional URLRequests and URLSessions rather than third-party external libraries (due to a couple of blog posts that I've read which mention the danger of using third-party libraries at times). Can anyone help me to do this?

Thanks in advance!

sccoding
  • 356
  • 3
  • 18
  • -F in curl means form data only. For reference https://github.com/newfivefour/BlogPosts/blob/master/swift-form-data-multipart-upload-URLRequest.md – Rikesh Subedi Nov 01 '17 at 15:23
  • @RikeshSubedi Thank you! Would you mind adding an answer here with the exact code I could follow? The link you've added is one of the resources I've tried (but forgotten to mention). Is it possible for you to add code from the link which I could use for exactly this case? Thanks! – sccoding Nov 01 '17 at 15:28

1 Answers1

2

The code should like this.

        let url = URL(string: "https://api.kairos.com/v2/media")
        var urlRequest = URLRequest(url: url!)
        urlRequest.httpMethod = "POST"
        urlRequest.addValue("XXX", forHTTPHeaderField: "app_id")
        urlRequest.addValue("YYY", forHTTPHeaderField: "app_key")
        let boundary = "Boundary-\(UUID().uuidString)"
        urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")


        //image data
        let image = UIImage() //replace with your image
        let fileName = "myimage.jpg"
        let data = UIImageJPEGRepresentation(image, 0.7)!

        //create body
        let body = NSMutableData()

        //append first line
        let line1_boundryPrefix = "--\(boundary)\r\n"
        body.append(line1_boundryPrefix.data(
            using: String.Encoding.utf8,
            allowLossyConversion: false)!)

        //append second line
        let line2_parameter = "Content-Disposition: form-data; name=\"source\"; filename=\"" + fileName + "\"\r\n"
        body.append(line2_parameter.data(
            using: String.Encoding.utf8,
            allowLossyConversion: false)!)

        //append third line (mime type)
        let mimeType = "image/jpg"
        let line3_contentType = "Content-Type: \(mimeType)\r\n\r\n"
        body.append(line3_contentType.data(
            using: String.Encoding.utf8,
            allowLossyConversion: false)!)

        //append image data
        //line4
        body.append(data)


        let line5 = "\r\n"
        body.append(line5.data(
            using: String.Encoding.utf8,
            allowLossyConversion: false)!)


        let line6 = "--" + boundary + "--\r\n"
        body.append(line6.data(
            using: String.Encoding.utf8,
            allowLossyConversion: false)!)
        urlRequest.httpBody = body as Data
        urlRequest.setValue(String(body.length), forHTTPHeaderField: "Content-Length")

        URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
            //handle callback
        }
Rikesh Subedi
  • 1,755
  • 22
  • 21