Swift3 视频文件上传和多一个表单参数(可以从表单中跳过并作为 url 路径发送)
Swift3 video file upload along with one more form parameter(can be skipped from form and sent as url path)
我搜索了很长时间,但没有找到任何关于如何执行此操作的好资源。
api 需要一个表单参数 "user_id"(现在将其作为 urlpath 而不是表单参数发送) 和视频文件的其他 "file"。请使用 URLSession Task 或 iOS.
的任何库提供一些代码示例
尝试过 Alamofire:
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(self.fileurl, withName: "file")
}, to:"http://www.www.www/upload/8590",
headers: ["Authorization": "Bearer \(SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key))"] )
{ (result) in
switch result {
case .success(let upload, _ , _):
upload.uploadProgress(closure: { (progress) in
print("uploding>>>>>>")
})
upload.responseJSON { response in
print(response)
print("done")
}
case .failure(let encodingError):
print("failed")
print(encodingError)
}
这从服务器抛出 500,表示无法使用 UTF-8 编码读取 Header 第一个字节。
message = "An Error OccuredInvalid header string: 'utf8' codec can't decode byte 0x9b in position 1: invalid start byte";
result = "Traceback (most recent call last):\n File \"/var/www/wb_ios/wb_app/views.py\", line 94, in post\n user_auth = jwt_decode_handler(auth).get('sub')\n File \"/usr/local/lib/python2.7/dist-packages/rest_framework_jwt/utils.py\", line 104, in jwt_decode_handler\n unverified_payload = jwt.decode(token, None, False)\n File \"/usr/local/lib/python2.7/dist-packages/jwt/api_jwt.py\", line 70, in decode\n payload, signing_input, header, signature = self._load(jwt)\n File \"/usr/local/lib/python2.7/dist-packages/jwt/api_jws.py\", line 177, in _load\n raise DecodeError('Invalid header string: %s' % e)\nDecodeError: Invalid header string: 'utf8' codec can't decode byte 0x9b in position 1: invalid start byte\n";
status = 500;
}
另外,我可以使用邮递员成功发送视频。使用如图所示的 form-data 字段。
body
Headers
最后我也试了:
let url = NSURL(string: "http://www.www.www/upload/8590")
let request = NSMutableURLRequest(url: url! as URL)
let boundary = "------------------------your_boundary"
request.httpMethod = "POST"
request.setValue("ios", forHTTPHeaderField: "client")
request.setValue(Constants.AUTH_KEY, forHTTPHeaderField: Constants.AUTH_KEY_key)
request.setValue("Bearer " + SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key)!, forHTTPHeaderField: Constants.AUTH_AUTHORIZATION_key)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var movieData: NSData?
do {
movieData = try NSData(contentsOfFile: fileurl.path, options: NSData.ReadingOptions.alwaysMapped)
print(movieData)
} catch _ {
movieData = nil
return
}
let body = NSMutableData()
// change file name whatever you want
let filename = "upload.mov"
let mimetype = "video/mov"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(movieData! as Data)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
guard let _:NSData = data as! NSData, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(dataString)
}
task.resume()
这也会抛出这样的错误:
{"status":500,"message":"An Error Occuredu'file'","result":"Traceback (most recent call last):\n File \"/var/www/wb_ios/wb_app/views.py\", line 104, in post\n file_obj = request.data['file']\n File \"/usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py\", line 85, in __getitem__\n raise MultiValueDictKeyError(repr(key))\nMultiValueDictKeyError: \"u'file'\"\n"})
Swift3.0
Alamofire.upload(multipartFormData: { MultipartFormData in
for (key, value) in parameter {
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
// here you can upload only mp4 video
multipartFormData.append(self.fileurl!, withName: "file", fileName: "video.mp4", mimeType: "video/mp4")
// here you can upload any type of video
multipartFormData.append((self.fileurl.data(using: String.Encoding.utf8, allowLossyConversion: false))!, withName: "File")
print(MultipartFormData)
},to:"http://www.www.www/upload/8590",headers: ["Authorization": "Bearer \(SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key))"]
)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value ?? String())
print(response.data ?? NSData())
// send to completion block
completion(response.data as AnyObject? ?? NSData())
}
case .failure(let encodingError):
print(encodingError)
errorOccured(encodingError as NSError?)
}
}
我搜索了很长时间,但没有找到任何关于如何执行此操作的好资源。 api 需要一个表单参数 "user_id"(现在将其作为 urlpath 而不是表单参数发送) 和视频文件的其他 "file"。请使用 URLSession Task 或 iOS.
的任何库提供一些代码示例尝试过 Alamofire:
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(self.fileurl, withName: "file")
}, to:"http://www.www.www/upload/8590",
headers: ["Authorization": "Bearer \(SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key))"] )
{ (result) in
switch result {
case .success(let upload, _ , _):
upload.uploadProgress(closure: { (progress) in
print("uploding>>>>>>")
})
upload.responseJSON { response in
print(response)
print("done")
}
case .failure(let encodingError):
print("failed")
print(encodingError)
}
这从服务器抛出 500,表示无法使用 UTF-8 编码读取 Header 第一个字节。
message = "An Error OccuredInvalid header string: 'utf8' codec can't decode byte 0x9b in position 1: invalid start byte";
result = "Traceback (most recent call last):\n File \"/var/www/wb_ios/wb_app/views.py\", line 94, in post\n user_auth = jwt_decode_handler(auth).get('sub')\n File \"/usr/local/lib/python2.7/dist-packages/rest_framework_jwt/utils.py\", line 104, in jwt_decode_handler\n unverified_payload = jwt.decode(token, None, False)\n File \"/usr/local/lib/python2.7/dist-packages/jwt/api_jwt.py\", line 70, in decode\n payload, signing_input, header, signature = self._load(jwt)\n File \"/usr/local/lib/python2.7/dist-packages/jwt/api_jws.py\", line 177, in _load\n raise DecodeError('Invalid header string: %s' % e)\nDecodeError: Invalid header string: 'utf8' codec can't decode byte 0x9b in position 1: invalid start byte\n";
status = 500;
}
另外,我可以使用邮递员成功发送视频。使用如图所示的 form-data 字段。 body Headers
最后我也试了:
let url = NSURL(string: "http://www.www.www/upload/8590")
let request = NSMutableURLRequest(url: url! as URL)
let boundary = "------------------------your_boundary"
request.httpMethod = "POST"
request.setValue("ios", forHTTPHeaderField: "client")
request.setValue(Constants.AUTH_KEY, forHTTPHeaderField: Constants.AUTH_KEY_key)
request.setValue("Bearer " + SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key)!, forHTTPHeaderField: Constants.AUTH_AUTHORIZATION_key)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var movieData: NSData?
do {
movieData = try NSData(contentsOfFile: fileurl.path, options: NSData.ReadingOptions.alwaysMapped)
print(movieData)
} catch _ {
movieData = nil
return
}
let body = NSMutableData()
// change file name whatever you want
let filename = "upload.mov"
let mimetype = "video/mov"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(movieData! as Data)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
guard let _:NSData = data as! NSData, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(dataString)
}
task.resume()
这也会抛出这样的错误:
{"status":500,"message":"An Error Occuredu'file'","result":"Traceback (most recent call last):\n File \"/var/www/wb_ios/wb_app/views.py\", line 104, in post\n file_obj = request.data['file']\n File \"/usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py\", line 85, in __getitem__\n raise MultiValueDictKeyError(repr(key))\nMultiValueDictKeyError: \"u'file'\"\n"})
Swift3.0
Alamofire.upload(multipartFormData: { MultipartFormData in
for (key, value) in parameter {
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
// here you can upload only mp4 video
multipartFormData.append(self.fileurl!, withName: "file", fileName: "video.mp4", mimeType: "video/mp4")
// here you can upload any type of video
multipartFormData.append((self.fileurl.data(using: String.Encoding.utf8, allowLossyConversion: false))!, withName: "File")
print(MultipartFormData)
},to:"http://www.www.www/upload/8590",headers: ["Authorization": "Bearer \(SharedPreferences.preferences.getKeyValue(key: Constants.AUTH_TOKEN_key))"]
)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value ?? String())
print(response.data ?? NSData())
// send to completion block
completion(response.data as AnyObject? ?? NSData())
}
case .failure(let encodingError):
print(encodingError)
errorOccured(encodingError as NSError?)
}
}