【问题标题】:Upload image with multipart form-data iOS in Swift在 Swift 中使用多部分表单数据 iOS 上传图像
【发布时间】:2015-06-19 19:37:42
【问题描述】:

我在使用 multipart-form 上传图片时遇到问题

这是我从 answer 使用的代码

    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"

    var boundary = generateBoundaryString()
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    var body = NSMutableData()

    if self.img.image != nil {
        var imageData = UIImagePNGRepresentation(self.img.image)

        if imageData != nil {
            body.appendString("--\(boundary)\r\n")
            body.appendString("Content-Disposition: form-data; name=\"image\"; filename=\"image.png\"\r\n")
            body.appendString("Content-Type: image/png\r\n\r\n")
            body.appendData(imageData!)
            body.appendString("\r\n")
        }

    }

    body.appendString("--\(boundary)--\r\n")
    request.setValue("\(body.length)", forHTTPHeaderField:"Content-Length")
    request.HTTPBody = body

然后我使用 NSURLSession 来应用请求

服务器说我没有选择上传图片我现在只想上传图片

我必须使用图像路径来上传任何图像还是它的数据就足够了?

我有什么想念的吗,对理解这一点有什么帮助吗?

【问题讨论】:

    标签: ios image swift file-upload multipartform-data


    【解决方案1】:
    public func UPLOADIMG(url: String,parameters: Dictionary<String,AnyObject>?,filename:String,image:UIImage, success:((NSDictionary) -> Void)!, failed:((NSDictionary) -> Void)!, errord:((NSError) -> Void)!) {
            var TWITTERFON_FORM_BOUNDARY:String = "AaB03x"
            let url = NSURL(string: url)!
            var request:NSMutableURLRequest = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 10)
            var MPboundary:String = "--\(TWITTERFON_FORM_BOUNDARY)"
            var endMPboundary:String = "\(MPboundary)--"
            //convert UIImage to NSData            
            var data:NSData = UIImagePNGRepresentation(image)
            var body:NSMutableString = NSMutableString();
            // with other params
            if parameters != nil {
                for (key, value) in parameters! {
                    body.appendFormat("\(MPboundary)\r\n")
                    body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                    body.appendFormat("\(value)\r\n")
                }
            }
            // set upload image, name is the key of image 
            body.appendFormat("%@\r\n",MPboundary)
            body.appendFormat("Content-Disposition: form-data; name=\"\(filename)\"; filename=\"pen111.png\"\r\n")
            body.appendFormat("Content-Type: image/png\r\n\r\n")
            var end:String = "\r\n\(endMPboundary)"
            var myRequestData:NSMutableData = NSMutableData();
            myRequestData.appendData(body.dataUsingEncoding(NSUTF8StringEncoding)!)
            myRequestData.appendData(data)
            myRequestData.appendData(end.dataUsingEncoding(NSUTF8StringEncoding)!)
            var content:String = "multipart/form-data; boundary=\(TWITTERFON_FORM_BOUNDARY)"
            request.setValue(content, forHTTPHeaderField: "Content-Type")
            request.setValue("\(myRequestData.length)", forHTTPHeaderField: "Content-Length")
            request.HTTPBody = myRequestData
            request.HTTPMethod = "POST"
            //        var conn:NSURLConnection = NSURLConnection(request: request, delegate: self)!
            let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {
                data, response, error in
                if error != nil {
                    println(error)
                    errord(error)
                    return
                }
                var parseError: NSError?
                let responseObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError)
                if let responseDictionary = responseObject as? NSDictionary {
                    success(responseDictionary)
                } else {
                }
    
            })
            task.resume()
    
    }
    

    【讨论】:

    • 同样的错误,你还有其他解释吗? ,这是什么namefilename在这一行body.appendFormat("Content-Disposition: form-data; name=\"\(filename)\"; filename=\"pen111.png\"\r\n"),我在php代码中使用了任何密钥,例如form-name或同一行中的其他内容,谢谢
    • name是图片的key,就像输入标签(html)中的name属性一样,重要的是,如果你在php中获取上传文件使用$photo = $_FILES['file'](thinkphp);您必须设置名称 file ; filename 为图片文件名,如“aaaa.png”你可以自己改名字@Panda
    • @jansma 感谢您对“名称”参数的评论!您帮助我了解了为什么特定 API 拒绝我的数据。干杯。
    • @jansma,我们可以添加 URL 作为文件名吗?
    • @jansma,我想用文件发送一个 url。如何发送?
    【解决方案2】:

    我注意到的第一件事是application/octet-streamConten-Type,这通常在文件类型未知的情况下使用。如果需要图像,一些 Web 框架/库将拒绝此内容类型。

    其次,我在任何地方都看不到帖子长度,尝试添加它:

    body.appendString("--\(boundary)--\r\n")
    
    // set the content-length
    request.setValue("\(body.length)", forHTTPHeaderField:"Content-Length")
    

    【讨论】:

    • 抱歉回复晚了,感谢您的帮助,我用content-TypeContent-Length 更新了代码,但仍然出现同样的错误,您还有什么建议吗?还有一些我不明白的东西是我从form-name之类的php代码中使用的任何密钥或其他东西,这条线好吗body.appendString("Content-Disposition: form-data; name=\"image\"; filename=\"image.png\"\r\n")
    • 是的,name=\"image\" 实际上包含您上传图片的字段名称。因此,如果您的表单中有名为“image-field”的图像字段,则必须编写 name=\"image-field\"
    【解决方案3】:

    我的版本 100% 有效。也许对你有帮助。

    let url = "http://server/upload"
    let img = UIImage(contentsOfFile: fullPath)
    let data: NSData = UIImageJPEGRepresentation(img, 1)
    
    sendFile(url, 
        fileName:"one.jpg", 
        data:data, 
        completionHandler: completionHandler:{
            (result:Bool, isNoInternetConnection:Bool) -> Void in
    
                // ...     
                NSLog("Complete: \(result)")
        }
    )
    
    
    func sendFile(
        urlPath:String,
        fileName:String,
        data:NSData,
        completionHandler: (NSURLResponse!, NSData!, NSError!) -> Void){
            
            var url: NSURL = NSURL(string: urlPath)!
            var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
            
            request1.HTTPMethod = "POST"
            
            let boundary = generateBoundary()
            let fullData = photoDataToFormData(data,boundary:boundary,fileName:fileName)
            
            request1.setValue("multipart/form-data; boundary=" + boundary,
                forHTTPHeaderField: "Content-Type")
            
            // REQUIRED!
            request1.setValue(String(fullData.length), forHTTPHeaderField: "Content-Length")
            
            request1.HTTPBody = fullData
            request1.HTTPShouldHandleCookies = false
            
            let queue:NSOperationQueue = NSOperationQueue()
            
            NSURLConnection.sendAsynchronousRequest(
                request1,
                queue: queue,
                completionHandler:completionHandler)
    }
    
    // this is a very verbose version of that function
    // you can shorten it, but i left it as-is for clarity
    // and as an example
    func photoDataToFormData(data:NSData,boundary:String,fileName:String) -> NSData {
        var fullData = NSMutableData()
        
        // 1 - Boundary should start with --
        let lineOne = "--" + boundary + "\r\n"
        fullData.appendData(lineOne.dataUsingEncoding(
            NSUTF8StringEncoding,
            allowLossyConversion: false)!)
        
        // 2
        let lineTwo = "Content-Disposition: form-data; name=\"image\"; filename=\"" + fileName + "\"\r\n"
        NSLog(lineTwo)
        fullData.appendData(lineTwo.dataUsingEncoding(
            NSUTF8StringEncoding,
            allowLossyConversion: false)!)
        
        // 3
        let lineThree = "Content-Type: image/jpeg\r\n\r\n"
        fullData.appendData(lineThree.dataUsingEncoding(
            NSUTF8StringEncoding,
            allowLossyConversion: false)!)
        
        // 4
        fullData.appendData(data)
        
        // 5
        let lineFive = "\r\n"
        fullData.appendData(lineFive.dataUsingEncoding(
            NSUTF8StringEncoding,
            allowLossyConversion: false)!)
        
        // 6 - The end. Notice -- at the start and at the end
        let lineSix = "--" + boundary + "--\r\n"
        fullData.appendData(lineSix.dataUsingEncoding(
            NSUTF8StringEncoding,
            allowLossyConversion: false)!)
        
        return fullData
    }
    

    【讨论】:

    • 感谢您的回答!)我只是添加了解决方案 request1.setValue("gzip, deflate", forHTTPHeaderField: "Accept-Encoding") 并且我的图片确实上传了
    • 哇。我在想,如果您还必须发送文本输入字段怎么办?
    • 什么是generateBoundary?
    • 对于未来的情况:使用像 Moya 这样的框架会更容易做到这一点。
    【解决方案4】:

    我在 Swift 4 中使用 Multi-part 实现了上传图片:

    这里是代码。请看一下

    //MARK: Uplaod User Profile Pic
    func uploadImageToServerFromApp(nameOfApi : NSString, parameters : NSString, uploadedImage : UIImage, withCurrentTask :RequestType, andDelegate :AnyObject)->Void {
        if self.isConnectedToNetwork(){
            currentTask = withCurrentTask
            let myRequestUrl = NSString(format: "%@%@%@",GlobalConstants.KBaseURL,nameOfApi,parameters)
            let url = (myRequestUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed))!
            var request : NSMutableURLRequest = NSMutableURLRequest()
            request = URLRequest(url: URL(string:url as String)!) as! NSMutableURLRequest
            request.httpMethod = "POST"
            let boundary = generateBoundaryString()
            //define the multipart request type
            request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
            let image_data = UIImagePNGRepresentation(uploadedImage)
            if(image_data == nil){
                return
            }
            let body = NSMutableData()
            let fname = "image.png"
            let mimetype = "image/png"
            //define the data post parameter
            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"image\"\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append("hi\r\n".data(using: String.Encoding.utf8)!)
            body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Disposition:form-data; name=\"image\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
            body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
            body.append(image_data!)
            body.append("\r\n".data(using: String.Encoding.utf8)!)
            body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
            request.httpBody = body as Data
            let session = URLSession.shared
            let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
                guard let data = data, error == nil else {                                                 // check for fundamental networking error
                    // print("error=\(String(describing: error))")
                    self.showAlertMessage(title: "App name", message: "Server not responding, please try later")
                    return
                }
                if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
                    // print("statusCode should be 200, but is \(httpStatus.statusCode)")
                    // print("response = \(String(describing: response))")
                    self.delegate?.internetConnectionFailedIssue()
                }else{
                    do {
                        self.responseDictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! NSDictionary
                        // self.Responsedata = data as NSData
                        //self.responseDictionary = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: AnyObject] as NSDictionary;
    
                        self.delegate?.responseReceived()
                    } catch {
                        //print("error serializing JSON: \(error)")
                    }
                }
            }
            task.resume()
        }
        else{
            // print("Internet Connection not Available!")
            self.showAlertMessage(title: "App Name", message: "No Internet Connection..")
        }
    }
    
    func generateBoundaryString() -> String
    {
        return "Boundary-\(NSUUID().uuidString)"
    }
    

    【讨论】:

    • 你不需要在标题中设置'Content-Length'吗?
    • 你可以加亲爱的,,。 body.setValue("(myRequestData.length)", forHTTPHeaderField: "Content-Length")
    • 是的。我们必须添加“Content-Length”,否则 multipart 不起作用?
    【解决方案5】:
    class func postMultiPartdata( postdatadictionary: [AnyHashable: Any], apikey: String, completion: @escaping (Any) -> () ) {
    
            if Utils().isConnectedToNetwork() == false
            {
                Utils().showMessage("Check internet")
                return
            }
    
            let strURL = "http://redspark.biz/dropp/api/\(apikey)"
    
            let url = URL(string: strURL)
            var urlRequest = URLRequest(url: url!)
    
            urlRequest.httpMethod = "POST"
    
            let body = NSMutableData();
            let boundary = "---------------------------14737809831466499882746641449"
            let contentType = "multipart/form-data; boundary=\(boundary)"
            urlRequest.addValue(contentType, forHTTPHeaderField: "Content-Type")
    
            for (key, value) in postdatadictionary {
    
                if(value is Data)
                {
                    let  TimeStamp = "\(Date().timeIntervalSince1970 * 1000)"
    
                    body.append("--\(boundary)\r\n".data(using: .utf8)!)
                    body.append("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(TimeStamp)\"\r\n".data(using:.utf8)!)
                    body.append("field_mobileinfo_image\r\n".data(using: .utf8)!)
    
                    body.append("--\(boundary)\r\n".data(using: .utf8)!)
                    body.append("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".data(using: .utf8)!)
                    body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
    
    //                var imgData: Data? = nil
    //                if let aKey = value as? Data {
    //                    imgData = NSData(data: aKey) as Data
    //                }
    
                    body.append(value as! Data)
    
                }
                else
                {
                    if let anEncoding = "--\(boundary)\r\n".data(using: .utf8) {
                        body.append(anEncoding)
                    }
                    if let anEncoding = "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8) {
                        body.append(anEncoding)
                    }
                    if let aKey = postdatadictionary[key], let anEncoding = "\(aKey)".data(using: .utf8) {
                        body.append(anEncoding)
                    }
                    if let anEncoding = "\r\n".data(using: .utf8) {
                        body.append(anEncoding)
                    }
                  }
                }
    
            if let anEncoding = "--\(boundary)--\r\n".data(using: .utf8) {
                body.append(anEncoding)
            }
            // setting the body of the post to the reqeust
            urlRequest.httpBody = body as Data
    
            URLSession.shared.dataTask(with:urlRequest) { (data, response, error) in
                if error != nil {
    
                    print(error!)
                    completion("")
                } else {
                    var dictonary:NSDictionary?
                    do {
                        dictonary = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
                        if let myDictionary = dictonary
                        {
                            completion(myDictionary)
                        }
                    } catch let error as NSError {
                        completion(error)
                    }
                }
    
                Utils().HideLoader()
    
                }.resume()
    
            }
    

    【讨论】:

      【解决方案6】:

      无需使用任何库来使用多部分请求上传图片。

      Swift 4.2

      func uploadImage(paramName: String, fileName: String, image: UIImage) {
          let url = URL(string: "http://api-host-name/v1/api/uploadfile/single")
      
          // generate boundary string using a unique per-app string
          let boundary = UUID().uuidString
      
          let session = URLSession.shared
      
          // Set the URLRequest to POST and to the specified URL
          var urlRequest = URLRequest(url: url!)
          urlRequest.httpMethod = "POST"
      
          // Set Content-Type Header to multipart/form-data, this is equivalent to submitting form data with file upload in a web browser
          // And the boundary is also set here
          urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
      
          var data = Data()
      
          // Add the image data to the raw http request data
          data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
          data.append("Content-Disposition: form-data; name=\"\(paramName)\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!)
          data.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!)
          data.append(image.pngData()!)
      
          data.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
      
          // Send a POST request to the URL, with the data we created earlier
          session.uploadTask(with: urlRequest, from: data, completionHandler: { responseData, response, error in
              if error == nil {
                  let jsonData = try? JSONSerialization.jsonObject(with: responseData!, options: .allowFragments)
                  if let json = jsonData as? [String: Any] {
                      print(json)
                  }
              }
          }).resume()
      }
      

      如果你有任何header要添加,可以通过urlRequest.setValue方法添加。

      来源:https://fluffy.es/upload-image-to-server/

      【讨论】:

      • 关闭分隔符 (\r\n--\(boundary)--) 之后的最后一个 \r\n 是可选的。
      • 如何添加额外的json输入?
      • 我把它从 data.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!) 改成 data.append("Content -Type: \"content-type header\"\r\n\r\n".data(using: .utf8)!) 为我结束这个coe的工作
      • 嗨!你能说 paramName 是 base64String 吗?
      【解决方案7】:

      在此处遵循这些答案是我的实现,其中包含视频和音频的具体示例。注意元素之间的边界是 --boundary,而最后一个边界是 --boudary--

          let url = URL(string: "https://...")!
          let boundary = UUID().uuidString
          var request = URLRequest(url: url)
          request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
          request.httpMethod = "post"
          var data = Data()
          data.addMultiPart(boundary: boundary, name: "metadata", filename: "metadata.json", contentType: "application/json", data: metaData)
          
          let ext = fileUrl.pathExtension.lowercased()
          let isImage = ["jpg","jpeg","png"].contains(ext)
          let contentType = isImage ? "image/\(ext)" : "video/\(ext)"
          let mediaData = try! Data(contentsOf: fileUrl)
          data.addMultiPart(boundary: boundary, name: "file", filename: fileUrl.lastPathComponent, contentType: contentType, data: mediaData)
          data.addMultiPartEnd(boundary: boundary)
          request.httpBody = data
          let task = session.dataTask(with: request)
          task.resume()
      
      
      private extension Data {
      mutating func addMultiPart(boundary: String, name: String, filename: String, contentType: String, data: Data) {
          print("adding boundary: \(boundary), name: \(name), filename: \(filename), contentType: \(contentType) data length: \(data.count) ")
          self.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
          self.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!)
          self.append("Content-Type: \(contentType)\r\n\r\n".data(using: .utf8)!)
          self.append(data)
      }
      mutating func addMultiPartEnd(boundary: String) {
          self.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
      }
      

      }

      【讨论】:

        【解决方案8】:

        我建议repository。 您可以在 Podfile 中添加 pod 'MultipartForm',然后按照存储库自述文件中的示例进行操作:

        import MultipartForm
        
        let form = MultipartForm(parts: [
        MultipartForm.Part(name: "a", value: "1"),
        MultipartForm.Part(name: "b", value: "2"),
        MultipartForm.Part(name: "c", data: imageData, filename: "3.png", contentType: "image/png"),
        ])
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue(form.contentType, forHTTPHeaderField: "Content-Type")
        
        let task = session.uploadTask(with: request, from: form.bodyData)
        task.resume()
        

        它也支持 Swift 包管理器。

        【讨论】:

          【解决方案9】:
          extension URLRequest {
              
              mutating func setMultipartFormDataBody(params: [String: (Data, filename: String?)]) {
                  
                  let boundary = UUID().uuidString
                  
                  self.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
                  
                  var body = Data()
                  for (key, (data, filename)) in params {
                      body.append("--\(boundary)\r\n")
                      
                      
                      if let filename = filename {
                          body.append("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n")
                      }
                      else {
                          body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n")
                      }
                      
                      body.append("\r\n")
                      body.append(data)
                      body.append("\r\n")
                  }
                  
                  body.append("--\(boundary)--")
                  self.httpBody = body
              }
              
          }
          
          extension Data {
              mutating func append(_ s: String) {
                  self.append(s.data(using: .utf8)!)
              }
          }
          

          【讨论】:

            【解决方案10】:
            import Foundation
            
            struct MultipartFormDataRequest {
                private let boundary: String = UUID().uuidString
                var httpBody = NSMutableData()
                let url: URL
                
                init(url: URL) {
                    self.url = url
                }
                
                func addTextField(named name: String, value: String) {
                    httpBody.appendString(textFormField(named: name, value: value))
                }
                
                private func textFormField(named name: String, value: String) -> String {
                    var fieldString = "--\(boundary)\r\n"
                    fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n"
                    fieldString += "Content-Type: text/plain; charset=ISO-8859-1\r\n"
                    fieldString += "Content-Transfer-Encoding: 8bit\r\n"
                    fieldString += "\r\n"
                    fieldString += "\(value)\r\n"
                    
                    return fieldString
                }
                
                
                func addDataField(fieldName: String, fileName: String, data: Data, mimeType: String) {
                    httpBody.append(dataFormField(fieldName: fieldName,fileName:fileName,data: data, mimeType: mimeType))
                }
                
                private func dataFormField(fieldName: String,
                                           fileName: String,
                                           data: Data,
                                           mimeType: String) -> Data {
                    let fieldData = NSMutableData()
                    
                    fieldData.appendString("--\(boundary)\r\n")
                    fieldData.appendString("Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(fileName)\"\r\n")
                    fieldData.appendString("Content-Type: \(mimeType)\r\n")
                    fieldData.appendString("\r\n")
                    fieldData.append(data)
                    fieldData.appendString("\r\n")
                    return fieldData as Data
                }
                
                func asURLRequest() -> URLRequest {
                    var request = URLRequest(url: url)
                    
                    request.httpMethod = "POST"
                    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
                    
                    httpBody.appendString("--\(boundary)--")
                    request.httpBody = httpBody as Data
                    return request
                }
            }
            
            extension NSMutableData {
                func appendString(_ string: String) {
                    if let data = string.data(using: .utf8) {
                        self.append(data)
                    }
                }
            }
            
            
            extension URLSession {
                func dataTask(with request: MultipartFormDataRequest,
                              completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void)
                -> URLSessionDataTask {
                    return dataTask(with: request.asURLRequest(), completionHandler: completionHandler)
                }
            }
            

            使用该函数调用上传文件func

            func uploadFile(file:Data, fileName: String, fileExtension: String){
                var mimeType = "image/png"
                if fileExtension == "PDF" {
                    mimeType = "application/pdf"
                }
                let url = "https://v2.convertapi.com/upload"
            
                let request = MultipartFormDataRequest(url: URL(string: url)!)
                request.addDataField(fieldName:  "file", fileName: fileName, data: file, mimeType: mimeType)
                URLSession.shared.dataTask(with: request, completionHandler: {data,urlResponse,error in
                    
            
                }).resume()
            }
            

            #资源:

            https://www.donnywals.com/uploading-images-and-forms-to-a-server-using-urlsession/ https://orjpap.github.io/swift/http/ios/urlsession/2021/04/26/Multipart-Form-Requests.html

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-08-17
              • 1970-01-01
              • 1970-01-01
              • 2019-07-29
              • 1970-01-01
              • 1970-01-01
              • 2023-03-23
              • 2019-08-29
              相关资源
              最近更新 更多