iOS Asynchronous NSURLConnection triggering behaviors on different views than the one that call it - iphone

Me and my team are currently rookie developers in Objective-C (less than 3 months in) working on the development of a simple tab based app with network capabilities that contains a navigator controller with a table view and a corresponding detailed view in each tab. The target is iOS 4 sdk.
On the networking side, we have a single class that functions as a Singleton that processes the NSURLConnection for each one of the views in order to retrieve the data we need for each of the table views.
The functionality works fine and we can retrieve the data correctly but only if the user doesn't change views until the petition is over or the button of the same petition (example: Login button) is pressed on again. Otherwise, different mistakes can happen. For example, an error message that should only be displayed on the root view of one of the navigation controllers appears on the detailed view and vice versa.
We suspect that the issue is that we are currently handling only a single delegate on the Singleton for the "active view" and that we should change it to support a behavior based on the native Mail app in which you can change views while the data that was asked for in each one of the views keeps loading and updating correctly separately.
We have looked over stackoverflow and other websites and we haven't found a proper methodology to follow. We were considering using an NSOperationQueue and wrapping the NSURLConnections on an NSOperation, but we are not sure if that's the proper approach.
Does anyone have any suggestions on the proper way to handle multiple asynchronous NSURLConnections to update multiple views, both parent and child, almost simultaneously at the whim of the user's interaction? Ideally, we don't want to block the UI or disable the buttons as we have been recommended.
Thank you for your time!
Edit - forgot to add, one of the project restrictions set by our client is that we can only use the native iOS sdk network framework and not the ASIHTTPRequest framework or similar. At the same time, we also forgot to add that we are not uploading any information, we are only retrieving it from the WS.

One suggestion is to use NSOperations and a NSOperationsQueue. The nice thing about this arrangement is you can quickly cancel any in-process or queued work (if say the user hits the back button.
There is a project on github, NSOperation-WebFetches-MadeEasy that makes this about as painless as it can be. You incorporate one class in your classes - OperationsRunner - which comes with a "how-to-use-me" in OperationsRunner.h, and two skeleton NSOperations classes, one the subclass of another, with the subclass showing how to fetch an image.
I'm sure others will post of other solutions - its almost a problem getting started as there are a huge number of libraries and projects doing this. That said, OperationsRunner is a bit over 100 lines of code, and the operations about the same, so this is really easy to read, understand, use, and modify.

You say that your singleton has a delegate. Delegation is inappropriate when multiple objects are interested in the result. If you wish to continue using a singleton for fetching data, you must switch your pattern to be based on notifications. Your singleton will have responsibility for determining which connection corresponds to which task, and choosing an appropriate notification to be posted.
If you still need help with this, let me know, I'll try to post some sample code.

Related

iOS & MVC - How to create this app/game

I'm really quite confused as to how I'm supposed to implement the following app. I have 90% of the code, but the last 10% I can't figure out. I can't figure out how I'm supposed to control the flow of events. I'll describe the app/game first.
The Game
The flow of events happens like this. The user sets the number of teams and the number of rounds. The game will then show a screen saying "Pass to team 1". The player on team 1 then presses a button which pushes on another view.
On this view, the current player tries to describe words/names on the screen to the other players on their team without saying them. Each time someone guesses a word/name correctly, the player presses a button which pulls out more words, and adds 1 to the score for that team. This continues until a timer runs out.
When the timer has ran out, this view will get popped off the navigation controller, and the previous view will tell the player to pass to team 2.
This will loop for the number of teams and the number of rounds.
My Problem
My problem is that I really don't understand how I'm supposed to keep track of all these events. I have a "GameBrain" class where I keep an array of scores and team names etc. but I don't know how to access this from each ViewController.
I asked a similar question earlier and someone suggested a Singleton class, but I've since read that this is bad practice and I can't help but feel that I should be able to do this following the MVC design pattern.
So my question is, how would you guys/girls approach coding a game like this?
Sorry for the kind of vague question. Any help would be greatly appreciated.
EDIT: Are delegates the correct way to go? i.e. Would I create the first ViewController that I need from my "GameBrain", set the brain (so self in this case) as the delegate for this instance, and have the ViewController call a "I'm done with this round" method on the brain which would then fire off the next ViewController?
Your GameBrain should be designed as a singleton, singletons may have some bad sides, but in your case they are the best choice, so just go with it
Since this class has to be accessed by all your viewControllers and since there is no need of having multiple instances of this class, then this would fit a singleton perfectly
I started with a comment but moved on to an answer.
In short, as #Omar says, for a quick little thing you describe the Singleton may work fine.
The longer version, several years ago I designed a quick little thing like this and we released it and all was well. Several months later we had several million users and had undergone multiple development phases and the Singleton pattern we had begun with was destroying the project. I might mention that my boss insisted at the beginning it was a small project and we would release it in two weeks and be done - hah, funny guy.
The reason the Singleton did not work well is because it restricted modularity. In the end, everything "game related" had to come back through this class which in turned sent a message to another class which sent a response back to the Singleton etc. etc. It was horrible.
If you have the time/energy, I recommend you create a GameBrain (or whatever) class for each game. This class is usually only ever used in the "game screen" anyway, so why keep it around when you are back in the menu or sending emails? If you need it persistent the make it backed by a database. If you only need it in one or two extra places (your winning screen might need to know who won etc.), just pass it along by reference - you should only need to do it one or two times.
Good luck.

Should View be allowed to open another View in MVVM

Lets take this example. I have a AView which is bound to AViewModel. AView should execute an ACommand on AViewModel, and pass it a parameter. The problem is that ViewA doesnt have enough information to pass to command, so another BView needs to be displayed, in order to gather information from the user. After the VIewB is closed, ViewA invokes ACommand on AViewModel, and passes parameter to it.
How to handle this scenario? Should I allow AView to communicate directly to BView, or I am breaking some rule if I do so?
Another way I am thinking is to invoke a ACommand on AViewModel without a parameter, then from VIewModelA send a message that a information is required to complete the task. This information is captured by MainPageViewModel, than sends a request to open BView, which is bound to BViewModel. When BView is closed, a BVIewModel sends a message with additional info, and ViewModelA has subscribed to this type of message, so it receives it, and completes the task. Pretty complicated for just entering values in two text boxes, right? :)
There are 3 golden rules to MVVM: Separation, Separation & Separation :)
Reasons include: Automated testing of components, complete separation of functionality (e.g. for independent modules), independent team development of modules (without tripping over each other) and generally just easier to figure out what does what.
In answer to your interconnecting two Views: you are adding dependencies that should not exist. Separation of concerns is more important than a little complexity (and I would argue that the messaging model is less complex than maintaining a direct interconnection).
The complexity of publishing/listening for an extra message is nothing compared to the harm of interconnecting unrelated components so your last suggestion is "better", but I would actually suggest a cleaner approach to the whole problem:
A few guidelines:
Views should not know where their data comes from, only how to display a certain shape of data. Command execution is via bindings to ICommands on the VM.
ViewModels should hold a certain shape of data and commands. It should have no idea where the data comes from or what is binding to it.
Models hold the actual data, but have no idea where it is consumed.
Controllers (often overlooked in MVVM) register/push events, populate VMs from models, set the code in ICommands, control visibility of views etc. Controllers are the only thing actually required to stay in memory at all times and they are quite slim (mostly code & little data).
Basically I would suggest adding Controllers to your MVVM pattern (MVCVM?). App/modules create and initialize controllers. Controllers subscribe to events and provide the logic of the application.
Try this pattern and see how simple it becomes to work with lots of Views, ViewModels and Models. You do not mention what language or framework you are using, so I can't make specific suggestions for examples.

How do I make a reusable web interface class in objective C?

I'm working on a new iPhone/iPod app that includes the need to do web services requests. I've found methods for doing these requests synchronously, or asynchronously by setting the controller as the delegate. What I'd really like to be able to do, though, is to create a single class that can handle all web requests for the whole application, and just create an instance of that class when I need to use it. That way, cookies and common pieces of code can be handled in one place, rather than all over the app.
So far the only thing I thought of that could accomplish what I'm trying to do is to create a new thread that handles the request synchronously within itself, then sends a message back to the calling controller once the request is complete. Is there a better way to accomplish what I'm trying to do?
Cookies are already a shared resource.
I would suggest reading the URL Loading System Overview to get an idea of how Apple set everything up. From what you describe, you want something very similar to how they have set up the system, maybe with a Singleton class for the connection. You can also look at ASIHTTPRequests which is a good wrapper around all of the connections stuff.
I would not suggest writing my own code here. Lots and lots of people have solved this problem for you.

Good strategies for REST -> XML -> Core Data -> UITableView?

What are good practices for asynchronously pulling large amounts of XML from a RESTful service into a Core Data store, and from this store, populating a UITableView on the fly?
I'm thinking of using libxml2's xmlParseChunk() function to parse chunks of incoming XML and translate a node and its children into the relevant managed objects, as nodes come in.
At the same time that these XML nodes are turned into managed objects, I want to generate UITableView rows, in turn. Say, 50 rows at a time. Is this realistic?
In your experience, what do you do to accomplish this task, to maintain performance and handle, potentially, thousands of rows? Are there different, simpler approaches that work as well or better?
Sure, this is a pretty standard thing. The easiest solution is to do the loading in a background thread on one MOC, and have the UI running on the main thread with its own MOC. Whenever you get a chunk of data you want to have appear (say 50 entries), you have the background MOCsave:.
Assuming you have the foreground MOC rigged to merge changes (via mergeChangesFromContextDidSaveNotification:) then whenever you save the background MOC the foreground MOC will get all of those changes. Assuming you are using NSFetchedResultsController it has delegate methods to cope with changes in its MOC, and if you are using Apple's sample code then you probably already have everything setup correctly.
In general CoreData is going to be faster than anything you roll yourself unless you really know what you are doing and are willing to spend a ton of time tuning for your specific case. The biggest thing you can do is make sure that slow things (like XML processing and synchronous flash I/O caused by save:) are not on the main thread blocking user interaction.
Joe Hewitt (Facebook app developer) has release much of his code as open-source. It is called Three20. There is a class there that is great for fetching internet data and populating it into a table, without the need for the data beforehand. The classes used for this are called TTTableViewController and TTTableViewDataSource.
From here, it would not be much of a stretch to store as CoreData, just subclass the classes as you see fit with the supplied hooks.
If you are worried about too much data, 50 at a time does sound reasonable. These classes have a built in "More" button to help you out.
From the Three20 readme:
Internet-aware table view controllers
TTTableViewController and
TTTableViewDataSource help you to
build tables which load their content
from the Internet. Rather than just
assuming you have all the data ready
to go, like UITableView does by
default, TTTableViewController lets
you communicate when your data is
loading, and when there is an error or
nothing to display. It also helps you
to add a "More" button to load the
next page of data, and optionally
supports reloading the data by shaking
the device.
No one has mentioned RestKit yet? My friends ... seriously, you have to check this out. If you are doing anything with REST on iOS (and now on OS X) and particularly if you're wanting to work with Core Data ... PLEASE have a look at RestKit. I've saved countless hours implementing some pretty complex data synchronization between a server and my Core Data models on iOS. RestKit made it so damned easy, it almost makes you sick.

Best practices for Singletons and Notifications on the iPhone

Just to give background for my situation, I have a manager singleton that pulls data from a webserver and provides access to the downloaded data. I have several types of views that will consume this data, but only one view at any time will need to receive events.
I was just wondering what people prefer to use when they need to get events from a singleton. Do you use NSNotificationCenter, Target/Action, or delegate?
Thanks for any help.
Are you really, really sure only one view needs to receive events? For instance, you don't have a master view that would need access to the same update that a subview was notified about?
If you truly have only one view controller needing updates at a time ever, I might use a delegate approach. Here's something to consider - what happens if you are in the middle of receiving an update and the user change screens... is that OK? would you cancel the request?
Anything more than one, or if that in-flight changing delegate scenario has issues, then you may well be better off with a notification that anyone can hook into. It's best to keep the notification light with some kind of reference to the change and have the receiver have to look up the altered data.
If there are going to be a large number of events, then you want to stay away from NSNotifications.
For the least amount of overhead I would go with the delegate pattern, although I don't think that target/action has much more overhead than delegates.
Try your favorite way and if there is a problem profile or try a different approach.
I usually start with the easiest to get implemented. For example I once tried to use notifications for some interface code I had written years ago but with 30-60 updates/second the whole interface bogged down unacceptably so I went with delegates which fixed the problem.