Reputation: 175
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
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
Specify main queue in the sendAsynchronousRequest
call:
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in
...
)
or
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