我是swift的新手,我一直在尝试从Iphone的本地存储上传pdf,docx和图像文件。我编写了一段代码,但它没有工作,我一直从响应中获得 状态代码:415 。这是我的代码:
func uploadfileToServer(completed: @escaping () -> ()){
let theTitle = labelTitle.text
guard let url = URL(string: "http://www.--------.com/assignment/post") else {return}
var request = URLRequest.init(url: url)
request.httpMethod = "POST"
request.addValue("cf7ab8c9d4efae82b575eabd6bec76cbb86c6108391e036387f3dd5356a582171519367747000", forHTTPHeaderField: "api_key")
let boundary = generateBoundaryString()
// Set Content-Type in HTTP header.
let boundaryConstant = boundary // This should be auto-generated.
let contentType = "multipart/form-data; boundary=" + boundaryConstant
let directory = NSTemporaryDirectory()
let fileName = NSUUID().uuidString
// This returns a URL? even though it is an NSURL class method
let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])
let fileNamee = fullURL?.path
let mimeType = "text/csv"
let fieldName = "uploadFile"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
var dataString = "--\(boundaryConstant)\r\n"
dataString += "\r\n"
dataString += "--\(boundaryConstant)--\r\n"
var theBody = Data()
let sectionID : String?
sectionID = nil
let str = "user_id=\(savedsesuid!)" + "&school_id=" + SCHOOL_ID + "&class_id=" + classID + "§ion_id=\(sectionID)" + "&subject_id=\(id)"
if let b = str.data(using: .utf8) {
theBody.append(b)
}
let str1 = "&atitle=" + theTitle! + "&class_id=" + classID
if let c = str1.data(using: .utf8){
theBody.append(c)
}
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
var filePath = documentDirectory.appendingFormat("/")
filePath = filePath.appendingFormat("/Users/prashanna/Desktop/ebusiness_topic_1_handout.pdf")
let pdfData = NSData(contentsOfFile: filePath)
let file = "&afile=" + "\(pdfData)"
if let d = file.data(using: .utf8){
theBody.append(d)
}
print(theBody)
request.httpBody = theBody
URLSession.shared.dataTask(with: request) { (data, response, error) in
print(response)
if let httpResponse = response as? HTTPURLResponse {
let statuscode = httpResponse.statusCode
if statuscode == 401{
self.displayMessage(userMessage: "Sending Failed")
}else if statuscode == 200{
if error == nil{
do{
self.displayMessage(userMessage: "File Successfully Uploaded!")
DispatchQueue.main.async {
completed()
}
}
}
}
}
}.resume()
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
有些解决方案告诉我将文件转换为数据,然后将其发送到服务器,而有些人则说直接将文件路径添加到您的身体。 需要帮助!
答案 0 :(得分:4)
一个基本错误是您在dataTask
个实例上使用的是URLSession
而不是uploadTask,例如uploadTask(with:from:completionHandler:)
构建正文数据
以下是我自己的代码(如下面的评论中所要求的)关于如何构建正文数据的一般示例:
// imagesURLS is an optional array of URLs, i.e. imageURLS:[URL]?
if let imgURLs = imagesURLS {
for f in imgURLs {
let filename = f.lastPathComponent
let splitName = filename.split(separator: ".")
let name = String(describing: splitName.first)
let filetype = String(describing: splitName.last)
let imgBoundary = "\r\n--\(boundary)\r\nContent-Type: image/\(filetype)\r\nContent-Disposition: form-data; filename=\(filename); name=\(name)\r\n\r\n"
if let d = imgBoundary.data(using: .utf8) {
bodyData.append(d)
}
do {
let imgData = try Data(contentsOf:f, options:[])
bodyData.append(imgData)
}
catch {
// can't load image data
}
}
}
let closingBoundary = "\r\n--\(boundary)--"
if let d = closingBoundary.data(using: .utf8) {
bodyData.append(d)
}
循环意味着每个数据项(在这种情况下是图像)前面都有一个边界字符串,在最后一个数据项之后添加了结束边界字符串(即以双连字符结尾的那个)。 / p>
答案 1 :(得分:1)
这适用于我,在Swift4中:
func uploadFiles(_ urlPath: [URL]){
if let url = URL(string: "YourURL"){
var request = URLRequest(url: url)
let boundary:String = "Boundary-\(UUID().uuidString)"
request.httpMethod = "POST"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["Content-Type": "multipart/form-data; boundary=----\(boundary)"]
for path in urlPath{
do{
var data2: Data = Data()
var data: Data = Data()
data2 = try NSData.init(contentsOf: URL.init(fileURLWithPath: path.absoluteString, isDirectory: true)) as Data
/* Use this if you have to send a JSON too.
let dic:[String:Any] = [
"Key":Value,
"Key":Value
]
for (key,value) in dic{
data.append("------\(boundary)\r\n")
data.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
data.append("\(value)\r\n")
}
*/
data.append("------\(boundary)\r\n")
//Here you have to change the Content-Type
data.append("Content-Disposition: form-data; name=\"file\"; filename=\"YourFileName\"\r\n")
data.append("Content-Type: application/YourType\r\n\r\n")
data.append(data2)
data.append("\r\n")
data.append("------\(boundary)--")
request.httpBody = data
}catch let e{
//Your errors
}
DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).sync {
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { (dataS, aResponse, error) in
if let erros = error{
//Your errors
}else{
do{
let responseObj = try JSONSerialization.jsonObject(with: dataS!, options: JSONSerialization.ReadingOptions(rawValue:0)) as! [String:Any]
}catch let e{
}
}
}).resume()
}
}
}
}
extension Data{
mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {
if let data = string.data(using: encoding) {
append(data)
}
}
}
答案 2 :(得分:0)
上传图片的示例代码为:
func uploadImage(){
var imageToUpload:UIImage = UIImage()
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if let dirPath = paths.first
{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("Image2.png") //Your image name here
let image = UIImage(contentsOfFile: imageURL.path)
imageToUpload = image!
}
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(UIImageJPEGRepresentation(imageToUpload, 1)!, withName: "Prescription", fileName: "Profile_Image.jpeg", mimeType: "image/jpeg")
}, to:"you_URL_here")
{ (result) in
switch result {
case .success(let upload, _, _):
print(result)
upload.uploadProgress(closure: { (progress) in
print(progress)
})
upload.responseJSON { response in
//print response.result
print(response);
}
case .failure(let encodingError):
print(encodingError);
}
}
}