Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用Swift 4将Pdf、Docx和图像文件上载到服务器_Ios_Swift_File Upload - Fatal编程技术网

Ios 使用Swift 4将Pdf、Docx和图像文件上载到服务器

Ios 使用Swift 4将Pdf、Docx和图像文件上载到服务器,ios,swift,file-upload,Ios,Swift,File Upload,我是swift的新手,我一直在尝试从Iphone的本地存储中上传pdf、docx和图像文件。我已经写了一个代码,但它不起作用,我不断从回复中得到状态代码:415。这是我的密码: func uploadfileToServer(completed: @escaping () -> ()){ let theTitle = labelTitle.text guard let url = URL(string: "http://www.--------.com/assignm

我是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)"
}
有些解决方案告诉我将文件转换为数据,然后将其发送到服务器,而有些解决方案则告诉我直接将文件路径添加到您的正文中。
需要帮助

上传图像的示例代码为:

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);
        }
    }

}

一个基本错误是,您在
URLSession
实例上使用的是
dataTask
,而不是
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)
    }

循环意味着每个数据项(在本例中为图像)前面都有一个边界字符串,在最后一个数据项之后添加结束边界字符串(即以双连字符结尾的边界字符串)。

在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)
    }
}
}

对不起,老兄,我不用阿拉莫菲尔!您对边界字符串的使用看起来也不正确,您有一个连接的
dataString
实例,但当实际数据应该在开始和结束边界字符串之间时,您不使用该实例。如果您确实有多个项目,那么在使用结束边界字符串终止主体数据之前,边界字符串需要打开其中的每个项目。除此之外,这是一个遵守服务器期望的案例。我从自己的代码中添加了一个通用示例,因为在不了解服务器要求的情况下,我需要花费很长时间来解包您需要的内容。希望这有帮助。我如何获得imagesURLS?我在代码的开头放了一条注释,解释imageURLS是什么,原因是这进一步回到了不相关的代码中,用户选择了一个文件夹,代码在该文件夹中构建了一个图像URL列表。您需要根据自己的需要调整代码,使用您拥有的数据和服务器的边界要求。