How can I get my activity indicator at the right time?

From everything I've read, you can activate it with a button, so I put it right after the button action that triggers the HTTP POST and loads, but now it starts spinning right after the function completes after the download is complete, opposite to what I was expecting would.
I'm new to Swift, so please explain your answer as if you were in nubie. Many thanks.

@IBAction func upload(sender: AnyObject) {

    myActivityIndicator.startAnimating()

    var imageData = UIImagePNGRepresentation(myImageView.image)

    if imageData != nil{
        var request = NSMutableURLRequest(URL: NSURL(string:"http://www.example.com/upload.php")!)

        var session = NSURLSession.sharedSession()

        request.HTTPMethod = "POST"

        var boundary = NSString(format: "---------------------------14737809831466499882746641449")
        var contentType = NSString(format: "multipart/form-data; boundary=%@",boundary)
        //  println("Content Type \(contentType)")
        request.addValue(contentType, forHTTPHeaderField: "Content-Type")

        var body = NSMutableData.alloc()

        // Title
        body.appendData(NSString(format: "\r\n--%@\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)

        // Image
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        //           println("body=\(body)")
        body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(imageData)
        body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)



        request.HTTPBody = body


        var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

        var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)

        println("returnString \(returnString)")

        //self.myActivityIndicator.stopAnimating()
        //self.myImageView.image = nil

    }


}

      

+3


source to share


2 answers


try it

myActivityIndicator.startAnimating()        
          dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
            //Do your post code here or call the post func
            dispatch_async(dispatch_get_main_queue()) {
                myActivityIndicator.stopAnimating()
            }
    }

      



http://ijoshsmith.com/2014/07/29/a-swift-app-that-calls-json-web-services/ http://www.raywenderlich.com/79149/grand-central-dispatch-tutorial- swift-part-1

+1


source


This is because this call blocks the main thread (which is responsible for updating the UI:

var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

      

Thus, after this line of code, anything you do in the UI will not appear until this synchronous call completes.

The solution here is to make this call on a background thread and then when done updating the UI on the main thread.

One of the best ways to achieve this is by using GCD (Grand Central Dispatch). GCD is a threading API that makes working on background threading easy.

As mentioned in the answer above:



    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), {

        var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)

        dispatch_async(dispatch_get_main_queue()) {
            myActivityIndicator.stopAnimating()
        }

    })

      

One of the key principles in iOS development is not blocking the main thread.

This leads to poor user experience.

Also, it is very important to always update the UI on the main thread.

Just to let you know that there are other ways to handle this kind of situation without GCD (Streaming API) for example . NSOperation

Alternatively, you can send the request asynchronously .

+1


source







All Articles