bobbyali / kidzvids2

Second attempt at the kid-friendly Youtube iOS player
1 stars 2 forks source link

Design patterns for async calls? #25

Closed bobbyali closed 9 years ago

bobbyali commented 9 years ago

When building this app, I got stuck with lots of bugs related to coordinating my main app code with the asynchronous YouTube API request code (making sure that the Grid VC only updated after the API calls completed, making sure that there weren't multiple simultaneous API calls being made, etc). As a result, my code ended up getting messy because I was implementing lots of locks and checks (to make sure that multiple events weren't being fired, to make sure that other events had completed before code was executed, etc).

Are there any application design patterns or strategies that I should consider for future projects, that will make it easier to handle these types of situations?

bobbyali commented 9 years ago

e.g. NetworkImporter has an isBusy variable that checks whether the code is busy executing an API call. If it's set to true, then no further API calls will be permitted.

https://github.com/bobbyali/kidzvids2/blob/master/kidsvids/NetworkImporter.swift#L28

e.g. GridCollectionViewController has a isDataReady variable that checks whether the API call has completed before executing follow-up code (e.g. loading images in the Collection View Cells). If it's false, then follow-up code cannot execute.

https://github.com/bobbyali/kidzvids2/blob/master/kidsvids/GridCollectionViewController.swift#L138

These variables are set in the API call completion methods in GridVC (fetchCompleted, fetchFailed), and updated at other points when the VC requests more data (viewWillAppear, viewDidLayoutSubviews, refreshController). It got quite confusing working out where the variables had to be set and updated in order to make the code work properly.

tudormunteanu commented 9 years ago

UITableViews and UICollectionViews are architected to specifically handle async data. Using a state flag like isBusy is redundant, because the central point should be a list/dictionary with the data that will be retrieved from the server and diplayed. At first the list/dictionary is empty. Making a server request populates this list/dictionary and a reload is triggered.

Most of the articles online are for Obj-c, but translating the method names to Swift should not be difficult. Here's a good implementation of a UITableView + AFNetworking: http://nscookbook.com/2013/12/ios-programming-recipe-16-2-populating-a-uitableview-with-data-from-the-web-ios-7-and-afnetworking-2-0/

To find out a bit more about how UICollectionViews work, take a look at Chapter 6, Lesson. 5 from the O'Reilly book that I emailed you.