Хорошо, идея такова:
для загрузки видеофайла в виде запроса из нескольких частей
установка токенов в качестве заголовка
тело должно быть закодировано как queryString
И для этого типа json все работает отлично:
{
"description": "opi",
"playerJersey": [
{
"playerId": "5c209d446ea7260b82fb0933",
"playerJerseyColor": "Black"
}
],
"title": "nas",
"playerList": [
{
"_id": "5c209d446ea7260b82fb0933"
}
]
}
но, если есть большечем 1 игрок в данных, и JSON выглядит так:
{
"description": "opi",
"playerJersey": [
{
"playerId": "5c209d446ea7260b82fb0933",
"playerJerseyColor": "Black"
},
{
"playerId": "5c209d4c6ea7260b82fb0934",
"playerJerseyColor": "Yellow"
}
],
"title": "nas",
"playerList": [
{
"_id": "5c209d446ea7260b82fb0933"
},
{
"_id": "5c209d4c6ea7260b82fb0934"
}
]
}
Я перехватил запрос и распечатал URL-адрес и расшифровал его онлайн, и вот как он сформирован:
http://194.106.182.88:3000/video/upload/5c209d1a6ea7260b82fb0932?description=opi&playerJersey%5B%5D%5BplayerId%5D=5c209d446ea7260b82fb0933&playerJersey%5B%5D%5BplayerJerseyColor%5D=Black&playerJersey%5B%5D%5BplayerId%5D=5c209d4c6ea7260b82fb0934&playerJersey%5B%5D%5BplayerJerseyColor%5D=Yellow&playerList%5B%5D%5B_id%5D=5c209d446ea7260b82fb0933&playerList%5B%5D%5B_id%5D=5c209d4c6ea7260b82fb0934&title=nas
или немного украшенный и декодированный%:
http://194.106.182.88:3000/video/upload/5c209d1a6ea7260b82fb0932?description=opi
&playerJersey[]
[playerId]=5c209d446ea7260b82fb0933
&playerJersey[]
[playerJerseyColor]=Black
&playerJersey[]
[playerId]=5c209d4c6ea7260b82fb0934
&playerJersey[]
[playerJerseyColor]=Yellow
&playerList[]
[_id]=5c209d446ea7260b82fb0933
&playerList[]
[_id]=5c209d4c6ea7260b82fb0934
&title=nas
Что не кажется правильным (эти два последних _id должны быть их собственным отдельным словарем / json, и эта кодировка, кажется, объединяет их вместев одном playerList и ответ, который я получаю от сервера, снова связан с этим вопросом и выглядит следующим образом:
[Данные]: 701 байт [Результат]: УСПЕХ: {"статус": 500,"message": "Внутренняя ошибка сервера!", "error": {"errors": {"playerList": {"message": "Преобразование в массив не выполнено для оценкиe \ " [{_id: ['5c209d446ea7260b82fb0933', '5c209d4c6ea7260b82fb0934']}] \" at path \ "playerList \" "," name ":" CastError "," stringValue ":" \ "[{_id: ['5c209d446ea7260b82fb0933', '5c209d4c6ea7260b82fb0934']}] \ "", "kind": "Array", "value": [{"_ id": ["5c209d446ea7260b82fb0933d] b6fc09b) 5cf 5c6c6bc5f6ccf5ccf5c6cf5ccf5c6b6ccf5c6cf5ccf5ccf5b6c6b6b6ccf5ccf5c5c6b6cf5c6b6ccf5c6b5c6fc5f6cc5b5b6ccf5c6b5c6b6cc5f5c6cf5c6c5c6cf5c6c5c6cf5c6c6, 5, cc, 6, cc6, cc6, cc {5}путь ":" playerList "," reason ": {}}}," _ message ":" Ошибка проверки видео "," message ":" Ошибка проверки видео: playerList: Ошибка приведения к массиву для значения \ "[{_id: ['5c209d446ea7260b82fb0933', '5c209d4c6ea7260b82fb0934']}] \ "at path \" playerList \ "", "name": "ValidationError"}}
где я выделил эту строку:
[ { _id: [ '5c209d446ea7260b82fb0933', '5c209d4c6ea7260b82fb0934' ] } ]
и да, это не то, что я хотел отправить (посмотрите снова на пример json в начале)
Вот мой код.
func postRequestForVideoStreamUpload(_ videoUrl: String, _ videoTitle: String, _ videoDescription: String, _ players: [PlayerIDInput],_ jerseys: [PlayerJersey], _ accessToken: String? = nil, callback: @escaping (() -> Void)) {
guard let userId = UserDefaults.standard.currentUserID() else { return }
guard let streamUrl = URL(string: [API.baseUrl, API.videoUpload, userId].joined(separator: "/")) else { return }
let fileUrl = URL(fileURLWithPath: videoUrl)
let accessToken = UserDefaults.standard.accessToken()
var request = URLRequest(url: streamUrl)
var finalRequest: URLRequest?
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type");
if let token = accessToken {
request.setValue(token, forHTTPHeaderField: "x-access-token")
}
var playersArr: [[String : String]] = []
for player in players {
var tempDict = Dictionary<String, String>()
tempDict["_id"] = player.playerId
playersArr.append(tempDict)
}
var jerseyArr: [[String : String]] = []
for jersey in jerseys {
var tempDict = Dictionary<String, String>()
tempDict["playerId"] = jersey.playerId
tempDict["playerJerseyColor"] = jersey.playerJerseyColor
jerseyArr.append(tempDict)
}
let parameters: [String : Any] = [
"title": videoTitle,
"description": videoDescription,
"playerList": playersArr,
"playerJersey": jerseyArr
]
do {
try finalRequest = Alamofire.URLEncoding(destination: .queryString).encode(request, with: parameters)
} catch let err {
print(err)
return
}
do {
let fileData = try Data(contentsOf: fileUrl)
Alamofire.upload(multipartFormData: { (multiPartFormData) in
multiPartFormData.append(fileData, withName: "withNamePolje", fileName: "fileNamePolje", mimeType: "video/mp4")
}, with: finalRequest!) { (result) in
switch result {
case .success(request: let upload, _, _):
upload.responseString { response in
debugPrint(response)
}.uploadProgress { progress in // main queue by default
DispatchQueue.main.async {
print("Upload Progress: \(progress.fractionCompleted)")
}
}
upload.response { (response) in
callback()
}
return
case .failure(let err):
print(err)
}
}
} catch let err {
print(err)
}
}
Некоторые извещи, которые я пробовал:
1) Бесчисленные способы создания оригинального словаря / JSON, прежде чем поместить его в качестве параметра в finalRequest.
2) Замена:
try finalRequest = Alamofire.URLEncoding(destination: .queryString).encode(request, with: parameters)
с:
try finalRequest = Alamofire.URLEncoding(destination: .queryString, arrayEncoding: .brackets).encode(request, with: parameters)
(пробовал оба .brackets & .noBrackets)