The view I'm developing does the following:
However, I'm having problem managing the tasks and the queues. What is the best way to be sure that all the requests and tasks are done before populating the Table View?
Here's the code:
import UIKit
class homeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var jsonData : [NSDictionary] = [NSDictionary]()
var imageUrls: NSDictionary = NSDictionary()
var urlsArray: [NSURL] = [NSURL]()
override func viewDidLoad() {
super.viewDidLoad()
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
self.refreshData()
self.getImage()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
})
}
override func viewWillAppear(animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return jsonData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var type = jsonData[indexPath.row]["type"] as! Int
for typej in jsonData {
let t : Int = typej["type"] as! Int
println("type : \(t)")
}
if type == 1 {
let cell1 : cellTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! cellTableViewCell
/* //If images url are retrieved, load them. Otherwise, load the placeholders
if self.urlsArray.isEmpty == false {
println("Tiè: \(self.urlsArray[indexPath.row])")
if let data = NSData(contentsOfURL: self.urlsArray[indexPath.row]) {
cell1.profileImg?.image = UIImage(data: data)
}
} else {
cell1.profileImg?.image = UIImage(named: "placeholder.png")
}*/
let block: SDWebImageCompletionBlock! = {
(image: UIImage!, error: NSError!, cacheType: SDImageCacheType, imageURL: NSURL!) -> Void in
println(self)
}
println("url Array: \(self.urlsArray)")
let url = NSURL(string: "http://adall.ga/s/profile-1439584252497.png")
if UIApplication.sharedApplication().canOpenURL(urlsArray[indexPath.row]) {
cell1.profileImg.sd_setImageWithURL(urlsArray[indexPath.row], completed: block)
} else {
cell1.profileImg.sd_setImageWithURL(url, completed: block)
}
cell1.testLbl.text = (self.jsonData[indexPath.row]["author"] as? String)!
return cell1
} else {
let cell2 : cell2TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell2") as! cell2TableViewCell
return cell2
}
}
func refreshData() {
let requestURL = NSURL(string:"http://adall.ga/api/feeds/author/mat/0")!
var request = NSMutableURLRequest(URL: requestURL)
request.HTTPMethod = "GET"
request.addValue(userToken, forHTTPHeaderField: "tb-token")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
data, response, error in
println(response)
var dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
println(dataString)
//let jsonResult : NSDictionary = (NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary)!
//jsonData = (NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers , error: nil) as? NSArray)!
self.jsonData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as! [NSDictionary]
}
task.resume()
var index: Int
for index = 0; index < 10000; ++index {
print("Index: \(index), Task state: \(task.state)")
}
}
func getImage() {
var i = 0
for jsonSingleData in jsonData {
let author = jsonSingleData["author"] as! String
let requestURL2 = NSURL(string: "http://adall.ga/api/users/" + author + "/image")!
var request2 = NSMutableURLRequest(URL: requestURL2)
request2.HTTPMethod = "GET"
request2.addValue(userToken!, forHTTPHeaderField: "tb-token")
let session2 = NSURLSession.sharedSession()
let task2 = session2.dataTaskWithRequest(request2) {
data, response, error in
println("response= \(response)")
var dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
println(dataString)
self.imageUrls = (NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary)
if self.imageUrls["url"] != nil {
//check if exists
let imageUrl = self.imageUrls["url"] as! String
let url = NSURL(string: "http://" + imageUrl)
self.urlsArray.append(url!)
} else {
let imageUrl = "http://shackmanlab.org/wp-content/uploads/2013/07/person-placeholder.jpg"
let url = NSURL(string: imageUrl)
self.urlsArray.append(url!)
}
}
task2.resume()
self.tableView.reloadData()
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
The point of the issue is the following code:
dispatch_async(backgroundQueue, {
self.refreshData()
self.getImage()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
})
The NSURLSession
working in the background thread, so your jsonData
is empty when the self.getImage()
and reloadData
are executed.
You can call the self.getImage()
after this line
self.jsonData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as! [NSDictionary]
in the session.dataTaskWithRequest
completed block and calls reloadData
(on the dispatch_get_main_queue) in the completed block of the session2.dataTaskWithRequest
.
I think this will solved your issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.