代码之家  ›  专栏  ›  技术社区  ›  TheSwiftGuy77

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

  •  6
  • TheSwiftGuy77  · 技术社区  · 6 年前

    我是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)"
    }
    

    有些解决方案告诉我将文件转换为数据,然后将其发送到服务器,而有些解决方案则说直接将文件路径添加到您的正文中。 需要帮助!

    3 回复  |  直到 6 年前
        1
  •  7
  •   sketchyTech    6 年前

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

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

        2
  •  2
  •   Genaro Arvizu    6 年前

    这对我来说很有用,在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)
        }
    }
    }
    
        3
  •  0
  •   Abhirajsinh Thakore    6 年前

    上载图像的示例代码为:

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