Download picture from alamofire

I am trying to upload an image to a server using Alamofire, but my code does not work. This is my code:

var parameters = ["image": "1.jpg"] let image = UIImage(named: "1.jpg") let imageData = UIImagePNGRepresentation(image) let urlRequest = urlRequestWithComponents("http://tranthanhphongcntt.esy.es/task_manager/IOSFileUpload/", parameters: parameters, imageData: imageData) Alamofire.upload(urlRequest.0, data: 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 this is urlRequestWithComponents methos:

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

and this is what I get in the console:

REQUEST {URL: http://tranthanhphongcntt.esy.es/task_manager/IOSFileUpload/ } RESPONSE Optional ({URL: http://tranthanhphongcntt.esy.es/task_manager/IOSFileUpload/ } {status code: 200, headers {"Accept -Ranges "= bytes; Connection = close;" Content-Length "= 345;" Content-Type "=" text / html "; Date =" Tue, Aug 25, 2015 10:52:01 GMT ";" Last-Modified "=" Mon, 24 Aug 2015 03:54:55 GMT "; Server = Apache;}}) JSON nil ERROR Optional (Error Domain = NSCocoaErrorDomain Code = 3840) The operation could not be completed. (Cocoa error 3840.) "(Invalid value around character 0.) UserInfo = 0x7f8c68c1c130 {NSDebugDescription = Invalid value around character 0.})

my php content is:

 <? php echo $_FILES['image']['name']. '<br/>'; //ini_set('upload_max_filesize', '10M'); //ini_set('post_max_size', '10M'); //ini_set('max_input_time', 300); //ini_set('max_execution_time', 300); $target_path = "uploads/"; $target_path = $target_path.basename($_FILES['image']['name']); try { //throw exception if can't move the file if (!move_uploaded_file($_FILES['image']['tmp_name'], $target_path)) { throw new Exception('Could not move file'); } echo "The file ".basename($_FILES['image']['name']). " has been uploaded"; } catch (Exception $e) { die('File did not upload: '.$e - > getMessage()); } ?> 

My code followed this suggestion: Download the parameter file using Alamofire. Please help me, thanks

+7
upload swift alamofire
source share
4 answers

While Rob's answer is correct, here is the Swift 2.0 version with a download update update .

Just copy and paste the following code, change the download URL and add to your parameters. Should work like a charm.

PS: MRProgress is an awesome library for updating progress!

  let apiToken = "ABCDE" Alamofire.upload( .POST, "http://sample.com/api/upload", multipartFormData: { multipartFormData in multipartFormData.appendBodyPart(data: imageData, name: "yourParamName", fileName: "imageFileName.jpg", mimeType: "image/jpeg") multipartFormData.appendBodyPart(data: apiToken.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"api_token") multipartFormData.appendBodyPart(data: otherBodyParamValue.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"otherBodyParamName") }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in print("Uploading Avatar \(totalBytesWritten) / \(totalBytesExpectedToWrite)") dispatch_async(dispatch_get_main_queue(),{ /** * Update UI Thread about the progress */ }) } upload.responseJSON { (JSON) in dispatch_async(dispatch_get_main_queue(),{ //Show Alert in UI print("Avatar uploaded"); }) } case .Failure(let encodingError): //Show Alert in UI print("Avatar uploaded"); } } ); 
+5
source share

Your error says that the response is invalid JSON. You call responseJSON , indicating that you are expecting a JSON response, but your server code does not generate JSON. So there are two solutions:

  • I would suggest changing my PHP code to generate JSON responses.

    For example, if successful:

     echo json_encode(array("success" => true, "filename" => basename($_FILES['image']['name'])); 

    or, if failed, it is possible:

     echo json_encode(array("success" => false, "error_code" => 42, "error_msg" => 'File did not upload: '.$e - > getMessage()); 

    Obviously, you need to remove the external echo lines in PHP if you are going to return JSON, but hopefully this illustrates the pattern. But this will trigger a response that you can parse with Alamofire responseJSON (or use NSJSONSerialization ).

  • Alternatively, you can change the Alamofire code to not expect JSON (for example, calling response , not responseJSON ), but then parsing the answers becomes much more complicated.

As a minor, non-related issue, I would personally advise you not to create this request manually, but let Alamofire do it for you. Here is an example from README :

 Alamofire.upload( multipartFormData: { multipartFormData in multipartFormData.append(unicornImageURL, withName: "unicorn") multipartFormData.append(rainbowImageURL, withName: "rainbow") }, to: "https://httpbin.org/post", encodingCompletion: { encodingResult in switch encodingResult { case .success(let upload, _, _): upload.responseJSON { response in debugPrint(response) } case .failure(let encodingError): print(encodingError) } } ) 

This is for Swift 3 and Alamofire 4. See the changelog for this question for previous versions.

+4
source share

SWIFT 2 AlamoFire total Solution for uploading images to the REST API

AlamoFire contains a load of simplified solution. The Alamofire.request method contains several simplified overloads that you can use to load in a simple way. Using Alamofire.request (the method developer can get rid of coding overhead.

Please check my solution below.

The solution was tested on SWIFT 2.0

 import UIKit import Alamofire class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! @IBOutlet var btnUpload: UIButton! override func viewDidLoad() { super.viewDidLoad() } func successDataHandler(responseData:String){ print ("IMAGE UPLOAD SUCCESSFUL !!!") } func failureDataHandler(errorData:String){ print (" !!! IMAGE UPLOAD FAILURE !!! ") } @IBAction func actionUpload(sender: AnyObject) { let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages" let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!] uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler) } func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () { let headerData:[String : String] = ["Content-Type":"application/json"] Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in switch response.result { case .Success: print(response.response?.statusCode) successHandler(response.result.value!) case .Failure(let error): failureHandler("\(error)") } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } 
0
source share
 let parameters: Parameters = [ "userid":user.userID! ] print("the uploadData - \(parameters)") let imageData = UIImageJPEGRepresentation(deviceImage.image!, 1) let url = try! URLRequest(url: URL(string:"your URL here")!, method: .post, headers: nil) Alamofire.upload(multipartFormData: { (multipartFormData) in multipartFormData.append(imageData!, withName: "file_name", fileName: "abc.jpg", mimeType: "image/jpg") for (key, value) in parameters { multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key) } }, with: url, encodingCompletion: { (result) in switch result { case .success(let upload, _, _): upload.responseJSON { response in if response.response?.statusCode == 200 { PrepareUIElements.showAlertAndPerformSegue(sender: self, message: "Uploaded Successfully", identifier: "ShowHome") } else { print("whatever you want") } } case .failure(let encodingError): PrepareUIElements.showAlert(sender: self, message: "Unable to Upload") print(encodingError) } }) 
0
source share

All Articles