使用Swift 4将Pdf,Docx和图像文件上传到服务器

The*_*y77 3 file-upload ios 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 + "&section_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)"
}
Run Code Online (Sandbox Code Playgroud)

有些解决方案告诉我将文件转换为Data,然后将其发送到服务器,而另一些解决方案则告诉我直接将文件路径添加到您的身体。需要帮忙!

ske*_*ech 5

一个基本的错误是您在实例上使用的dataTask不是uploadTaskURLSession,例如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)
    }
Run Code Online (Sandbox Code Playgroud)

循环意味着每一项数据(在这种情况下为图像)之前都带有边界字符串,并且在最后一项数据之后添加了结束边界字符串(即以双连字符结​​尾的边界字符串)。