Difference between AppDelegate.m and View Controller.m - iphone

Could anyone tell me when we use the AppDelegate.m and AppDelegate.h during iPhone programming? I have used only the ViewController.m and ViewController.h for basic learning. I just want to know when and why AppDelegate is used.

Both define classes, but the classes are used for different things. ViewController.h/m define a view controller class that manages a hierarchy of views -- basically, one screen of an application. You might have multiple screens that each have their own view controller.
AppDelegate.h/m define a class that manages the application overall. The app will create one instance of that class and send that object messages that let the delegate influence the app's behavior at well-defined times. For example, -application:didFinishLaunchingWithOptions: is sent when the app has finished launching and is ready to do something interesting. Take a look at the UIApplicationDelegate reference page for a list of messages that the app delegate can implement to modify the behavior of the application.

I would like to add the following to #Caleb's answer.
If care is not taken, the AppDelegate could easily become one of the most accessed objects in the application. I usually refrain from calling methods in the AppDelegate from any of my ViewControllers. Unless, something needs to be reported to the AppDelegate that would influence the behaviour of the whole application.
I keep my AppDelegate for the following:
initialization: whatever needs to be done on the very first launch (after an install or an update)
data migration from version to version (e.g. if you use CoreData and migrations)
configuration of objects linked via IBOutlets from MainWindow.xib
determining the initial orientation to launch in
saving uncommitted data / state prior to the application being terminated or entering background mode
registering for the Apple Push Notification Service and sending the device token to our server
opening one of the supported application URLs (e.g. maps://)
For other use case scenarios and a more thourough description of the AppDelegate, see the iOS Application Programming Guide.

The view-controller. h/m is responsible of controlling the connection between your model and your view (more on MVC here).
AppDelegate. h/m is responsible for the life-cycle of your application. What to do when the user press the home button and exit your app, what to do when the app enter background. Things like this.

Related

Difference between SceneDelegate and AppDelegate

In my SwiftUI project I see AppDelegate file as well as a SceneDelegate file.
What are the differences between them?
For example between the methods in SceneDelegate
scene(_:willConnectTo:options:)
and in the AppDelegate
application(_:didFinishLaunchingWithOptions:)
The two files are meant to split the work by what is needed to run the app as a whole and what is needed for one "instance" that would support visibly running in the background. This would be something like configuring a database once, but displaying different sets of values by window.
You could think of them as the global and private versions. One is shared and the other is limited to the individual owner. In a way, they are exactly what you would expect by the names.
Multi-window support is happening
Next time you create a new Xcode project you’ll see your AppDelegate
has split in two: AppDelegate.swift and SceneDelegate.swift. This is a
result of the new multi-window support that landed with iPadOS, and
effectively splits the work of the app delegate in two.
From iOS 13 onwards, your app delegate should:
Set up any data that you need for the duration of the app.
Respond to any events that focus on the app, such as a file being shared with you.
Register for external services, such as push notifications.
Configure your initial scenes.
In contrast, scene delegates are there to handle one instance of your
app’s user interface. So, if the user has created two windows showing
your app, you have two scenes, both backed by the same app delegate.
Keep in mind that these scenes are designed to work independently from
each other. So, your application no longer moves to the background,
but instead individual scenes do – the user might move one to the
background while keeping another open.
Courtesy of https://www.hackingwithswift.com/articles/193/whats-new-in-ios-13
AppDelegate is responsible for handling application-level events(like app launch), application lifecycle, and setup.
SceneDelegate is responsible for handling what is shown on the screen (Windows or Scenes) and managing the way your app is shown.
scene(_:willConnectTo:options:) is the first method called in UISceneSession life cycle. This method will create a new UIWindow, set the root view controller, and make this window the key window to be displayed.
application(_:didFinishLaunchingWithOptions:) is called when the application is launched and where the application set-up is done. Earlier iOS 13, we might have used this method to configure the UIWindow object and assign a ViewController instance to the UIWindow object to make it display on the screen. From iOS 13, if your application has scenes, then AppDelegate is no longer responsible for handling this and is moved to SceneDelegate.
From: https://medium.com/#kalyan.parise/understanding-scene-delegate-app-delegate-7503d48c5445
Multiplatform
In addition to the answer of Abandoned Cart, Since Xcode 11, You have a new option called Multiplatform for choosing as a starting template. That's where you will only see a file contains:
#main
struct MyMultiplatformApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
This is how the system knows where to start the code with #main (in Swift 5.3) and it contains WindowGroup that manages multiple windows of your app in all apple platforms. So you don't need the be worry about SceneDelegate and AppDelegate anymore.
If you need it to be like the old app delegate, for example when you want to use its methods, You should subscribe for corresponding notifications or use the UIAppDelegateAdapter wrapper as I described here

Understanding application flow of iOS 7 apps. What happens on launch?

I'm new to Objective-C and iOS programming. I've read through a few of Apple's "Getting Started" docs and I've downloaded a few sample applications to try and get familiar with what is going on in the app. What I'm confused about is what exactly happens from the application's launch. I see in main.m that UIApplicationMain gets called and invokes the AppDelegate. From what I've read, now, if applicationDidFinishLaunching returns true, the app will enter the main event loop.
Is this all correct? If so, how do I tie my code to events? Where do I create instances of my classes when an event occurs?
Finally, from my understanding, Xcode now creates all template apps with storyboards. However, some applications I am looking at are a bit older and don't use storyboards, but I don't see .xib or .nib files anywhere in the directory, but the applications successfully build. Am I wrong in assuming that applications require these files?
An application does not require a .xib or .nib to run. Many programmers do not use any of the visual design tools that generate storyboards or .nib files. You can define your UI completely in code if you wish.
The call to UIApplicationMain in main.m creates a singleton UIApplication object, sets up an event loop, and sets up your UIApplicationDelegate which works in tandem with UIApplication so you can customize the behavior of your app at key points in its lifecycle. UIApplication manages the event loop for you. It receives events from the system and dispatches them to your code for handling.
In order to really understand event handling you need to understand the responder chain. If you look at the superclass of your app delegate you will see it is UIResponder. This is the interface that lets objects respond to and handle events. It is the superclass of UIApplication and UIView and handles most of the raw event handling for you. Events follow a defined path through your code. In the simplest case, touch events, UIApplication pops an event from the event loop and hands it off to UIWindow. UIWindow will perform a hit test to try and deliver it directly to the UIView under the finger. It gets more complicated and motion events take a different path but the point is that much of the raw event processing is handled for you by UIKit. All you really need to do is setup your UIWindow and its rootViewController and events will follow a specific delivery path through all your UIKit responders. You can read about the responder chain in detail here https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html.
When your app starts, the following delegate methods will get called in this order:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions;
- (void)applicationDidBecomeActive:(UIApplication *)application;
In addition, your initial view controller will get created and shown and the following methods will get called (assuming you are using storyboards or xib files):
-(void)viewDidLoad;
-(void) viewWillAppear:(BOOL)animated;
As for "tying your code to events", what type of events are you talking about? What are you trying to accomplish?
You no longer need to use xib files if you are using storyboards, however, you can if you want to.

How do I tie up appDelegate to the rest of the app?

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.

Should I be writing the majority of my code in a controller or the delegate?

I was using Xcode 4.1 and after upgrading to 4.2, things started to become out of date. I am using many examples from different books, such as Big Nerd Ranch Guides, which do not use Storyboards and the Windows-Based Application had been changed to "Empty" Application.
With these new changes, I feel like the books and tutorials I had been using to start have become outdated. In many of these examples, they say to write the methods and variables in the delegate header files for 4.1. With the new 4.2 Xcode, there is an AppDelegate and ViewController. Should I still be writing the methods and class members in the AppDelegate, or should I be now writing them in the Controller file?
I am confused. Does Apple now want us to create our controller and reference it through the delegate?
When your app is run, it creates an instance of UIApplication. You want to know things that only the UIApplication object knows (did we just get switched to the background? did we just open?) so you use the delegate pattern to get it. When you start a new project Apple starts you off with an already-assigned App Delegate. You can open up MainWindow.nib and inspect your App Delegate to see how it is connected to your UIApplication instance (File's Owner, in this case).
In general you only want to put code in there that has to do with the basic functionality of your app. Launch, quit, go to background and come to foreground are when you'll be doing things in the App Delegate.
Most everything else should go in your view controllers or model objects. Since 'delegate' is just a design pattern, your view controllers can be delegates of other objects. For example, if you present a UITableView, you will assign a view controller as it's delegate in order to respond to events such as selection and scrolling. Your app has many delegates, but it only has one App Delegate.
The AppDelegate is really just a "launcher" for your app. Ie: You shouldn't be writing much code in it at all.
If you're concerned with "set up" code, do it in your View Controller, under viewDidLoad.

Custom Delegates

I've read in a number of places that using the AppDelegate as the heart of the application is bad (apart from the actual UIApplication delegates themselves).
Would it be wise to create custom delegate classes to keep code modularized.
For example if I need to format various text inputs, create a Formatter delegate class and set the delegate on any text input object that needs to be formatted?
Does that make sense?
The point of the articles you've read is 'Do not keep all application logic in app delegate'. Responsibility of app delegate is to handle important events in app lifecycle in lightweight way by notifying appropriate parts of application, not to manage views or data flows or network calls. For example in application:didFinishLaunchingWithOptions: delegate usually adding root controller's view into window, makes this window active and leaves everything else to controller.