Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading file with parameters using Alamofire

I am attempting to upload a file using Alamofire. The upload works fine when using a File (NSUrl), however, I cant seem to figure out how to use the NSData option?

This is what I have as a test:

 var url:NSURL = NSURL.URLWithString("http://localhost:8080/bike.jpeg")   var err: NSError?  var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)   Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload/test.png", imageData)         .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in             println(totalBytesWritten)         }         .responseJSON { (request, response, JSON, error) in             println(request)             println(response)            println(JSON)  } 

I am getting a status code 415?

Also, how can I send across additional params in the upload?

Thanks

EDIT

I wasn't setting the correct Content-Type:

var manager = Manager.sharedInstance manager.session.configuration.HTTPAdditionalHeaders = ["Content-Type": "application/octet-stream"]   let imageData: NSMutableData = NSMutableData.dataWithData(UIImageJPEGRepresentation(imageTest.image, 30));  Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload?attachmentName=file.jpg",  imageData)         .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in             println(totalBytesWritten)         }         .responseString { (request, response, JSON, error) in             println(request)             println(response)             println(JSON) } 

Still cant figure out how to send additional parameters along with the upload.

like image 624
user3432352 Avatar asked Sep 30 '14 13:09

user3432352


People also ask

Is Alamofire asynchronous?

Everything with Alamofire is asynchronous, which means you'll update the UI in an asynchronous manner: Hide the upload button, and show the progress view and activity view. While the file uploads, you call the progress handler with an updated percent.


2 Answers

Here is a simple function that requires the target upload url, parameters, and imageData and returns the URLRequestConvertible and NSData that Alamofire.upload requires to upload an image with parameters.

// this function creates the required URLRequestConvertible and NSData we need to use Alamofire.upload func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData) -> (URLRequestConvertible, NSData) {      // create url request to send     var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)     mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue     let boundaryConstant = "myRandomBoundary12345";     let contentType = "multipart/form-data;boundary="+boundaryConstant     mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")        // create upload data to send     let uploadData = NSMutableData()      // add image     uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)     uploadData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"file.png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)     uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)     uploadData.appendData(imageData)      // add parameters     for (key, value) in parameters {         uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)         uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!)     }     uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)        // return URLRequestConvertible and NSData     return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData) }     

Here's an example of how to use it (see CREATE AND SEND REQUEST):

// init paramters Dictionary var parameters = [     "task": "task",     "variable1": "var" ]  // add addtionial parameters parameters["userId"] = "27" parameters["body"] = "This is the body text."  // example image data let image = UIImage(named: "177143.jpg") let imageData = UIImagePNGRepresentation(image)    // CREATE AND SEND REQUEST ----------  let urlRequest = urlRequestWithComponents("http://example.com/uploadText/", parameters: parameters, imageData: imageData)  Alamofire.upload(urlRequest.0, urlRequest.1)     .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in         println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")     }     .responseJSON { (request, response, JSON, error) in         println("REQUEST \(request)")         println("RESPONSE \(response)")         println("JSON \(JSON)")         println("ERROR \(error)") }     

And if you need the php file for the target url (with an 'uploads' folder in the same directory):

// get picture variables $file       = $_FILES['file']['tmp_name']; $fileName   = $_FILES['file']['name']; $fileType   = $_FILES['file']['type'];  // check extension $allowedExts = array("jpg", "jpeg", "png"); $rootName = reset(explode(".", $fileName)); $extension = end(explode(".", $fileName));  // create new file name $time = time(); $newName = $rootName.$time.'.'.$extension;  // temporarily save file $moved = move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/".$newName ); if ($moved) $path = "uploads/".$newName;  $body = $_POST['body']; $userId = $_POST['userId'];   $time = time(); if ($moved) {     $fullUrl = "http://antiblank.com/testPhotoUpload/".$path;     $arrayToSend = array('status'=>'success','time'=>$time,'body'=>$body,'userId'=>$userId, "imageURL"=>$fullUrl); } else {     $arrayToSend = array('status'=>'FAILED','time'=>$time,'body'=>$body,'userId'=>$userId); }  header('Content-Type:application/json'); echo json_encode($arrayToSend); 
like image 179
antiblank Avatar answered Oct 22 '22 00:10

antiblank


Upload Photo / File with parameters and custom headers via Swift 3 & 4 and Alamofire 4

// import Alamofire func uploadWithAlamofire() {   let image = UIImage(named: "bodrum")!    // define parameters   let parameters = [     "hometown": "yalikavak",     "living": "istanbul"   ]    Alamofire.upload(multipartFormData: { multipartFormData in     if let imageData = UIImageJPEGRepresentation(image, 1) {       multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")     }      for (key, value) in parameters {       multipartFormData.append((value?.data(using: .utf8))!, withName: key)     }}, to: "upload_url", method: .post, headers: ["Authorization": "auth_token"],         encodingCompletion: { encodingResult in           switch encodingResult {           case .success(let upload, _, _):             upload.response { [weak self] response in               guard let strongSelf = self else {                 return               }               debugPrint(response)             }           case .failure(let encodingError):             print("error:\(encodingError)")           }   }) } 

via Swift 2 and Alamofire 3

  // import Alamofire   func uploadWithAlamofire() {     let image = UIImage(named: "myImage")!      // define parameters     let parameters = [       "hometown": "yalikavak",       "living": "istanbul"     ]      // Begin upload     Alamofire.upload(.POST, "upload_url",       // define your headers here       headers: ["Authorization": "auth_token"],       multipartFormData: { multipartFormData in          // import image to request         if let imageData = UIImageJPEGRepresentation(image, 1) {           multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "myImage.png", mimeType: "image/png")         }          // import parameters         for (key, value) in parameters {           multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)         }       }, // you can customise Threshold if you wish. This is the alamofire's default value       encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold,       encodingCompletion: { encodingResult in         switch encodingResult {         case .Success(let upload, _, _):           upload.responseJSON { response in             debugPrint(response)           }         case .Failure(let encodingError):           print(encodingError)         }     })   } 

Current swift version: https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#uploading-data-to-a-server

like image 23
fatihyildizhan Avatar answered Oct 22 '22 00:10

fatihyildizhan