GiedriuX
GiedriuX

Reputation: 175

xcode IOS swift NSURLConnection works slow

I'm trying to get information from my API and show it on APP, everything is fine except that slow printing on view. After i got JSON information from my API it stucks for ±5-8 secs.

There is my function for async post:

class func postAsync(post :NSString, def: Bool = true, completionHandler: ((AnyObject?, NSError?) -> Void)) {

    var post_url : NSString

        /* SOME CODE */

    post_url = post

    let jsonData = NSDictionary();

    var postData:NSData = post_url.dataUsingEncoding(NSASCIIStringEncoding)!

    var postLength:NSString = String( postData.length )

    let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
    var request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 2.0)

    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")


    var reponseError: NSError?
    var response: NSURLResponse?

    var urlData: NSData? = nil

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler: { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        if (error != nil) {
            completionHandler(nil, error)
            println("API error: \(error), \(error.userInfo)")
        }
        var jsonError:NSError?

        let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers, error: &jsonError) as NSDictionary
        if (jsonError != nil) {
            println("Error parsing json: \(jsonError)")
            completionHandler(nil, jsonError)
        }
        else {

            ... error ...

            completionHandler(jsonData, nil)

        }
    })

}

This is how i call it:

        WebReq.postAsync("default", def: true) { (data, error) -> Void in
        if let er = error {
            println("\(er)")
        }

        if let arr = data?["arr"] as? NSArray {
            for (index,album) in enumerate(arr) {

                var position = CGRect(x: 0, y: index*21, width: 90, height: 20)
                var label = UILabel(frame: position)
                label.textAlignment = NSTextAlignment.Center
                label.text = album["text"] as? NSString
                self.view.addSubview(label)

            }
        }
    }

And results prints after 5-8 secs. If I do synchronized then hangs my whole app for a little bit shorter time like 2-5 secs

If do println() on that place where I'm trying to create UILabel, then it appears instantly after I get and parse my info.

Any suggestions? I've no idea where is the problem

Upvotes: 1

Views: 881

Answers (1)

Rob
Rob

Reputation: 437482

You have instructed sendAsynchronousRequest to use a background operation queue for the completion block (you instantiated a new NSOperationQueue()). Therefore, you are trying to do UI updates from background thread. But UI updates must happen on the main thread.

Either

  1. Specify main queue in the sendAsynchronousRequest call:

     NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in
         ...
     )
    

    or

  2. Manually dispatch the UI updates back to the main queue

     NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { response, data, error in
         // do stuff in background queue
    
         // when ready to update model/UI dispatch that to main queue
         dispatch_async(dispatch_get_main_queue()) {
             ...
         } 
     )
    

    or

     NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { response, data, error in
         // do stuff in background queue
    
         // when ready to update model/UI dispatch that to main queue
         NSOperationQueue.mainQueue().addOperationWithBlock { 
             ...
         } 
     )
    

Upvotes: 3

Related Questions