vendredi 28 août 2015

struggling with asynchronous patterns using NSURLSession

I'm using Xcode 7 and Swift 2 but my question isn't necessarily code specific, I'll gladly take help of any variety.

In my app I have a list of favorites. Due to API TOS I can't store any data, so I just keep a stub I can use to lookup when the user opens the app. I also have to look up each favorite one by one as there is no batch method. Right now I have something like this:

 self.api.loadFavorite(id, completion: { (event, errorMessage) -> Void in
     if errorMessage == "" {
         if let rc = self.refreshControl {
             dispatch_async(dispatch_get_main_queue()) { () -> Void in
                 rc.endRefreshing()
             }
         }
         dispatch_async(dispatch_get_main_queue()) { () -> Void in
         self.viewData.append(event)
             self.viewData.sortInPlace({ $0.eventDate.compare($1.eventDate) == NSComparisonResult.OrderedDescending })
             self.tableView.reloadData()
         }
     } else {
         // some more error handling here

     }
 })

in api.loadFavorite I'm making a typical urlSession.dataTaskWithURL which is itself asynchronous.

You can see what happens here is that the results are loaded in one by one and after each one the view refreshes. This does work but its not optimal, for long lists you get a noticeable "flickering" as the view sorts and refreshes.

I want to be able to get all the results then just refresh once. I tried putting a dispatch group around the api.loadFavorites but the async calls in dataTaskWith URL don't seem to be bound by that group. I also tried putting the dispatch group around just the dataTaskWithURL but didn't have any better luck. The dispatch_group_notify always fires before all the data tasks are done.

Am I going at this all wrong? (probably) I considered switching to synchronous calls in the background thread since the api only allows one connection per client anyway but that just feels like the wrong approach.

I'd love to know how to get async calls that make other async calls grouped up so that I can get a single notification to update my UI.

For the record I've read about every dispatch group thread I could find here and I haven't been able to make any of them work. Most examples on the web are very simple, a series of print's in a dispatch group with a sleep to prove the case.

Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire