I am making a very basic iOS chat application, the app now has several different viewControllers so i now somehow want to always listen to the server no matter what viewController the user is on.
Before i had my NSStream code on the viewController that i wanted to update, however now since i have multiple views i want to make sure that the server is listening for updates no matter what viewController a user is on..
How can i do this? Where would i put my methods for listing / writing to the server (so that all viewControllers can read/write to it)?
You could make a global singleton that handles your chat connections and does all the reads and writes. All the view controllers that need to be able to send or receive chat messages would then use that singleton.
For how to communicate between the view controllers and your chat singleton, have a look at Apple's Notification Programming Topics and Key-Value Observing Programming Guide
Don't abuse the AppDelegate for things like that. Just because it is a globally available singleton, does not mean it should handle everything that is shared between view controllers.
Your views should not know anything about chat connections.
Create a singleton to manage the communication. Call it something like XXChatDataController. Be sure that none of the view controllers create their own instance.
If you have multiple view controllers you want to look at using notifications (instead of delegation) to distribute information about new chat data being received as this will allow your code to be simpler and to handle the situation where you have multiple view controllers observing updates at the same time (if you were using child view controllers say).
Related
I am a relative beginner to iOS development, but I managed to get my app to do everything I want it to. However, I have some questions about tying the app up together.
The only code I have currently inside my appDelegate handles remote notifications; when I receive a remote notification I send out the alerts, messages, and so on to the user. I also generate notifications for the notification center which cause different methods to run inside different view controllers.
What about all the different functions in the appDelegate? DidEnterBackground, WillEnterForeground, etc.? My app starts on one view (view1), which creates an object (stream1), which has a method stopStream. I have buttons to start and stop the streams ([self.stream1 stopStream]). My question in, how do I call these methods to stop that particular instance of the object in one of the appDelegate methods? Do I need to create a notification for the notification center inside the appDelegate, and handle it triggering in the view? Or is there a simpler method? Or am I doing things completely wrong and not according to best practices?
Any help would be appreciated! Also a link to a guide about the architecture of apps, or a link to your favorite book about building apps in iOS would be great!
Your app delegate only needs to implement the various app delegate methods if the app delegate actually needs to do something with those events.
If a given view controller or other class is interested in the various app delegate notifications (such as enter background, or return to foreground, etc.), then the view controller or other class should register for the corresponding notification. See the docs for UIApplication for the different notifications.
Do not have the app delegate method post a custom notification.
All the methods you're looking for can be found listed here in the docs.
As for what to do about them thats definitely up to your app. It is best practice to handle at least going in and out of the background properly so at least use the methods for those and take the appropriate action in your app.
Its very common for apps to simply blast out NSNotifications like you mention. Its perfectly acceptable in most circumstances.
I am fairly new to Objective-C, but haven't been able to find the answer I am looking for yet.
I am building a practice app which counts down days till specific events (christmas). It all works well, but I wanted to implement a simple way to change the background image (created from storyboards). The current setup of the app is a basic utility app, with the alternate view containing a UISegmentedControl that will set which background image will be displayed behind the countdown label.
I know I can just push separate views, but that seems quite inefficient. I am fairly sure I can use NSNotifications to update the background image, but am still unclear after reading the documentation how to implement it.
One way is to use delegates. A delegate is a callback. That avoids one view passing a reference to another view and having it poke (introduces coupling). Instead, one provides a callback via a formal protocol and delegate to the other.
Here's an SO question that covers it:
What exactly does delegate do in xcode ios project?
Another option is to have a shared model. Using a singleton pattern, multiple views can share a model (data and operations) and you can use NSNotificationCenter to send notifications. When the other view gets the notification that the background changed, it can query the model and update the background.
Related posts:
Giving notification to another class with NSNotificationCenter
How to share an object with the entire project?
As far as the pros and cons go, basically a notification is good when you want to broadcast a change to multiple views. Delegation is good when two items need to communicate directly with some abstraction.
NSNotificationCenter vs delegation( using protocols )?
Here is something I just can't get to work....I can make the view controller talk to my custom objects just fine....but how do I send messages to the View Controller from my objects?
A message from myViewController to myObject would look like
[myObject doSomething].
What would the opposite message look like? Does it even make sense to send a message the other way?
Greatly appreciate your help!
You could pass a controller to a model, but often you want models to not depend on views or controllers.
To avoid that, make a protocol that the model wants to talk to and have the view controller implement it and have the model take an instance of the protocol, not the view controller as a property.
I often use NSNotificationCenter to broadcast updates from model objects to interested controllers. For a more tightly bound interaction, consider making a delegate protocol for the model object.
A notification is mostly one way, although the listener could access the model object that sent the notification. There can be any number of interested parties, including none if controllers come and go but the model is persistent.
A delegate is two way, but there can only be one delegate at a time. Usually a delegate is expected to outlive the object it is a delegate to. A delegate might be good for a phase of a model object lifespan that requires extra user input.
Notifications and delegates can be used simultaneously. As with UIApplication, the delegate is usually called before the notification is sent.
Why would you want your model to actively talk to anything in the first place? View controllers are the active managers of the app flow, and initiate communications to the model, not the other way around.
Can you say a more specific example of a situation where you would actually need to do this?
Like you suspect yourself, most of the time it doesn't make sense to send messages “the other way.” But if you really need to do that, an appropriate way to broadcast information “out” from models is notifications. You can have your model send notifications, and view controllers or any other objects can subscribe to those notifications if they care, but there is no tight coupling from model to other app pieces.
considering good design, is it better for each view controller to manager their own connection / networking / loading, or to centralize it in the app delegate, or a separate object?
Context:
I have a multi-tab app, each with a navigation controller, and a number of view controller below. Each view controller is doing networking loading XML and images. Currently, i have it setup that it calls to the app delegate to get the xml asynchronously, processing it, and then calling back the top view controller to display the info, and then launching a separate process of loading the images into an array, and sending callbacks for when each is loaded.
From an architectural view-point, is it better to have more networking code in each of the view controllers or calling back to the app delegate?
Ideas / opinions?
TIA.
It's going to make much more sense to have this in each View Controller, I think. The way you've got it set up now sounds a bit weird - you must either be using delegation so that the App Delegate can speak to each view controller, or you have a ton of references to your View Controllers in your app delegate which you probably don't need. I'd imagine your app delegate is cluttered, and I'm curious as to how you're handling things like if the user decides to stop looking at a particular view before the XML related to that view has been sent back to your app and parsed.
If you're worried about having code duplication in your View Controllers, you can probably mitigate that by using Categories.
In the end though I think it's probably best for domain objects to handle this, and not the View Controllers. For example, in viewWillAppear you get or create an instance of a domain object and kick off a getData method which has the view controller as a delegate. All of the requesting/parsing is done in your domain object and when it's completed, it sends your view controller a getDataDidFinish message or something like that.
When I have a situation like this I tend to create an object that handles all the networking stuff for me. That way I end up being able to write code like:
[netObj getXML:somePlace];
The main reason I like this approach is because it keeps my code base tidy and minimizes duplicated code.
I'm new to development on the iPhone. Just about every sample project (as well as the default project templates) have one or more delegates and controllers. Can someone give me a breakdown of what the delegates are responsible for vs. what the controllers are supposed to do?
The simplest way I can think to differentiate the two are:
A delegate is a protocol (interface) that defines methods that an object implements in order to receive specific messages from other objects. Delegates objects are most often used to receive asynchronous callbacks such as user input, I/O.
A controller is an object that usually contains UI elements (views, controls, etc.) and data, and both receives and send messages to the various objects within it. In many cases, a controller is a delegate and can implement several delegate protocols to receive events from multiple objects.
Keep in mind that many UI elements and controls let you pass events back to the controller by linking them to an IBAction method in Interface Builder. This is very handy as it doesn't require extra code to implement delegates. However, some other APIs such as the ABPeoplePickerNavigationController or NSURLConnection have no visualization in Interface Builder and so must use delegates to handle their events.
A delegate is some object that implements a set of methods which either your application or the framework you link against depends on for functioning. It is a means of implementing a delegation based design pattern wherein the responsibility for performing an action is transferred from some root source to an interested third party. For instance, UIApplication has delegate methods that provide a third party with the ability to perform operations at certain times during the applications lifetime. It can be though of as a milestone in a timeline into which you can contribute to the story.
A controller is a totally different animal and is responsible for doing, well, the controlling. A ViewController is charged with managing views - for loading them into memory from disk when they are needed and unloading them when they are not. They transform content from some underlying model object into a form that is usable by your view objects, load content into your in-memory model from the disk or from the internet, and dump the contents back to disk when you save and/or quit.