2015-04-14 20 views
11

tôi đang gặp vấn đề với tải lên hình ảnh với nhiều phần dữ liệu dạngTải lên hình ảnh với nhiều phần dữ liệu form-data iOS trong Swift

đây là mã của tôi sử dụng từ này 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 

sau đó tôi sử dụng NSURLSession để áp dụng các yêu cầu

máy chủ nói rằng tôi đã không chọn hình ảnh để tải lên tôi chỉ muốn tải lên hình ảnh cho bây giờ

làm tôi phải sử dụng con đường s của hình ảnh để tải lên bất kỳ hình ảnh hoặc dữ liệu của nó là đủ?

tôi có bỏ lỡ bất kỳ điều gì, bất kỳ trợ giúp nào để hiểu điều này không?

Trả lời

4
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() 

} 
+1

lỗi tương tự, bạn có giải thích nào khác không? , và tên 'name' và' filename' ở đây trong dòng này 'body.appendFormat (" Content-Disposition: form-data; name = \ "\ (tên tệp) \"; filename = \ "pen111.png \" \ r \ n ")', có bất kỳ khóa nào tôi sử dụng từ mã php giống như tên biểu mẫu hay cái gì khác trong cùng một dòng không, nhờ tên –

+2

là chìa khóa của hình ảnh, như thuộc tính được gọi là tên trong thẻ đầu vào (html) , điều quan trọng là, nếu bạn nhận được tệp tải lên trong php, hãy sử dụng '$ photo = $ _FILES ['file']' (thinkphp); bạn phải đặt tên 'file'; tên tệp là tên tệp hình ảnh, như "aaaa.png", bạn có thể thay đổi tên của chính mình @Panda – jansma

+0

@jansma Cảm ơn bạn đã nhận xét này về thông số "tên"! Bạn đã giúp tôi hiểu lý do tại sao một API cụ thể đã từ chối dữ liệu của tôi. Chúc mừng. – Moritz

1

Điều đầu tiên tôi nhận thấy là application/octet-stream như Conten-Type, điều này thường được sử dụng khi các loại tập tin không rõ. Một số khung/thư viện web sẽ từ chối loại nội dung này nếu cần hình ảnh.

Thứ hai, tôi không thể nhìn thấy độ dài bài bất cứ nơi nào, cố gắng thêm nó:

body.appendString("--\(boundary)--\r\n") 

// set the content-length 
request.setValue("\(body.length)", forHTTPHeaderField:"Content-Length") 
+0

Xin lỗi vì đã trả lời trễ và cảm ơn vì đã cố gắng trợ giúp, tôi đã cập nhật mã bằng 'content-Type' và' Content-Length' nhưng vẫn gặp lỗi tương tự, bạn có đề xuất gì khác không? và cũng có một cái gì đó mà tôi không hiểu là có bất kỳ chìa khóa tôi sử dụng từ mã php như 'form-name' hoặc cái gì khác, là dòng này ok' body.appendString ("Content-Disposition: form-data; name = \ "image \"; filename = \ "image.png \" \ r \ n ")'? –

+1

Có, tên = \ "hình ảnh \" thực sự chứa tên trường bạn đang tải lên hình ảnh. Vì vậy, nếu trong biểu mẫu của bạn, bạn có trường hình ảnh có tên là 'trường hình ảnh', bạn phải viết tên = \ "trường hình ảnh \" – bontoJR

5

phiên bản của tôi rằng 100% công trình. Có thể nó sẽ giúp được bạn.

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/jpg\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 
} 
+0

cảm ơn bạn đã trả lời!) Tôi chỉ cần thêm vào giải pháp request1.setValue ("gzip, deflate", forHTTPHeaderField: "Accept-Encoding") và hình ảnh của tôi đã tải lên – ajjnix

+0

Wow. Một cái gì đó tôi đang suy nghĩ, nếu bạn C haveNG phải gửi các trường nhập văn bản? – Fattie

+0

Tạo biên dạng là gì? – Priyal

0

tôi thực hiện Tải lên hình ảnh sử dụng Multi-gia Swift 4:

Đây là mã. Hãy có một cái nhìn

//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)" 
} 
0

Tìm hiểu lớp tùy chỉnh của tôi trên GitHub AGUploadImage

Bạn có thể gửi đơn và nhiều hình ảnh, thiết lập quan trọng tham số và thông tin hình ảnh trên ImageStructInfo struct có sẵn như thế nào.

let parameter: [String: Any] = [ 
    "user_id": 12, 
    "image": ImageStructInfo(fileName: "image.jpg", type: "image/jpg", data: #imageLiteral(resourceName: "TempImage").toData()) 
] 

Mã hình ảnh tải lên rất đơn giản bằng cách sử dụng clouser, mã bên dưới.

AGUploadImage(url: "Url", parameter: parameter).responseJSON { (data, error) in 
    if error != nil{ 
     print("error") 
    } 
    else{ 
     print(data) 
    } 
} 
Các vấn đề liên quan