Xcode 6 - beta 6/7: I've created a iOS 8 (Swift) blog reader app with an overview (table view) and a detail view (web view) screen. If there's internet connection the app, when starting up, loads the actual json data from the blog and saves it as entity objects into core data. The table view that is shown first then fills its cells with those objects from core data. The cells, containing title and subtitle, are fully loaded like expected. Everything seems to work fine but...
If I don't interact and just wait, the table view quickly refreshes after around 10 seconds (cells get blank and are filled with the same text again within half a second). After that everything works just fine, I can click the named cells and being forwarded to detail view, I can go back and chose any other.
If I start interacting immediately, like one normally does, I have to click a cell twice before being forwarded to the detail view. When going back to the overview within little time I find my table view filled just with the one cell I just tapped before, the rest are blanks.
- Either I can then wait for another 5-15 seconds before everything refreshes automatically (and from that point on work fine) or
- I can tap those blank cells which get then visible again immediately, whereas - of course - I'm being forwarded again to the detail view or
If I had stood for longer on the detail view, let's say reading some of the blog, and then go back, all cells are visible as there was enough time for this strange refresh taking place in the meanwhile
As a note: If there is no internet connection the app successfully loads the objects from core data but the problem mentioned remains. So, anyway, I have to wait till this "second refresh" took place before the app runs like I want it too.
If it's a completely unknown problem and you have to see some of the code for further investigation, I'm happy to share it. But right now I haven't seen a point as it's more or less the basic code implemented when using table views. I'm fairly new to core data and may have overseen something but not noticed so far. I'd be very thankful for some help as I usually investigate quite long time before asking but this time really have no clue what the reason could be.
EDIT:
It may be important to add that I started the app with the "Master-Detail Application" template in Xcode and make us of the methods it provides to fill the cells automatically with the proper entity objects from core data (NSFetchedResultsController). Some part of the code that could give a hint where to investigate further (please tell me, if more code is needed):
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
self.configureCell(cell, atIndexPath: indexPath)
return cell
}
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
cell.textLabel?.text = object.valueForKey("title")?.description
let published = object.valueForKey("published")?.description
let author = object.valueForKey("author")?.description
let spaceholder = " "
cell.detailTextLabel?.text = published! + spaceholder + author!
}
EDIT 2:
Thanks to the input nzeltzer I think I've found the point: The problem above occurs just when some parts of the code run on global (instead of main) thread. So I did some testing: The console output at the bottom shows the NSThread.isMainThread() results when the app builds for the first time.
When I rerun the app a second time and more, the process is the following: Core data already has some values so the cells are configured directly (Log: _ is Main Thread
). Then, in case there is internet connection it is deleting (in the viewDidLoad) all the core data objects, loads the json data again, puts the objects to core data and creates the cells a second time. This second part of the Log is now again _ is NOT Main Thread
. If I run the app now without internet connection, the second part doesn't get triggered and just the first cell configuration with _ is Main Thread
takes place.
Any straight forward explanation for that behavior?
What would be the right (elegant) approach to dispatch those parts that might be responsible for the problem on main thread in any case? Does it have anything to do with the template's built-in NSFetchedResultsController or is it just normal that some tasks are dispatched to global queues automatically?
Log (app builds for the first time, 10 cells):
2014-09-08 13:04:54.821 Blog Reader[3682:193346] 17545849:_UIScreenEdgePanRecognizerEdgeSettings.edgeRegionSize=13.000000
2014-09-08 13:04:54.823 Blog Reader[3682:193346] 17545849:_UIScreenEdgePanRecognizerEdgeSettings.edgeRegionSize=13.000000
NumbersOfRowsInSection is Main Thread
NumbersOfRowsInSection is Main Thread
NumbersOfRowsInSection is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread
configureCell is NOT Main Thread
cellForRowAtIndexPath is NOT Main Thread