Home > Mobile >  Swift UrlSession Multipart/form-data Upload Array Of Images
Swift UrlSession Multipart/form-data Upload Array Of Images

Time:12-31

With Node JS backend I have the following function to receive array of images which is tested with postman and its working fine and return the uploaded array details,

router.post('/imagesTest',multer().fields([{ name: 'externalImages', maxCount: 10 }]),adminController.imagesTest)

exports.imagesTest = async (req, res) => {
  console.log(req.files['externalImages'])
  res.send(req.files['externalImages'])
};

Now I want to send the images with swift using the following,

func imagesTest(imageDataArray : [Data]) -> AnyPublisher<APIResponse, Error> {
        print("================= TEST IMAGES ")
        let boundary = UUID().uuidString
        var request = URLRequest(url: URL(string: "\(Constants.baseUrl)/admin/imagesTest")!)
        request.httpMethod = "POST"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.httpBody = createMultiImageMultiPartBody(boundary: boundary, imageDataArray: imageDataArray)
        return URLSession.shared.dataTaskPublisher(for: request)
            .receive(on: RunLoop.main)
            .map({$0.data})
            .decode(type: APIResponse.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }

func createMultiImageMultiPartBody(boundary : String,imageDataArray : [Data]) -> Data {
            var body = Data()
    
            let mimetype = "image/jpg"
            
            for imageData in imageDataArray{
                body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Disposition: form-data; name=\"externalImages\"; filename=\"\(Date().timeIntervalSince1970).jpg\"\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
                body.append(imageData)
                body.append("\r\n".data(using: String.Encoding.utf8)!)
                body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
            }
            return body
        }

But unfortunately Im getting only 1 image in the backend !! why is that ? i searched a lot and I found this question as well same issue

Note : I don't want to use any third part libraries

Any help will be much appreciated

CodePudding user response:

I found what was wrong with my code by checking postman request body, the createMultiImageMultiPartBody function should be as below, hope to help someone

func createMultiImageMultiPartBody(boundary : String,imageDataArray : [Data]) -> Data {
            var body = Data()
    
            let mimetype = "image/jpg"
            
            for imageData in imageDataArray{
                body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Disposition: form-data; name=\"externalImages\"; filename=\"\(Date().timeIntervalSince1970).jpg\"\r\n".data(using: String.Encoding.utf8)!)

                body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
                body.append(imageData)
                body.append("\r\n".data(using: String.Encoding.utf8)!)
                
            }
            // Just take this line out of the images loop 
            body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
            return body
        }

CodePudding user response:

  If you try to watch this tutorial, it can help you:

  https://www.youtube.com/watch?v=8GH0yMPvQFU


  Note: Only try to change url which is used in video, all other stuffs are correct.
  • Related