Image Upload with Progress Bar example in Swift

In this video tutorial I am going to share how to upload an image and display the upload progress using the UIProgressView.

  • I am going to use UIImagePickerController to let user select one of the images on their device
  • I will use NSMutableURLRequest to send HTTP POST request with image data to a server side PHP script
  • and I will use UIProgressView and well as UILabel to display the upload progress

Video tutorial, source code and links to download project files are below. I hope it helps!

Link to download Image Upload Example with Progress Bar

UIViewController source code:


import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate {
@IBOutlet weak var myImageView: UIImageView!
@IBOutlet weak var imageUploadProgressView: UIProgressView!
@IBOutlet weak var progressLabel: UILabel!
@IBOutlet weak var uploadButton: UIButton!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

@IBAction func uploadButtonTapped(sender: AnyObject) {

var myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary

self.presentViewController(myPickerController, animated: true, completion: nil)

}

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])

{
myImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage

myImageView.backgroundColor = UIColor.clearColor()
self.dismissViewControllerAnimated(true, completion: nil)

uploadImage()
}

func uploadImage()
{
let imageData = UIImageJPEGRepresentation(myImageView.image, 1)

if(imageData == nil ) { return }

self.uploadButton.enabled = false

let uploadScriptUrl = NSURL(string:"http://www.swiftdeveloperblog.com/http-post-example-script/")
var request = NSMutableURLRequest(URL: uploadScriptUrl!)
request.HTTPMethod = "POST"
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")

var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())

var task = session.uploadTaskWithRequest(request, fromData: imageData)
task.resume()

}

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
{
println("didCompleteWithError")

let myAlert = UIAlertView(title: "Alert", message: error?.localizedDescription, delegate: nil, cancelButtonTitle: "Ok")
myAlert.show()

self.uploadButton.enabled = true

}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64)
{
println("didSendBodyData")
var uploadProgress:Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend)

imageUploadProgressView.progress = uploadProgress
let progressPercent = Int(uploadProgress*100)
progressLabel.text = "\(progressPercent)%"
println(uploadProgress)
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void)
{
println("didReceiveResponse")
println(response);
self.uploadButton.enabled = true
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)
{
println("didReceiveData")
}

}

Source code of PHP script that accepts HTTP POST request with image data, saves image to target directory and sends back JSON response:


$target_dir = "wp-content/uploads/2015/02";

if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}

$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);

if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK"
]);

} else {

echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error"
]);
}

  • Jeffrey Zhang

    Hi Sergey,

    This is so helpful! I am dealing with a similar situation on video uploading. Thanks a lot! Hope the beginners like me can learn more from you 🙂

  • Loïc Fontaine

    Hi Sergey,

    I have a little problem, when i execute your code, i get this message :

    didReceiveResponse

    { URL: http://kword.zz.mu/uploadImage.php } { status code: 200, headers {

    Connection = “Keep-Alive”;

    “Content-Encoding” = gzip;

    “Content-Type” = “application/json”;

    Date = “Wed, 22 Jul 2015 08:04:23 GMT”;

    “Keep-Alive” = “timeout=2, max=100”;

    Server = Apache;

    “Transfer-Encoding” = Identity;

    Vary = “Accept-Encoding”;

    “X-Powered-By” = “PHP/5.5.26”;

    } }

    but on my server the Image doesn’t appear and i don’t know what is the problem.

    Can you help me please ?

    • Loic, can you make sure that your PHP script receives all required parameters? One way to do it is to simple echo back the json_encoded value of your parameters. and see if they all appear in you Xcode debug console

      • ast

        Sergey, same issue…I tried also with your php but with no fortune…
        same message in the console, and no file on the server…

        • I would check two things:
          1. Make sure my php script receives all required parameters.
          2. When I am sure that php scripts gets all needed values, I would make sure images folder has needed permissions for files to be uploaded. While debugging only I would create a images folder manually and set its permissions to 777 to see if image gets in.
          Can you try this?

          • ast

            Thank you Sergey,
            I have read the previous thread and beforere I did a folder with read write and execute permissions.
            About the parameters:
            How can I test it?

          • ast

            Thank you Sergey,
            I wil try it soon

          • ast

            Thank you Sergey,
            I wil try it soon

          • ast

            I create a folder with 777 permissions.

            I think that the value needed by the php is only the $_FILES[“file”][“name”] parameter, correct? how can I verify that is correctly sent to the php, if the response I get is only a 200 status?

          • You can print it out for example in your PHP script do:

            echo $_FILES[“file”][“name”];

            return;

            and in your Swift code just before this line of code which converts NSData to JSON:

            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

            add this code:

            let datastring = NSString(data: data!, encoding:NSUTF8StringEncoding)

            print(datastring)

            return

            This will print out value sent by php script without converting it to JSON format.

          • Coração Tricolor

            I don’t understand (and see) in your swift code where and how parameters “file” and “name” are being passed?

          • Abdul Waheed

            yes that’s the main point…

          • iKhalil

            Same issue here, the other script with the boundary and the requestTask works just fine, but this one doesn’t work for me ?

          • ast

            here:

            var task = session.uploadTaskWithRequest(request, fromData: imageData)

          • ast

            Sorry Sergey, I’m unable to find

            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary

            in your code!

          • ast

            I create a folder with 777 permissions.

            I think that the value needed by the php is only the $_FILES[“file”][“name”] parameter, correct? how can I verify that is correctly sent to the php, if the response I get is only a 200 status?

  • Hamzah

    I get status 200 but do not see the image on server. Any echo’s i do from the script are not shown in xcode log

    • Can you try creating a directory on server manually and try uploading an image to that directory. Will it work?

      • Hamzah

        My folder is already there and being used by an android version of the app

        • If echo(s) do not appear then there is an issue with PHP script. Do you think you can let me look at it? If it is still actual.

          • Hamzah

            Its OK I fixed it

  • Can we get this in ASp.net Web services 🙂

    • Hi Emre! I unfortunately I do not work with ASP.NET

  • Vincent Lombard

    Hi, I’m trying to implement this code on my project, but how does the PHP script knows that the file to upload has the parameter ‘file’ in $_FILES ? The progresses working fine but finally it’s not uploaded on the server. Why ?

    • Hi Vincent, please find below my conversation with Loic. There are a couple of things I suggest to check first. Can you check your code to make sure this is not an issue in your case?

  • nickisaacs

    Hi, How can I do background uploads? I need to upload files in background with parameters like the capture time, and few other details. I have implemented this but this seems to work only in foreground

  • Abdul Waheed

    the php script you uploaded is not working.. while trying to echo json_encode i get an error ..

  • Abdul Waheed

    here is the error List

    Notice: Undefined index: file in /Applications/XAMPP/xamppfiles/htdocs/practice/uploadScript.php on line 11

    Notice: Undefined index: file in /Applications/XAMPP/xamppfiles/htdocs/practice/uploadScript.php on line 12

    Notice: Undefined index: file in /Applications/XAMPP/xamppfiles/htdocs/practice/uploadScript.php on line 13

    {“Message”:”Sorry, there was an error uploading your file.”,”Status”:”Error”}

  • Vishal Wadhera

    i am having an issue, that i dont get any value in $_FILES[“file”][“name”] in my php script. what to do?

  • Vishal Wadhera

    i am having an issue, that i dont get any value in $_FILES[“file”][“name”] in my php script. what to do?