I am developing one navigation based application. All data required for each screen are getting downladed from webserver. I am starting downloading in viewDidLoad method. ALl downloadinh is happening asynchroniously and respective viewcontroller will receive data through delegate pattern. Now my question is in case new viewcontroller is getting pushed on navigation stack or current view controller is getting popped off so fast before data will get received, how we will handle this situation? We do not want to block UI so user can move back or forward. I used notification mechanism to detect particular view controller (one who receive data ) is alive or not , but it seems like not a concrete solution. So basically I want to detect receiver is appropriate for receiving downloaded data before I make a call to its delegate method.
Any pointer related to it is highly appreciable.
Thanks!
Nilesh
I think the dataSource pattern is more appropriate.
1) Create a datasource (singleton or attached in your app delegate)
2) Implement a method dataWithPredicate: (or just data)
3) Notify your viewController (with NSNotificationCenter) when a data is updated
4) Reload data from the controller (with dataWithPredicate: call)
Another way is to use core data for that. CoreData generate all the notification and do the job for you.
Related
I have an application in which
i want to do pushing and poping of my view controllers to the
navigation controller while a webservice call is on
.Now when i am doing it i make all the buttons inactive untill the request finished.But i need to remove this.I need to go back and forth while calling the service.Can anybody help me on this regard
From what I get out of your question, solution could be as follow:
You need to implement delegation for this purpose. You have to define a protocol in the class from which your web service is getting invoked. And then implement that protocol into the class to which you want to navigate to. By doing this you will be able to handle the response/error to the navigated ViewController class.
Again, When you want to move back and forth, you again need to implement delegation to the main ViewController, from which your web service is getting called. (Just to handle response/error, in case if you are in the same class while response is returned)
Hope this clears the point.
P.S. My answer is as par the understanding of your question. For detailed answer please elaborate your question accordingly. Thanks.
Just a wild guess.. how about creating a singleton object which handles all you network related stuff. So instead of calling the web service and implementing its delegate methods in your view controller you assign this object the responsibility of handling the network interaction. This way your view controllers will remain clean (less code) and you can reuse this object anywhere throughout the application... any other thoughts on this are welcome.
I have a fairly complex application at this point, and feel as though the way I am handling data is not up to scratch.
So I have started taking some steps towards making my app more MVC friendly.
The first of which, I have gone from having inline parser methods in all of my ViewControllers to creating a dedicated parser class.
Its not hard to call I just set up the class then call the initializer method I have made which I pass the data to for my request.. everything in my object class works sweet I get a whole bunch of return data from the server that I am parsing.. but then this is where I get abit lost.
How do I get that data back to the ViewController that called it? I have worked a little with protocols and delegates.. but I dont know how that would fit into this.
Here is an graphical example of what I am trying to achieve.
So as above View controller calls the initalization method of the object class which connects to the DB downloads the data, and then parses that data. The issue I am having is how do I then get that data to ViewController2..
what is the most appropriate and future proof way of doing this?
A custom -init method does wonders. For instance, I needed to instantiate and push a picker preloaded with the array from the previous screen, so I defined -(id)initWithArray:(NSArray*)array in the second view, then just called secondView = [[SecondView alloc]initWithArray:_population]; then pushed it. Remember to get ownership of any object you pass before it is deallocated and destroyed!
If you want to broadcast data from your object to all view controllers the good way to do this will be by notifications (NSNotificationCenter). You could also write a methods with completion blocks inside your parser object.
Try to send a local notification using NSNotificationCenter. Register your ViewController2 as a listener, then upon receiving the notification, call your data model (singleton!?) for the data.
I'm currently developing an iPhone app communicating via REST with a web server.
Each time the app starts it checks for remote data updates. If the data has not been loaded I start an async request in the app delegates applicationDidBecomeActive and show a modal progress view while the request is running. Some of my view controllers also need a data update which should be handled while the same progress view is visible and after the first request has finished.
What is the best approach to handle this scenario? Post a notification to the view controllers after the first request has finished and call back the delegate to dismiss the progress view?
Or is this considered a bad solution?
Best Regards
Carsten
Posting a notification should be used if the sender does not know anything about (should not depend on) the observers. For example, data object posts notification when it changes, so the visual objects connected to it could update themselves.
In your case you need to have a root object, the owner of your view controllers. It may be your Application Delegate or a subclass of a Navigation Controller. Since the owner knows about the view controllers, it can directly tell them to update when the request finishes.
Generally, do not send notifications between the owner and its dependants. Owners can directly call dependants' methods. Dependants can have weak links to their owners and let them know when they update. If you need to make dependants independent on the owner's class, define a delegate protocol.
I'm new to Objective-C and not a full time programmer. I'm beginning to understand the Model-View-Controller design pattern for differentiating the UI from the model. So the user takes an action and the view controller sends a message to the delegate (model). But I'm not sure what the best way to send actions from the delegate back to the view controller.
For example, the user pushes a button, the VC messages the Delegate. That part I understand. Then the delegate takes action, and following that the delegate wants to update the VC (e.g., update a label).
So what I missed (or have forgotten) is how this gets done, while maintaining separation between the UI and the model. I suppose I can use the notification center. Or I think I can just have the view controller pass a callback to the delegate. Or maybe there's another choice I don't know of. Can someone give me a recommendation, please?
I think you're slightly misunderstanding the MVC paradigm. Models should never be delegates of views, since models should have no dependencies or knowledge of any view classes. Typically, a view sends a message to its delegate or target (if you're using target/action), which is usually a controller (often a subclass of UIViewController on iOS). The controller then accesses data from the model and can update any views that need updating. I'd recommend reading the MVC fundamentals guide for a more complete explanation.
Basically you're right, you could do all the notification-related things yourself (i.e. with NotificationCenter) but since we're talking about UI-Stuff here I would greatly recommend you to use IBAction-Methods and IBOutlet-Properties in your code which you can easily connect to UI-Elements respectively their Callbacks in Interface Builder.
A very basic introduction to this topic can be found here:
iPhone SDK Interface Builder basic training
i hope that it is not too basic tough, and that I could lead you on the right track.
First of all delegate is NOT a Model.
Model is something passive that only holds the data (DB, plist, array, dictionary etc.).
While delegate is some set of functions that exist in order to react to some events.
Delegate is more likely to be a view controller in your case.
The view controller should react to user's action.
If the button tap should display some data from your model in some label then view controller should do all the work (receive user's action, take the necessary data from the model and display it on the view...).
Using Apple's Mail application as an example; pretend it uses Core Data. When you touch an email account, it shows you all the messages in that account. So the controller did a fetch request for all the messages in that account.
Then you touch a message and drill one level deeper, now you are viewing a single message. This single message was probably passed from the message list controller, but -- you can also click the triangles in the upper right to move through all the messages in the same email account. This means the view controller for viewing a single email message also needs the exact same list of messages.
So you could cut and paste the fetch request logic from the list view, but that isn't DRY/don't-repeat-yourself.
Any suggestions for a best practice in solving this problem?
Create an object to manage your messages, then interact with that object to fetch the messages that you need for any of your view controllers.
This would also allow you to switch from CoreData without changing any of your view controller logic if you decided to at a later time.
The solution I've been using to solve this problem is to use the delegate design pattern. I.e., in an application with a rootViewController and a detailViewController, the rootViewController acts as a delegate for the detailViewController.
So, for example, when the user is viewing an email message (on the detail view), and they click a button to iterate to new a message, then the detailViewController informs the rootViewController via a delegate method that the rootViewController needs to display a new message.
This way, the detailViewController only every needs to know information about one model object (the email being displayed). While the rootViewController handles interaction that involve the rest of the objects.
To me, this is a nice division of responsibility, so this is the solution I've been using.