好的想法是:
将视频文件作为多部分请求上传
将令牌设置为标头
正文应编码为queryString
对于这种json类型,一切正常:
{
"description": "opi",
"playerJersey": [
{
"playerId": "5c209d446ea7260b82fb0933",
"playerJerseyColor": "Black"
}
],
"title": "nas",
"playerList": [
{
"_id": "5c209d446ea7260b82fb0933"
}
]
}
但是,如果数据中有多个播放器,并且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[]
[playerId]=5c209d446ea7260b82fb0933
&playerJersey[]
[playerJerseyColor]=Black
&playerJersey[]
[playerId]=5c209d4c6ea7260b82fb0934
&playerJersey[]
[playerJerseyColor]=Yellow
&playerList[]
[_id]=5c209d446ea7260b82fb0933
&playerList[]
[_id]=5c209d4c6ea7260b82fb0934
&title=nas
这似乎不太正确(最后两个_id应该是它们自己的独立字典/ json,并且此编码似乎将它们合并到一个playerList中,并且我从服务器获得的响应与此再次相关,并且看起来像这个:
[数据]:701个字节[结果]:成功:{“状态”:500,“消息”:“内部 服务器错误!“,”错误“:{”错误“:{”玩家列表“:{”消息“:”发布到 数组值\“ [{_id:['5c209d446ea7260b82fb0933', '5c209d4c6ea7260b82fb0934']} \“在路径上 \“ playerList \”“,” name“:” CastError“,” stringValue“:” \“ [{_id:[ '5c209d446ea7260b82fb0933','5c209d4c6ea7260b82fb0934']} ] \“”,“种类”:“数组”,“值”:[{“ _ id”:[“ 5c209d446ea7260b82fb0933”,“ 5c209d4c6ea7260b82fb0934”]}]],“路径”:“玩家列表”,“原因”:{}} },“ _ message”:“视频 验证失败”,“消息”:“视频验证失败:playerList: 值\“ [{_id:[ '5c209d446ea7260b82fb0933','5c209d4c6ea7260b82fb0934']}] \“在路径上 \“ playerList \”“,”名称“:” 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的参数之前,有无数种制作原始字典/ json的方法。
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)