Swift - 管理任务以填充UITableView

时间:2015-08-16 13:17:02

标签: ios swift uitableview http task

我正在开发的观点如下:

  1. 向API发送GET请求以检索用户列表
  2. 向API发送GET请求以从用户列表中检索个人资料图片
  3. 在TableViewCells中显示图像
  4. 但是,我在管理任务和队列方面遇到了问题。在填充表视图之前确保所有请求和任务完成的最佳方法是什么?

    以下是代码:

    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.
        }
        */
    
    }
    

1 个答案:

答案 0 :(得分:0)

问题的关键是以下代码:

dispatch_async(backgroundQueue, {

    self.refreshData()
    self.getImage()

    dispatch_async(dispatch_get_main_queue(), { () -> Void in

        self.tableView.reloadData()

    })
})

NSURLSession在后​​台线程中工作,因此jsonDataself.getImage()执行时reloadData为空。

您可以在此行之后调用self.getImage()

self.jsonData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as! [NSDictionary]
session.dataTaskWithRequest已完成的块中

并在reloadData的已完成块中调用session2.dataTaskWithRequest(在dispatch_get_main_queue上)。

我认为这将解决您的问题。