First of all, to avoid my bad English, I uploaded a video showing my problem
http://www.mediafire.com/download/j6krsa274o80ik9/Screen_Recording.mov
Second, I have a UITableViewController, that uses a remote API to download data. the data contains many image URLs, my first problem is that the tableView is not being updated even though i am doing .reloadData()
function
my second problem is that in the function:
tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
I download the images, which I had got their urls from the first call, then eventhing works good but I can't see the image unless I clicked on the row
Please see the video, it is easier to understand
Here is my code: (I gave you the full code of my UITableView because, it is simple, and because it has two functions, and they are the ones that making me problems)
class Physicst: NSObject {
let image : String
var imageData: UIImage?
let name : NSString
init(image: String, name: NSString) {
self.image = image
self.name = name
}
}
class PhysicistTableViewController: UITableViewController {
var physicsts : [Physicst]?
@IBOutlet var physicstsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
loadDataFromDBPedia()
}
func loadDataFromDBPedia() {
let session = NSURLSession.sharedSession()
var url = "http://dbpedia.org/sparql/"
let query = "http://dbpedia.org&query=select * {?o dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
if let error = error {
print ("\(error)")
}
if let response = response {
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
print("Status code = \(statusCode)")
}
if let data = data {
do {
let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let binding = jsonResponse["results"]!!["bindings"] as! NSArray
for oneBinding in binding {
let name = oneBinding["o"]!!["value"] as! NSString
var image = oneBinding["p"]!!["value"] as! String
image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let physicst = Physicst(image: image, name: name)
if self.physicsts == nil {
self.physicsts = [Physicst]()
}
self.physicsts!.append(physicst)
}
self.physicstsTableView.reloadData()
}catch _ {
print ("not well json-formatted response")
}
}
})
task.resume()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.physicsts == nil {
return 0
}else {
return self.physicsts!.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
let row = indexPath.row
let physicst = self.physicsts![row]
cell.textLabel?.text = physicst.name as String
if (physicst.imageData == nil) {
let session = NSURLSession.sharedSession()
let url = NSURL(string: physicst.image as String)
if let url = url {
let request = NSMutableURLRequest(URL: url)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let data = data {
let imageData = UIImage(data: data)
cell.imageView?.image = imageData
physicst.imageData = imageData
self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}
})
task.resume()
}else {
print ("nill URL \(physicst.image)")
}
}else {
cell.imageView?.image = physicst.imageData!
}
return cell
}
}
**fell free to copy/paste it, there is no custom cell, so it should work **
tableView reload should be called on main thread. session.dataTaskWithRequest completion block is called on background thread performing UI Operations on background thread might lead to serious consequences. I believe the problem you are facing is just one of those consequences. Modify the code as follow.
func loadDataFromDBPedia() {
let session = NSURLSession.sharedSession()
var url = "http://dbpedia.org/sparql/"
let query = "http://dbpedia.org&query=select * {?o dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
if let error = error {
print ("\(error)")
}
if let response = response {
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
print("Status code = \(statusCode)")
}
if let data = data {
do {
let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let binding = jsonResponse["results"]!!["bindings"] as! NSArray
for oneBinding in binding {
let name = oneBinding["o"]!!["value"] as! NSString
var image = oneBinding["p"]!!["value"] as! String
image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let physicst = Physicst(image: image, name: name)
if self.physicsts == nil {
self.physicsts = [Physicst]()
}
self.physicsts!.append(physicst)
}
dispatch_async(dispatch_get_main_queue()) { () -> Void in
self.physicstsTableView.reloadData()
}
}catch _ {
print ("not well json-formatted response")
}
}
})
task.resume()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
let row = indexPath.row
let physicst = self.physicsts![row]
cell.textLabel?.text = physicst.name as String
if (physicst.imageData == nil) {
let session = NSURLSession.sharedSession()
let url = NSURL(string: physicst.image as String)
if let url = url {
let request = NSMutableURLRequest(URL: url)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let data = data {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let imageData = UIImage(data: data)
cell.imageView?.image = imageData
physicst.imageData = imageData
self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
})
}
})
task.resume()
}else {
print ("nill URL \(physicst.image)")
}
}else {
cell.imageView?.image = physicst.imageData!
}
return cell
}
TIP
Downloading the images manually for each cell and then loading it to tableViewCell and handling caching in order to improve the performance of scroll is like re inventing the wheel when you have tubless tires availabe :) Please consider using SDWebImage
or AFNetworking
I have personlly used SDWebImage and its caching feature works perfectly.
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.