Often, in GUI, I’m faced with a program flow which is essentially sequential, but involves asynchronous operations (such as NSURLConnection downloading stuff) and UI actions (wait for the user to choose an option in an UIActionSheet).
Just to illustrate, for example,
- Show a
UIActionSheet, prompting the user to choose a color. - If color is blue, download a file from a server.
- If download fails, inform the user (
UIAlertView, wait for tap on OK) - If user chooses YES in the
UIAlertView, retry downloading.
- If download fails, inform the user (
- if color is black, do something else.
- and so on and so on.
The flow is sequential – we don’t do 2 before 1. But because of async operations and UI elements, this very quickly becomes spaghetti code if we use delegates (or blocks).
Is there a general approach to writing such code?
There is a library called Reactive Cocoa that is amazing, but tough to get used to.
An easier way to achieve your goal, but not quite as awesome, is using a blocks wrapper around UIAlertView and UIActionSheet. Also this assumes you have call back blocks in your network code.
Example:
So the last line “[sheet showInView:self.view]” starts the whole thing off. If they select Blue then that block gets called. Your network code also supports blocks, so you get a success and failure block callback from there. If it’s failure then you pop up a block based alert view that makes the ActionSheet show itself all over again.
I hope this helped at least a little. Also there are probably some strong referencing happening with the “self.view” call so i’d make a weak reference to the view as well.
Here is the ReactiveCocoa example. I am very new to this framework so I hope I am using it correctly.
Then we get into a network request controller I have.
And now we are in my actually network wrapper that knows when a request has completed or failed or whatever.
And finally to give you an idea of when I have the subject [sendNext:] is in my parser.
The self.currentParsedCharacterData is an NSString with and integer value.
I know this is long but I really wanted to give some actual code examples.