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.
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.
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);
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With