Reputation: 457
I have an issue with my TableView displaying JSON data. When it is displayed, it currently lags whenever I scroll up and down. I know that I have to use the Grand Central Dispatch methods (GCD) for that, however, I have no clue on how to go about that.
This is my code snippet in my viewDidLoad() method that just grabs the JSON data into a dictionary:
// Convert URL to NSURL
let url = NSURL(string: apiURL)
let jsonData: NSData?
do {
/*
Try getting the JSON data from the URL and map it into virtual memory, if possible and safe.
DataReadingMappedIfSafe indicates that the file should be mapped into virtual memory, if possible and safe.
*/
jsonData = try NSData(contentsOfURL: url!, options: NSDataReadingOptions.DataReadingMappedIfSafe)
} catch let error as NSError
{
showErrorMessage("Error in retrieving JSON data: \(error.localizedDescription)")
return
}
if let jsonDataFromApiURL = jsonData
{
// The JSON data is successfully obtained from the API
/*
NSJSONSerialization class is used to convert JSON and Foundation objects (e.g., NSDictionary) into each other.
NSJSONSerialization class's method JSONObjectWithData returns an NSDictionary object from the given JSON data.
*/
do
{
let jsonDataDictionary = try NSJSONSerialization.JSONObjectWithData(jsonDataFromApiURL, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Typecast the returned NSDictionary as Dictionary<String, AnyObject>
dictionaryOfRecipes = jsonDataDictionary as! Dictionary<String, AnyObject>
// Grabs all of the matched recipes
// This will return an array of all of the matched recipes
matchedRecipes = dictionaryOfRecipes["matches"] as! Array<AnyObject>
// Returns the first 10 recipes shown in the JSON data
recipeCount = matchedRecipes.count
}catch let error as NSError
{
showErrorMessage("Error in retrieving JSON data: \(error.localizedDescription)")
return
}
}
else
{
showErrorMessage("Error in retrieving JSON data!")
}
Thanks!
Upvotes: 0
Views: 299
Reputation: 457
I've figured it out. It wasn't just the
dispatch_async(dispatch_get_main_queue())
because that is just using the main thread, and you should only use that when you are displaying JSON information onto a view. If I am understanding this correctly, you are supposed to use:
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)){}
Whenever you are trying to download the data, such as an image, before displaying it onto a view. Here is an example code for anyone interested:
//-----------------
// Set Recipe Image
//-----------------
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0))
{
// This grabs the Image URL from JSON
let imageURL = recipeDataDict["imageUrlsBySize"] as! NSDictionary
let imageSize90 = imageURL["90"] as! String
// Create an NSURL from the given URL
let url = NSURL(string: imageSize90)
var imageData: NSData?
do {
/*
Try getting the thumbnail image data from the URL and map it into virtual memory, if possible and safe.
DataReadingMappedIfSafe indicates that the file should be mapped into virtual memory, if possible and safe.
*/
imageData = try NSData(contentsOfURL: url!, options: NSDataReadingOptions.DataReadingMappedIfSafe)
} catch let error as NSError
{
self.showErrorMessage("Error in retrieving thumbnail image data: \(error.localizedDescription)")
}
dispatch_async(dispatch_get_main_queue(),
{
if let image = imageData
{
// Image was successfully gotten
cell.recipeImage!.image = UIImage(data: image)
}
else
{
self.showErrorMessage("Error occurred while retrieving recipe image data!")
}
})
}
Before I had just the dispatch_get_global_queue WITHOUT the main_queue thread, the images would download very slowly (but the tableview did not lag). However, once I added in the main_queue before displaying the JSON data, it was downloaded instantly (or almost instantly) and without any further lags.
More information on: https://tetontech.wordpress.com/2014/06/04/swift-ios-and-grand-central-dispatch/
Upvotes: 0
Reputation: 207
Give your code inside
dispatch_async(dispatch_get_main_queue(), {
// Your Execution Code
}
This simply works
Upvotes: 1