Kevin Bertrand
Kevin Bertrand

Reputation: 111

Send image from iOS Alamofire to Vapor

I have an application where user can update their profile picture. The application is developed in SwiftUI and used Alamofire to perform API request and the server is developed with Vapor. When I tried to send the picture to the server, I got this error:

[ WARNING ] Value required for key 'filename'. [request-id: A5083FA1-657C-4777-A7FF-9D02E2A66703]

Here is the code from Vapor:

private func updatePicture(req: Request) async throws -> Response {
        let file = try req.content.decode(File.self)
        guard let fileExtension = file.extension else { throw Abort(.badRequest)}
        
        return .init(status: .accepted, headers: getDefaultHttpHeader(), body: .empty)
    }

And here is the iOS code:

func uploadFiles(urlParams: [String], method: HTTPMethod, user: User, image: UIImage, completionHandler: @escaping ((Data?, HTTPURLResponse?, Error?)) -> Void) {
        guard let formattedUrl = URL(string: "\(url)/\(urlParams.joined(separator: "/"))") else {
            completionHandler((nil, nil, nil))
            return
        }
        var headers: HTTPHeaders?
        headers = ["Authorization" : "Bearer \(user.token)"]
        
        let multiPart: MultipartFormData = MultipartFormData()
        multiPart.append(image.jpegData(compressionQuality: 0.9), withName: "data", fileName: "filename", mimeType: "image/jpeg" )

        AF.upload(multipartFormData: multiPart, to: formattedUrl, method: .patch, headers: headers).response { data in
            print(data)
        }.resume()
    }

I followed vapor and Alamofire documentation and I still get this issue.

Is anyone can help me with this issues ?

Upvotes: 1

Views: 205

Answers (1)

imike
imike

Reputation: 5656

On the Vapor side you have to use struct with File field inside

struct PayloadModel: Content {
    let data: File
}

private func updatePicture(req: Request) async throws -> HTTPStatus {
    let payload = try req.content.decode(PayloadModel.self)
    guard let fileExtension = payload.data.extension else {
        throw Abort(.badRequest)
    }

    return .accepted
}

Upvotes: 1

Related Questions