HTTP Status 400 – Bad Request

I'm making a POST function but I'm getting an error. I am getting "HTTP Status 400 – Bad Request" error in console. In the simulator, it says "Something went wrong. Please try again later" on the screen. I don't understand where I am making the mistake. I need to fix this error urgently. Could you help?

JSON Model:

struct TaniTalep: Encodable {

    let photo: Data?

    let xray: Data?

    let talep: String

    

    init(photo: UIImage?, xray: UIImage?, talep: Talep) throws {

        self.photo = photo?.pngData()

        self.xray = xray?.pngData()

        let jsonData = try JSONEncoder().encode(talep)

        self.talep = String(data: jsonData, encoding: .utf8)!

    }

}



struct Talep: Codable {

    let tanitalepid: Int

    let hastaid: Int

    let cevap: String

    let anamnezList: [Anamnez]

    let sikayetanaList: [SikayetAna]

    let sorucevapList: [SoruCevap]



    struct SoruCevap: Codable {

        let sikayetsoruid: Int

        let soru: String

        let sorucevap: String

    }

    

    struct SikayetAna: Codable {

        let sikayet: String

        let sikayetanaid: Int

    }

    

    struct Anamnez: Codable {

        let aciklama: String

        let anamnezid: Int

        let cevap: String

        let nitelik: String

        let sonaltiay: String

    }

}

Web Service:

func postTaniTalep(token: String, email: String, tanitalepid: Int, taniTalep: TaniTalep) async throws -> Bool {

        guard let url = URL(string: "http://ec2-3-74-42-117.eu-central-1.compute.amazonaws.com:8080/dentistodayapis/inserttanitalep") else {

            throw NetworkError.invalidURL

        }



        var request = URLRequest(url: url)

        request.httpMethod = "POST"

        request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")

//        request.addValue("application/json", forHTTPHeaderField: "Accept")

        request.addValue("\(token)", forHTTPHeaderField: "credentialtoken")

        request.addValue("\(email)", forHTTPHeaderField: "username")

        request.addValue("IOS", forHTTPHeaderField: "platform")

        request.addValue("TR", forHTTPHeaderField: "langcode")

        

        

        let formData = try JSONEncoder().encode(taniTalep)

        

        print("\(Date())-\(#line)--\(#function)--formData: \(String(data: formData, encoding: .utf8))-")

        

        request.httpBody = formData

        

        let (data, response) = try await URLSession.shared.data(for: request)

            

        print(url)

        print(String(data: data, encoding: .utf8))

            

        return (response as? HTTPURLResponse)?.statusCode == 200

    }

View:

final class TaniTalepViewModel: ObservableObject {

    static let shared = TaniTalepViewModel()

    init() {}

    

    var hastaID: Int?

    var cevap: String?

    var soruCevapList = [Talep.SoruCevap]()

    var sikayetAnaList = [Talep.SikayetAna]()

    var anamnezList = [Talep.Anamnez]()

    var photo: UIImage?

    var xray: UIImage?

    @Published var message: String?

    

    @MainActor

    func postTaniTalep() async {

        guard

            let hastaID = hastaID,

            let cevap = cevap

        else {

            assertionFailure("Insufficient data")

            return

        }

        

        let defaults = UserDefaults.standard

        guard let token = defaults.string(forKey: "jsonwebtoken") else {

            return

        }

        guard let email = defaults.string(forKey: "email") else {

            return

        }

        

        do {

            let tanitalepid = try await Webservice().getSequenceNextval(token: token, email: email)

            let success = try await Webservice().postTaniTalep(token: token, email: email, tanitalepid: tanitalepid, taniTalep: TaniTalep(photo: photo, xray: xray, talep: .init(tanitalepid: tanitalepid, hastaid: hastaID, cevap: cevap, anamnezList: anamnezList, sikayetanaList: sikayetAnaList, sorucevapList: soruCevapList)))

            if success {

                message = "Your registration number \(tanitalepid) has been completed successfully.\n \(tanitalepid) numaralı kaydınız başarıyla tamamlanmıştır."

            } else {

                message = "Something went wrong. Please try again later."

            }

            

        } catch {

            print("\(Date())-\(#line)--\(#function)--error: \(error)-")

            message = "Error while posting tani talep: \(error)"

        }

    }

    



}



struct TaniTalepView: View {

    @ObservedObject private var viewModel = TaniTalepViewModel.shared

    

    var body: some View {

        ZStack {

            Color.flesh

                .ignoresSafeArea()

            

            if let message = viewModel.message {

                Text(message)

                    .padding()

            } else {

                ProgressView()

            }

        }

        .task {

            await viewModel.postTaniTalep()

        }

    }

}

Just to see where it may come from, try to comment out:

        request.addValue("\(token)", forHTTPHeaderField: "credentialtoken")
        request.addValue("\(email)", forHTTPHeaderField: "username")
        request.addValue("IOS", forHTTPHeaderField: "platform")
        request.addValue("TR", forHTTPHeaderField: "langcode")

Do you still get the error ?

I have two suggestions to help you figure out what's going wrong.

First, set a breakpoint at the start of the postTaniTalep function. Step through the code line by line and check that everything in the request is what you expect to see. If you haven't used Xcode's debugger before, the following article will help you:

https://www.swiftdevjournal.com/an-introduction-to-xcodes-debugger/

Second, you have the following line of code to make the network call:

let (data, response) = try await URLSession.shared.data(for: request)

The code uses try. Code with try can throw errors, but you don't handle them. Wrap the network call in a do-catch block and at least print the error in the catch part of the block. The error message you get should be more helpful than "400 Bad Request".

HTTP Status 400 – Bad Request
 
 
Q