I am encountering points whereas trying to add audio recordsdata in my iOS Swift utility utilizing URLSession. The aim is to ship an audio file together with some parameters to a server endpoint utilizing multipart type information. Nevertheless, regardless of seemingly appropriate implementation, I am going through surprising conduct.
This is a short overview of my code’s performance:
I’ve a perform uploadFile(testID:) the place I assemble the URLRequest with vital headers and parameters. I then try to learn an audio file (sample-3s.mp3) from the primary bundle and add it to the request as part of multipart type information.
I am using a customized struct URLSession.File to signify every file to be uploaded, containing properties similar to title, fileName, information, and contentType.
Nevertheless, upon executing the request, I am not receiving the 422 standing code response from the server.
func uploadFile(testID:Int) {
var recordsdata: [URLSession.File] = []
var params: [String : Any] = ["test_id": testID]
guard let url = URL(string: "(baseURL)/speaking-file") else {return}
var urlRequest = URLRequest(url: url)
let boundary = UUID().uuidString
urlRequest.httpMethod = "POST"
if let token = Auth.shared.oAuth?.accessToken, let sort = Auth.shared.oAuth?.tokenType {
urlRequest.addValue("(sort) (token)", forHTTPHeaderField: "Authorization")
}
urlRequest.addValue(Configuration.conf?.clientId ?? "", forHTTPHeaderField: "clientid")
urlRequest.addValue(Configuration.conf?.clientSecret ?? "", forHTTPHeaderField: "clientsecret")
urlRequest.setValue("multipart/form-data; boundary=(boundary)", forHTTPHeaderField: "Content material-Sort")
if let audioUrl = Bundle.principal.url(forResource: "sample-3s", withExtension: "mp3") {
do{
let audioData = attempt Knowledge(contentsOf: audioUrl)
let fileName = audioUrl.lastPathComponent
let contentType = "audio/mp3" // Modify content material sort as wanted
let file = URLSession.File(title: "file", fileName: fileName, information: audioData, contentType: contentType)
recordsdata.append(file)
}catch {
print("Didn't convert to information")
}
}
let information = createBodyWithMultipleImages(parameters: params, recordsdata: recordsdata, boundary: boundary)
urlRequest.httpBody = information
Logger.log(request: urlRequest)
URLSession.shared.dataTask(with: urlRequest) { information, response, error in
if let error {
print("Error from file add")
completion(.failure(error))
}
if let response {
print("response type file add (response)")
}
if let information {
do {
let json = attempt JSONSerialization.jsonObject(with: information,choices: [])
print(json)
}catch {
print("Didn't seairlized json")
}
completion(.success(ResponseMessage(element: "File Uploaded")))
}
}.resume()
}
personal func createBodyWithMultipleImages(parameters: [String: Any]?, recordsdata: [URLSession.File], boundary: String) -> Knowledge {
var physique = Knowledge()
if let parameters = parameters {
for (key, worth) in parameters {
physique.append("--(boundary)rn".information(utilizing: .utf8)!)
physique.append("Content material-Disposition: form-data; title="(key)"rnrn".information(utilizing: .utf8)!)
physique.append("(worth)rn".information(utilizing: .utf8)!)
}
}
recordsdata.forEach{
physique.append("--(boundary)rn".information(utilizing: .utf8)!)
physique.append("Content material-Disposition: form-data; title="($0.title)"; filename="($0.fileName)"rn".information(utilizing: .utf8)!)
physique.append("Content material-Sort: ($0.contentType)rnrn".information(utilizing: .utf8)!)
physique.append($0.information)
physique.append("rn".information(utilizing: .utf8)!)
}
physique.append("--(boundary)--rn".information(utilizing: .utf8)!)
return physique
}
extension URLSession {
public struct File {
public let title: String
public let fileName: String
public let information: Knowledge
public let contentType: String
public init(title: String, fileName: String, information: Knowledge, contentType: String) {
self.title = title
self.fileName = fileName
self.information = information
self.contentType = contentType
}
}
}