I'm just learning Ios programming for the first time, with Swift and Xcode 6 beta.
I am making a simple test app that should call an API, and then segue programmatically to a different view to present the information that was retrieved.
The problem is the segue. In my delegate method didReceiveAPIResults
, after everything has been successfully retrieved, I have:
println("--> Perform segue")
performSegueWithIdentifier("segueWhenApiDidFinish", sender: nil)
When the app runs, the console outputs --> Perform segue
, but then there is about a 5-10 second delay before the app actually segues to the next view. During this time all the UI components are frozen.
I'm a little stuck trying to figure out why the segue doesn't happen immediately, or how to debug this!
Heres The Full View controller:
import UIKit
class ViewController: UIViewController, APIControllerProtocol {
@lazy var api: APIController = APIController(delegate: self)
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func didReceiveAPIResults(results: NSDictionary) {
println(results)
println("--> Perform segue")
performSegueWithIdentifier("segueWhenApiDidFinish", sender: nil)
}
@IBAction func getData(sender : AnyObject){
println("--> Get Data from API")
api.getInfoFromAPI()
}
}
And my API controller:
import UIKit
import Foundation
protocol APIControllerProtocol {
func didReceiveAPIResults(results: NSDictionary)
}
class APIController: NSObject {
var delegate: APIControllerProtocol?
init(delegate: APIControllerProtocol?) {
self.delegate = delegate
}
func getInfoFromAPI(){
let session = NSURLSession.sharedSession()
let url = NSURL(string: "https://itunes.apple.com/search?term=Bob+Dylan&media=music&entity=album")
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
if(error) {
println("There was a web request error.")
return
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions. MutableContainers, error: &err) as NSDictionary
if(err?) {
println("There was a JSON error.")
return
}
self.delegate?.didReceiveAPIResults(jsonResult)
})
task.resume()
}
}
UPDATE: Got this working based on Ethan's answer. Below is the exact code that ended up getting the desired behavior. I needed assign that
to self
to have access to self inside the dispatch_async
block.
let that = self
if(NSThread.isMainThread()){
self.delegate?.didReceiveAPIResults(jsonResult)
}else
{
dispatch_async(dispatch_get_main_queue()) {
println(that)
that.delegate?.didReceiveAPIResults(jsonResult)
}
}
Interestingly, this code does not work if I remove the println(that)
line! (The build fails with could not find member 'didReceiveAPIResults'
). This is very curious, if anyone could comment on this...